Skip to content

Commit dcd9af0

Browse files
committed
GVN: Preserve derefs at unreachable
1 parent f44d2d6 commit dcd9af0

File tree

4 files changed

+36
-40
lines changed

4 files changed

+36
-40
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,9 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
19241924
// Currently, only preserving derefs for trivial terminators like SwitchInt and Goto.
19251925
let safe_to_preserve_derefs = matches!(
19261926
terminator.kind,
1927-
TerminatorKind::SwitchInt { .. } | TerminatorKind::Goto { .. }
1927+
TerminatorKind::SwitchInt { .. }
1928+
| TerminatorKind::Goto { .. }
1929+
| TerminatorKind::Unreachable
19281930
);
19291931
if !safe_to_preserve_derefs {
19301932
self.invalidate_derefs();

tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
// skip-filecheck
21
//@ compile-flags: -O
32

43
#![crate_type = "lib"]
54

65
// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff
76
// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir
87
pub fn two_unwrap_unchecked(v: &Option<i32>) -> i32 {
8+
// CHECK-LABEL: fn two_unwrap_unchecked(
9+
// CHECK: [[DEREF_V:_.*]] = copy (*_1);
10+
// CHECK: [[V1V2:_.*]] = copy (([[DEREF_V]] as Some).0: i32);
11+
// CHECK: _0 = Add(copy [[V1V2]], copy [[V1V2]]);
912
let v1 = unsafe { v.unwrap_unchecked() };
1013
let v2 = unsafe { v.unwrap_unchecked() };
1114
v1 + v2

tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@
4141

4242
bb0: {
4343
- StorageLive(_2);
44+
- StorageLive(_3);
45+
+ nop;
4446
+ nop;
45-
StorageLive(_3);
4647
_3 = copy (*_1);
47-
StorageLive(_8);
48+
- StorageLive(_8);
49+
+ nop;
4850
_8 = discriminant(_3);
49-
switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1];
51+
- switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1];
52+
+ switchInt(copy _8) -> [0: bb2, 1: bb3, otherwise: bb1];
5053
}
5154

5255
bb1: {
@@ -58,37 +61,43 @@
5861
}
5962

6063
bb3: {
61-
_2 = move ((_3 as Some).0: i32);
62-
StorageDead(_8);
63-
StorageDead(_3);
64-
- StorageLive(_4);
64+
- _2 = move ((_3 as Some).0: i32);
65+
- StorageDead(_8);
66+
- StorageDead(_3);
67+
+ _2 = copy ((_3 as Some).0: i32);
6568
+ nop;
69+
+ nop;
70+
StorageLive(_4);
6671
StorageLive(_5);
67-
_5 = copy (*_1);
72+
- _5 = copy (*_1);
73+
+ _5 = copy _3;
6874
StorageLive(_9);
69-
_9 = discriminant(_5);
70-
switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb1];
75+
- _9 = discriminant(_5);
76+
- switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb1];
77+
+ _9 = copy _8;
78+
+ switchInt(copy _8) -> [0: bb4, 1: bb5, otherwise: bb1];
7179
}
7280

7381
bb4: {
7482
unreachable;
7583
}
7684

7785
bb5: {
78-
_4 = move ((_5 as Some).0: i32);
86+
- _4 = move ((_5 as Some).0: i32);
87+
+ _4 = copy _2;
7988
StorageDead(_9);
8089
StorageDead(_5);
8190
StorageLive(_6);
8291
_6 = copy _2;
8392
StorageLive(_7);
84-
_7 = copy _4;
93+
- _7 = copy _4;
8594
- _0 = Add(move _6, move _7);
86-
+ _0 = Add(copy _2, copy _4);
95+
+ _7 = copy _2;
96+
+ _0 = Add(copy _2, copy _2);
8797
StorageDead(_7);
8898
StorageDead(_6);
89-
- StorageDead(_4);
99+
StorageDead(_4);
90100
- StorageDead(_2);
91-
+ nop;
92101
+ nop;
93102
return;
94103
}

tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@ fn two_unwrap_unchecked(_1: &Option<i32>) -> i32 {
55
let mut _0: i32;
66
let mut _2: std::option::Option<i32>;
77
let _4: i32;
8-
let mut _5: std::option::Option<i32>;
98
scope 1 {
109
debug v1 => _4;
11-
let _7: i32;
1210
scope 2 {
13-
debug v2 => _7;
11+
debug v2 => _4;
1412
}
1513
scope 8 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
16-
let mut _6: isize;
1714
scope 9 {
1815
}
1916
scope 10 (inlined #[track_caller] unreachable_unchecked) {
@@ -37,33 +34,18 @@ fn two_unwrap_unchecked(_1: &Option<i32>) -> i32 {
3734
}
3835

3936
bb0: {
40-
StorageLive(_2);
4137
_2 = copy (*_1);
42-
StorageLive(_3);
4338
_3 = discriminant(_2);
44-
switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb3];
39+
switchInt(copy _3) -> [0: bb2, 1: bb1, otherwise: bb2];
4540
}
4641

4742
bb1: {
48-
_4 = move ((_2 as Some).0: i32);
49-
StorageDead(_3);
50-
StorageDead(_2);
51-
StorageLive(_5);
52-
_5 = copy (*_1);
53-
StorageLive(_6);
54-
_6 = discriminant(_5);
55-
switchInt(move _6) -> [0: bb3, 1: bb2, otherwise: bb3];
56-
}
57-
58-
bb2: {
59-
_7 = move ((_5 as Some).0: i32);
60-
StorageDead(_6);
61-
StorageDead(_5);
62-
_0 = Add(copy _4, copy _7);
43+
_4 = copy ((_2 as Some).0: i32);
44+
_0 = Add(copy _4, copy _4);
6345
return;
6446
}
6547

66-
bb3: {
48+
bb2: {
6749
unreachable;
6850
}
6951
}

0 commit comments

Comments
 (0)