Skip to content

Commit 0b13e63

Browse files
committed
Simplify assume of a constant.
1 parent c748ac1 commit 0b13e63

6 files changed

+80
-85
lines changed

compiler/rustc_mir_transform/src/simplify_branches.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,25 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
1616
}
1717

1818
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
19+
trace!("Running SimplifyConstCondition on {:?}", body.source);
1920
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
20-
for block in body.basic_blocks_mut() {
21+
'blocks: for block in body.basic_blocks_mut() {
22+
for stmt in block.statements.iter_mut() {
23+
if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
24+
&& let NonDivergingIntrinsic::Assume(discr) = intrinsic
25+
&& let Operand::Constant(ref c) = discr
26+
&& let Some(constant) = c.const_.try_eval_bool(tcx, param_env)
27+
{
28+
if constant {
29+
stmt.make_nop();
30+
} else {
31+
block.statements.clear();
32+
block.terminator_mut().kind = TerminatorKind::Unreachable;
33+
continue 'blocks;
34+
}
35+
}
36+
}
37+
2138
let terminator = block.terminator_mut();
2239
terminator.kind = match terminator.kind {
2340
TerminatorKind::SwitchInt {

tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff

+11-14
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
+ debug self => _2;
1010
+ let mut _3: &std::option::Option<T>;
1111
+ let mut _4: isize;
12+
+ let mut _5: bool;
13+
+ let mut _6: bool;
1214
+ scope 2 {
1315
+ debug val => _0;
1416
+ }
1517
+ scope 3 {
1618
+ scope 5 (inlined unreachable_unchecked) {
1719
+ scope 6 {
1820
+ scope 7 (inlined unreachable_unchecked::runtime) {
19-
+ let _5: !;
2021
+ }
2122
+ }
2223
+ }
@@ -30,24 +31,20 @@
3031
StorageLive(_2);
3132
_2 = move _1;
3233
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable];
34+
- }
35+
-
36+
- bb1: {
3337
+ StorageLive(_3);
3438
+ StorageLive(_4);
3539
+ StorageLive(_5);
40+
+ StorageLive(_6);
3641
+ _4 = discriminant(_2);
37-
+ switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2];
38-
}
39-
40-
bb1: {
41-
+ assume(const false);
42-
+ _5 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
43-
+ }
44-
+
45-
+ bb2: {
46-
+ unreachable;
47-
+ }
48-
+
49-
+ bb3: {
42+
+ _5 = Ne(_4, const 0_isize);
43+
+ assume(move _5);
44+
+ _6 = Eq(_4, const 1_isize);
45+
+ assume(move _6);
5046
+ _0 = move ((_2 as Some).0: T);
47+
+ StorageDead(_6);
5148
+ StorageDead(_5);
5249
+ StorageDead(_4);
5350
+ StorageDead(_3);

tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff

+17-20
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
+ debug self => _2;
1010
+ let mut _3: &std::option::Option<T>;
1111
+ let mut _4: isize;
12+
+ let mut _5: bool;
13+
+ let mut _6: bool;
1214
+ scope 2 {
1315
+ debug val => _0;
1416
+ }
1517
+ scope 3 {
1618
+ scope 5 (inlined unreachable_unchecked) {
1719
+ scope 6 {
1820
+ scope 7 (inlined unreachable_unchecked::runtime) {
19-
+ let _5: !;
2021
+ }
2122
+ }
2223
+ }
@@ -30,33 +31,29 @@
3031
StorageLive(_2);
3132
_2 = move _1;
3233
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2];
34+
- }
35+
-
36+
- bb1: {
3337
+ StorageLive(_3);
3438
+ StorageLive(_4);
3539
+ StorageLive(_5);
40+
+ StorageLive(_6);
3641
+ _4 = discriminant(_2);
37-
+ switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2];
38-
}
39-
40-
bb1: {
41-
- StorageDead(_2);
42-
- return;
43-
+ assume(const false);
44-
+ _5 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
45-
}
46-
47-
- bb2 (cleanup): {
48-
- resume;
49-
+ bb2: {
50-
+ unreachable;
51-
+ }
52-
+
53-
+ bb3: {
42+
+ _5 = Ne(_4, const 0_isize);
43+
+ assume(move _5);
44+
+ _6 = Eq(_4, const 1_isize);
45+
+ assume(move _6);
5446
+ _0 = move ((_2 as Some).0: T);
47+
+ StorageDead(_6);
5548
+ StorageDead(_5);
5649
+ StorageDead(_4);
5750
+ StorageDead(_3);
58-
+ StorageDead(_2);
59-
+ return;
51+
StorageDead(_2);
52+
return;
53+
- }
54+
-
55+
- bb2 (cleanup): {
56+
- resume;
6057
}
6158
}
6259

tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir

+14-18
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,40 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
66
scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
77
debug self => _1;
88
let mut _2: isize;
9-
let mut _4: &std::option::Option<T>;
9+
let mut _3: bool;
10+
let mut _4: bool;
11+
let mut _5: &std::option::Option<T>;
1012
scope 2 {
1113
debug val => _0;
1214
}
1315
scope 3 {
1416
scope 5 (inlined unreachable_unchecked) {
1517
scope 6 {
1618
scope 7 (inlined unreachable_unchecked::runtime) {
17-
let _3: !;
1819
}
1920
}
2021
}
2122
}
2223
scope 4 (inlined Option::<T>::is_some) {
23-
debug self => _4;
24+
debug self => _5;
2425
}
2526
}
2627

2728
bb0: {
28-
StorageLive(_4);
29+
StorageLive(_5);
2930
StorageLive(_2);
31+
StorageLive(_3);
32+
StorageLive(_4);
3033
_2 = discriminant(_1);
31-
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
32-
}
33-
34-
bb1: {
35-
assume(const false);
36-
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
37-
}
38-
39-
bb2: {
34+
_3 = Ne(_2, const 0_isize);
35+
assume(move _3);
36+
_4 = Eq(_2, const 1_isize);
37+
assume(move _4);
4038
_0 = move ((_1 as Some).0: T);
41-
StorageDead(_2);
4239
StorageDead(_4);
40+
StorageDead(_3);
41+
StorageDead(_2);
42+
StorageDead(_5);
4343
return;
4444
}
45-
46-
bb3: {
47-
unreachable;
48-
}
4945
}

tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir

+14-18
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,40 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
66
scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
77
debug self => _1;
88
let mut _2: isize;
9-
let mut _4: &std::option::Option<T>;
9+
let mut _3: bool;
10+
let mut _4: bool;
11+
let mut _5: &std::option::Option<T>;
1012
scope 2 {
1113
debug val => _0;
1214
}
1315
scope 3 {
1416
scope 5 (inlined unreachable_unchecked) {
1517
scope 6 {
1618
scope 7 (inlined unreachable_unchecked::runtime) {
17-
let _3: !;
1819
}
1920
}
2021
}
2122
}
2223
scope 4 (inlined Option::<T>::is_some) {
23-
debug self => _4;
24+
debug self => _5;
2425
}
2526
}
2627

2728
bb0: {
28-
StorageLive(_4);
29+
StorageLive(_5);
2930
StorageLive(_2);
31+
StorageLive(_3);
32+
StorageLive(_4);
3033
_2 = discriminant(_1);
31-
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
32-
}
33-
34-
bb1: {
35-
assume(const false);
36-
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
37-
}
38-
39-
bb2: {
34+
_3 = Ne(_2, const 0_isize);
35+
assume(move _3);
36+
_4 = Eq(_2, const 1_isize);
37+
assume(move _4);
4038
_0 = move ((_1 as Some).0: T);
41-
StorageDead(_2);
4239
StorageDead(_4);
40+
StorageDead(_3);
41+
StorageDead(_2);
42+
StorageDead(_5);
4343
return;
4444
}
45-
46-
bb3: {
47-
unreachable;
48-
}
4945
}

tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir

+6-14
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,22 @@ fn ub_if_b(_1: Thing) -> Thing {
44
debug t => _1;
55
let mut _0: Thing;
66
let mut _2: isize;
7+
let mut _3: bool;
8+
let mut _4: bool;
79
scope 1 (inlined unreachable_unchecked) {
810
scope 2 {
911
scope 3 (inlined unreachable_unchecked::runtime) {
10-
let _3: !;
1112
}
1213
}
1314
}
1415

1516
bb0: {
1617
_2 = discriminant(_1);
17-
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
18-
}
19-
20-
bb1: {
18+
_3 = Ne(_2, const 1_isize);
19+
assume(move _3);
20+
_4 = Eq(_2, const 0_isize);
21+
assume(move _4);
2122
_0 = move _1;
2223
return;
2324
}
24-
25-
bb2: {
26-
assume(const false);
27-
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
28-
}
29-
30-
bb3: {
31-
unreachable;
32-
}
3325
}

0 commit comments

Comments
 (0)