From c151ed4764636b380aab6f6edc6e369c4a7a2f58 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 5 Feb 2024 23:19:48 +0000 Subject: [PATCH 1/2] Add test. --- tests/mir-opt/gvn_copy_moves.fn0.GVN.diff | 27 +++++++++++++ tests/mir-opt/gvn_copy_moves.rs | 46 +++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/mir-opt/gvn_copy_moves.fn0.GVN.diff create mode 100644 tests/mir-opt/gvn_copy_moves.rs diff --git a/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff new file mode 100644 index 0000000000000..b7463a08d9f3f --- /dev/null +++ b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff @@ -0,0 +1,27 @@ +- // MIR for `fn0` before GVN ++ // MIR for `fn0` after GVN + + fn fn0() -> () { + let mut _0: (); + let mut _1: usize; + let mut _2: [u128; 6]; + let mut _3: ([u128; 6],); + let mut _4: ([u128; 6],); + let mut _5: (); + + bb0: { + _1 = const 1_usize; + _2 = [const 42_u128; 6]; +- _2[_1] = const 1_u128; ++ _2[1 of 2] = const 1_u128; + _3 = (_2,); + _4 = _3; +- _5 = fn1(move (_3.0: [u128; 6]), _4) -> [return: bb1, unwind unreachable]; ++ _5 = fn1(move (_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + return; + } + } + diff --git a/tests/mir-opt/gvn_copy_moves.rs b/tests/mir-opt/gvn_copy_moves.rs new file mode 100644 index 0000000000000..d216825e5e689 --- /dev/null +++ b/tests/mir-opt/gvn_copy_moves.rs @@ -0,0 +1,46 @@ +// unit-test: GVN + +#![feature(custom_mir, core_intrinsics)] +extern crate core; +use core::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "initial")] +fn fn0() { + // CHECK-LABEL: fn fn0( + mir! { + let a: usize; + let b: [u128; 6]; + let c: ([u128; 6],); + let d: ([u128; 6],); + let x: (); + { + // CHECK: bb0: { + // CHECK-NEXT: _1 = const 1_usize; + // CHECK-NEXT: _2 = [const 42_u128; 6]; + // CHECK-NEXT: _2[1 of 2] = const 1_u128; + // CHECK-NEXT: _3 = (_2,); + // CHECK-NEXT: _4 = _3; + // CHECK-NEXT: _5 = fn1((_3.0: [u128; 6]), _3) + a = 1_usize; + b = [42; 6]; + b[a] = 1; + c = (b,); + d = c; + Call(x = fn1(Move(c.0), d), ReturnTo(bb1), UnwindUnreachable()) + } + bb1 = { + Return() + } + } +} + +#[inline(never)] +fn fn1(a: [u128; 6], mut b: ([u128; 6],)) { + b.0 = [0; 6]; +} + +fn main() { + fn0(); +} + +// EMIT_MIR gvn_copy_moves.fn0.GVN.diff From 6fbd761644932a31457b15f425f87378387fbdc1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 5 Feb 2024 23:21:33 +0000 Subject: [PATCH 2/2] Also turn moves into copies even if through projections. --- compiler/rustc_mir_transform/src/gvn.rs | 4 ++-- tests/mir-opt/gvn_copy_moves.fn0.GVN.diff | 2 +- .../separate_const_switch.identity.SeparateConstSwitch.diff | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 390ec3e1a36ac..07b788526706d 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1228,8 +1228,8 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> { fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) { if let Operand::Move(place) = *operand - && let Some(local) = place.as_local() - && self.reused_locals.contains(local) + && !place.is_indirect_first_projection() + && self.reused_locals.contains(place.local) { *operand = Operand::Copy(place); } diff --git a/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff index b7463a08d9f3f..b12de636f58b1 100644 --- a/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff +++ b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff @@ -17,7 +17,7 @@ _3 = (_2,); _4 = _3; - _5 = fn1(move (_3.0: [u128; 6]), _4) -> [return: bb1, unwind unreachable]; -+ _5 = fn1(move (_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable]; ++ _5 = fn1((_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index e7280f148377c..d273161528464 100644 --- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -66,7 +66,7 @@ _5 = ((_2 as Break).0: std::result::Result); StorageLive(_6); _6 = _5; - _12 = move ((_5 as Err).0: i32); + _12 = ((_5 as Err).0: i32); _0 = Result::::Err(_12); StorageDead(_6); StorageDead(_2); @@ -83,7 +83,7 @@ } bb4: { - _10 = move ((_1 as Err).0: i32); + _10 = ((_1 as Err).0: i32); StorageLive(_11); _11 = Result::::Err(_10); _2 = ControlFlow::, i32>::Break(move _11); @@ -92,7 +92,7 @@ } bb5: { - _9 = move ((_1 as Ok).0: i32); + _9 = ((_1 as Ok).0: i32); _2 = ControlFlow::, i32>::Continue(_9); goto -> bb3; }