Skip to content

Commit 491b6c2

Browse files
authored
Rollup merge of rust-lang#120688 - cjgillot:gvn-partial-move, r=oli-obk
GVN: also turn moves into copies with projections Fixes rust-lang#120613
2 parents 16cf13f + 6fbd761 commit 491b6c2

File tree

4 files changed

+78
-5
lines changed

4 files changed

+78
-5
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1231,8 +1231,8 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
12311231

12321232
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) {
12331233
if let Operand::Move(place) = *operand
1234-
&& let Some(local) = place.as_local()
1235-
&& self.reused_locals.contains(local)
1234+
&& !place.is_indirect_first_projection()
1235+
&& self.reused_locals.contains(place.local)
12361236
{
12371237
*operand = Operand::Copy(place);
12381238
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
- // MIR for `fn0` before GVN
2+
+ // MIR for `fn0` after GVN
3+
4+
fn fn0() -> () {
5+
let mut _0: ();
6+
let mut _1: usize;
7+
let mut _2: [u128; 6];
8+
let mut _3: ([u128; 6],);
9+
let mut _4: ([u128; 6],);
10+
let mut _5: ();
11+
12+
bb0: {
13+
_1 = const 1_usize;
14+
_2 = [const 42_u128; 6];
15+
- _2[_1] = const 1_u128;
16+
+ _2[1 of 2] = const 1_u128;
17+
_3 = (_2,);
18+
_4 = _3;
19+
- _5 = fn1(move (_3.0: [u128; 6]), _4) -> [return: bb1, unwind unreachable];
20+
+ _5 = fn1((_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable];
21+
}
22+
23+
bb1: {
24+
return;
25+
}
26+
}
27+

tests/mir-opt/gvn_copy_moves.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// unit-test: GVN
2+
3+
#![feature(custom_mir, core_intrinsics)]
4+
extern crate core;
5+
use core::intrinsics::mir::*;
6+
7+
#[custom_mir(dialect = "runtime", phase = "initial")]
8+
fn fn0() {
9+
// CHECK-LABEL: fn fn0(
10+
mir! {
11+
let a: usize;
12+
let b: [u128; 6];
13+
let c: ([u128; 6],);
14+
let d: ([u128; 6],);
15+
let x: ();
16+
{
17+
// CHECK: bb0: {
18+
// CHECK-NEXT: _1 = const 1_usize;
19+
// CHECK-NEXT: _2 = [const 42_u128; 6];
20+
// CHECK-NEXT: _2[1 of 2] = const 1_u128;
21+
// CHECK-NEXT: _3 = (_2,);
22+
// CHECK-NEXT: _4 = _3;
23+
// CHECK-NEXT: _5 = fn1((_3.0: [u128; 6]), _3)
24+
a = 1_usize;
25+
b = [42; 6];
26+
b[a] = 1;
27+
c = (b,);
28+
d = c;
29+
Call(x = fn1(Move(c.0), d), ReturnTo(bb1), UnwindUnreachable())
30+
}
31+
bb1 = {
32+
Return()
33+
}
34+
}
35+
}
36+
37+
#[inline(never)]
38+
fn fn1(a: [u128; 6], mut b: ([u128; 6],)) {
39+
b.0 = [0; 6];
40+
}
41+
42+
fn main() {
43+
fn0();
44+
}
45+
46+
// EMIT_MIR gvn_copy_moves.fn0.GVN.diff

tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
_5 = ((_2 as Break).0: std::result::Result<std::convert::Infallible, i32>);
6767
StorageLive(_6);
6868
_6 = _5;
69-
_12 = move ((_5 as Err).0: i32);
69+
_12 = ((_5 as Err).0: i32);
7070
_0 = Result::<i32, i32>::Err(_12);
7171
StorageDead(_6);
7272
StorageDead(_2);
@@ -83,7 +83,7 @@
8383
}
8484

8585
bb4: {
86-
_10 = move ((_1 as Err).0: i32);
86+
_10 = ((_1 as Err).0: i32);
8787
StorageLive(_11);
8888
_11 = Result::<Infallible, i32>::Err(_10);
8989
_2 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _11);
@@ -92,7 +92,7 @@
9292
}
9393

9494
bb5: {
95-
_9 = move ((_1 as Ok).0: i32);
95+
_9 = ((_1 as Ok).0: i32);
9696
_2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(_9);
9797
goto -> bb3;
9898
}

0 commit comments

Comments
 (0)