diff --git a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff new file mode 100644 index 000000000000..d17213993282 --- /dev/null +++ b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff @@ -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; + } + } + diff --git a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff new file mode 100644 index 000000000000..64d137bfc26b --- /dev/null +++ b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff @@ -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; + } + } + diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs index c9473025a15f..af1839fd3efc 100644 --- a/tests/mir-opt/gvn_copy_aggregate.rs +++ b/tests/mir-opt/gvn_copy_aggregate.rs @@ -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 +} diff --git a/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff b/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff new file mode 100644 index 000000000000..f13c92e4fd01 --- /dev/null +++ b/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff @@ -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; + } + } + diff --git a/tests/mir-opt/gvn_overlapping.rs b/tests/mir-opt/gvn_overlapping.rs index f148a8435612..a41f8ad5fd60 100644 --- a/tests/mir-opt/gvn_overlapping.rs +++ b/tests/mir-opt/gvn_overlapping.rs @@ -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)); }