Add miscompiled test cases for GVN

This commit is contained in:
dianqk 2025-10-18 21:42:08 +08:00
parent 930ecbcdf8
commit 732406017c
No known key found for this signature in database
5 changed files with 188 additions and 0 deletions

View file

@ -0,0 +1,50 @@
- // MIR for `deref_nonssa` before GVN
+ // MIR for `deref_nonssa` after GVN
fn deref_nonssa() -> Single {
let mut _0: Single;
let mut _1: Single;
let mut _4: Single;
let mut _5: u8;
scope 1 {
debug a => _1;
let _2: &Single;
scope 2 {
debug b => _2;
let _3: u8;
scope 3 {
debug c => _3;
}
}
}
bb0: {
StorageLive(_1);
- _1 = Single(const 0_u8);
- StorageLive(_2);
+ _1 = const Single(0_u8);
+ nop;
_2 = &_1;
- StorageLive(_3);
+ nop;
_3 = copy ((*_2).0: u8);
StorageLive(_4);
- _4 = Single(const 1_u8);
- _1 = move _4;
+ _4 = const Single(1_u8);
+ _1 = const Single(1_u8);
StorageDead(_4);
StorageLive(_5);
_5 = copy _3;
- _0 = Single(move _5);
+ _0 = copy (*_2);
StorageDead(_5);
- StorageDead(_3);
- StorageDead(_2);
+ nop;
+ nop;
StorageDead(_1);
return;
}
}

View file

@ -0,0 +1,77 @@
- // MIR for `deref_nonssa_2` before GVN
+ // MIR for `deref_nonssa_2` after GVN
fn deref_nonssa_2() -> Single {
let mut _0: Single;
let mut _1: Single;
let mut _3: &Single;
let _4: &Single;
let mut _7: Single;
let mut _9: u8;
scope 1 {
debug a => _1;
let _2: SingleRef<'_>;
scope 2 {
debug r => _2;
let _5: &Single;
scope 3 {
debug b => _5;
let _6: u8;
scope 4 {
debug c => _6;
let _8: Single;
scope 5 {
debug d => _8;
}
}
}
}
}
bb0: {
StorageLive(_1);
- _1 = Single(const 0_u8);
+ _1 = const Single(0_u8);
StorageLive(_2);
- StorageLive(_3);
- StorageLive(_4);
+ nop;
+ nop;
_4 = &_1;
_3 = &(*_4);
- _2 = SingleRef::<'_>(move _3);
- StorageDead(_3);
- StorageDead(_4);
+ _2 = SingleRef::<'_>(copy _3);
+ nop;
+ nop;
StorageLive(_5);
- _5 = copy (_2.0: &Single);
- StorageLive(_6);
- _6 = copy ((*_5).0: u8);
+ _5 = copy _3;
+ nop;
+ _6 = copy ((*_4).0: u8);
StorageLive(_7);
- _7 = Single(const 1_u8);
- _1 = move _7;
+ _7 = const Single(1_u8);
+ _1 = const Single(1_u8);
StorageDead(_7);
StorageLive(_8);
StorageLive(_9);
_9 = copy _6;
- _8 = Single(move _9);
+ _8 = copy (*_4);
StorageDead(_9);
_0 = move _8;
StorageDead(_8);
- StorageDead(_6);
+ nop;
StorageDead(_5);
StorageDead(_2);
StorageDead(_1);
return;
}
}

View file

@ -259,3 +259,28 @@ fn remove_storage_dead_from_index(f: fn() -> usize, v: [SameType; 5]) -> SameTyp
}
}
}
pub struct Single(u8);
// EMIT_MIR gvn_copy_aggregate.deref_nonssa.GVN.diff
fn deref_nonssa() -> Single {
let mut a = Single(0);
let b = &a;
let c = (*b).0;
a = Single(1);
// GVN shouldn't replace `Single(c)` with `*b`.
Single(c)
}
pub struct SingleRef<'a>(&'a Single);
// EMIT_MIR gvn_copy_aggregate.deref_nonssa_2.GVN.diff
pub fn deref_nonssa_2() -> Single {
let mut a = Single(0);
let r = SingleRef(&a);
let b = r.0;
let c = (*b).0;
a = Single(1);
let d = Single(c);
d
}

View file

@ -0,0 +1,19 @@
- // MIR for `copy_overlapping` before GVN
+ // MIR for `copy_overlapping` after GVN
fn copy_overlapping() -> () {
let mut _0: ();
let mut _1: Adt;
let mut _2: u32;
let mut _3: &Adt;
bb0: {
((_1 as variant#1).0: u32) = const 0_u32;
_3 = &_1;
_2 = copy (((*_3) as variant#1).0: u32);
- _1 = Adt::Some(copy _2);
+ _1 = copy (*_3);
return;
}
}

View file

@ -64,6 +64,23 @@ fn fields(_1: (Adt, Adt)) {
}
}
// EMIT_MIR gvn_overlapping.copy_overlapping.GVN.diff
#[custom_mir(dialect = "runtime")]
fn copy_overlapping() {
mir! {
let _1;
let _2;
let _3;
{
place!(Field(Variant(_1, 1), 0)) = 0u32;
_3 = &_1;
_2 = Field(Variant(*_3, 1), 0);
_1 = Adt::Some(_2);
Return()
}
}
}
fn main() {
overlapping(Adt::Some(0));
}