clean up GVN TypeId test

This commit is contained in:
Lukas Markeffsky 2025-07-04 19:14:26 +02:00
parent 556d20a834
commit 71176a28e6
6 changed files with 95 additions and 34 deletions

View file

@ -0,0 +1,12 @@
- // MIR for `no_optimize` before GVN
+ // MIR for `no_optimize` after GVN
fn no_optimize() -> bool {
let mut _0: bool;
bb0: {
_0 = Eq(const no_optimize::<T>::{constant#0}, const no_optimize::<T>::{constant#1});
return;
}
}

View file

@ -0,0 +1,13 @@
- // MIR for `optimize_false` before GVN
+ // MIR for `optimize_false` after GVN
fn optimize_false() -> bool {
let mut _0: bool;
bb0: {
- _0 = Eq(const optimize_false::<T>::{constant#0}, const optimize_false::<T>::{constant#1});
+ _0 = const false;
return;
}
}

View file

@ -0,0 +1,13 @@
- // MIR for `optimize_true` before GVN
+ // MIR for `optimize_true` after GVN
fn optimize_true() -> bool {
let mut _0: bool;
bb0: {
- _0 = Eq(const optimize_true::<T>::{constant#0}, const optimize_true::<T>::{constant#1});
+ _0 = const true;
return;
}
}

View file

@ -0,0 +1,57 @@
//@ test-mir-pass: GVN
//@ compile-flags: --crate-type lib
//! Regressions test for a mis-optimization where some functions
//! (`type_id` / `type_name` / `needs_drop`) could be evaluated in
//! a generic context, even though their value depends on some type
//! parameter `T`.
//!
//! In particular, `type_name_of_val(&generic::<T>)` was incorrectly
//! evaluated to the string "crate_name::generic::<T>", and
//! `no_optimize` was incorrectly optimized to `false`.
#![feature(const_type_name)]
fn generic<T>() {}
const fn type_name_contains_i32<T>(_: &T) -> bool {
let pattern = b"i32";
let name = std::any::type_name::<T>().as_bytes();
let mut i = 0;
'outer: while i < name.len() - pattern.len() + 1 {
let mut j = 0;
while j < pattern.len() {
if name[i + j] != pattern[j] {
i += 1;
continue 'outer;
}
j += 1;
}
return true;
}
false
}
// EMIT_MIR gvn_const_eval_polymorphic.optimize_true.GVN.diff
fn optimize_true<T>() -> bool {
// CHECK-LABEL: fn optimize_true(
// CHECK: _0 = const true;
// CHECK-NEXT: return;
(const { type_name_contains_i32(&generic::<i32>) }) == const { true }
}
// EMIT_MIR gvn_const_eval_polymorphic.optimize_false.GVN.diff
fn optimize_false<T>() -> bool {
// CHECK-LABEL: fn optimize_false(
// CHECK: _0 = const false;
// CHECK-NEXT: return;
(const { type_name_contains_i32(&generic::<i64>) }) == const { true }
}
// EMIT_MIR gvn_const_eval_polymorphic.no_optimize.GVN.diff
fn no_optimize<T>() -> bool {
// CHECK-LABEL: fn no_optimize(
// CHECK: _0 = Eq(const no_optimize::<T>::{constant#0}, const no_optimize::<T>::{constant#1});
// CHECK-NEXT: return;
(const { type_name_contains_i32(&generic::<T>) }) == const { true }
}

View file

@ -1,12 +0,0 @@
- // MIR for `cursed_is_i32` before GVN
+ // MIR for `cursed_is_i32` after GVN
fn cursed_is_i32() -> bool {
let mut _0: bool;
bb0: {
_0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
return;
}
}

View file

@ -1,22 +0,0 @@
//@ test-mir-pass: GVN
//@ compile-flags: -C opt-level=2
#![feature(core_intrinsics)]
fn generic<T>() {}
const fn type_id_of_val<T: 'static>(_: &T) -> u128 {
std::intrinsics::type_id::<T>()
}
// EMIT_MIR gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
fn cursed_is_i32<T: 'static>() -> bool {
// CHECK-LABEL: fn cursed_is_i32(
// CHECK: _0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
// CHECK-NEXT: return;
(const { type_id_of_val(&generic::<T>) } == const { type_id_of_val(&generic::<i32>) })
}
fn main() {
dbg!(cursed_is_i32::<i32>());
}