clean up GVN TypeId test
This commit is contained in:
parent
556d20a834
commit
71176a28e6
6 changed files with 95 additions and 34 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
57
tests/mir-opt/gvn_const_eval_polymorphic.rs
Normal file
57
tests/mir-opt/gvn_const_eval_polymorphic.rs
Normal 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 }
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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>());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue