Skip to content

Commit aa21fc2

Browse files
committed
Add a MIR test for simplifying checked_sub
1 parent a18bd8a commit aa21fc2

5 files changed

+287
-1
lines changed

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

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// skip-filecheck
21
//@ compile-flags: -O -Zmir-opt-level=2
32
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
43

@@ -8,10 +7,35 @@
87
// EMIT_MIR checked_ops.step_forward.PreCodegen.after.mir
98
pub fn step_forward(x: u16, n: usize) -> u16 {
109
// This uses `u16` so that the conversion to usize is always widening.
10+
11+
// CHECK-LABEL: fn step_forward
12+
// CHECK: inlined{{.+}}forward
1113
std::iter::Step::forward(x, n)
1214
}
1315

1416
// EMIT_MIR checked_ops.checked_shl.PreCodegen.after.mir
1517
pub fn checked_shl(x: u32, rhs: u32) -> Option<u32> {
18+
// CHECK-LABEL: fn checked_shl
19+
// CHECK: [[TEMP:_[0-9]+]] = ShlUnchecked(copy _1, copy _2)
20+
// CHECK: _0 = Option::<u32>::Some({{move|copy}} [[TEMP]])
1621
x.checked_shl(rhs)
1722
}
23+
24+
// EMIT_MIR checked_ops.use_checked_sub.PreCodegen.after.mir
25+
// EMIT_MIR checked_ops.use_checked_sub.GVN.diff
26+
pub fn use_checked_sub(x: u32, rhs: u32) {
27+
// We want this to be equivalent to open-coding it, leaving no `Option`s around.
28+
29+
// CHECK-LABEL: fn use_checked_sub
30+
// FIXME-CHECK-NOT: let{{.+}}Option
31+
// CHECK: inlined{{.+}}u32{{.+}}checked_sub
32+
// CHECK: [[DELTA:_[0-9]+]] = SubUnchecked(copy _1, copy _2)
33+
// FIXME-CHECK: do_something({{move|copy}} [[DELTA]])
34+
if let Some(delta) = x.checked_sub(rhs) {
35+
do_something(delta);
36+
}
37+
}
38+
39+
unsafe extern "Rust" {
40+
safe fn do_something(_: u32);
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
- // MIR for `use_checked_sub` before GVN
2+
+ // MIR for `use_checked_sub` after GVN
3+
4+
fn use_checked_sub(_1: u32, _2: u32) -> () {
5+
debug x => _1;
6+
debug rhs => _2;
7+
let mut _0: ();
8+
let mut _3: std::option::Option<u32>;
9+
let mut _4: u32;
10+
let mut _5: u32;
11+
let mut _6: isize;
12+
let _8: ();
13+
let mut _9: u32;
14+
scope 1 {
15+
debug delta => _7;
16+
let _7: u32;
17+
scope 2 (inlined core::num::<impl u32>::checked_sub) {
18+
let mut _10: bool;
19+
let mut _11: u32;
20+
}
21+
}
22+
23+
bb0: {
24+
StorageLive(_3);
25+
StorageLive(_4);
26+
_4 = copy _1;
27+
StorageLive(_5);
28+
_5 = copy _2;
29+
StorageLive(_10);
30+
- _10 = Lt(copy _4, copy _5);
31+
+ _10 = Lt(copy _1, copy _2);
32+
switchInt(move _10) -> [0: bb5, otherwise: bb4];
33+
}
34+
35+
bb1: {
36+
- StorageLive(_7);
37+
+ nop;
38+
_7 = copy ((_3 as Some).0: u32);
39+
StorageLive(_9);
40+
_9 = copy _7;
41+
- _8 = do_something(move _9) -> [return: bb2, unwind unreachable];
42+
+ _8 = do_something(copy _7) -> [return: bb2, unwind unreachable];
43+
}
44+
45+
bb2: {
46+
StorageDead(_9);
47+
- StorageDead(_7);
48+
+ nop;
49+
goto -> bb3;
50+
}
51+
52+
bb3: {
53+
StorageDead(_3);
54+
return;
55+
}
56+
57+
bb4: {
58+
_3 = const Option::<u32>::None;
59+
goto -> bb6;
60+
}
61+
62+
bb5: {
63+
StorageLive(_11);
64+
- _11 = SubUnchecked(copy _4, copy _5);
65+
+ _11 = SubUnchecked(copy _1, copy _2);
66+
_3 = Option::<u32>::Some(move _11);
67+
StorageDead(_11);
68+
goto -> bb6;
69+
}
70+
71+
bb6: {
72+
StorageDead(_10);
73+
StorageDead(_5);
74+
StorageDead(_4);
75+
_6 = discriminant(_3);
76+
switchInt(move _6) -> [1: bb1, 0: bb3, otherwise: bb7];
77+
}
78+
79+
bb7: {
80+
unreachable;
81+
}
82+
}
83+
84+
ALLOC0 (size: 8, align: 4) {
85+
00 00 00 00 __ __ __ __ │ ....░░░░
86+
}
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
- // MIR for `use_checked_sub` before GVN
2+
+ // MIR for `use_checked_sub` after GVN
3+
4+
fn use_checked_sub(_1: u32, _2: u32) -> () {
5+
debug x => _1;
6+
debug rhs => _2;
7+
let mut _0: ();
8+
let mut _3: std::option::Option<u32>;
9+
let mut _4: u32;
10+
let mut _5: u32;
11+
let mut _6: isize;
12+
let _8: ();
13+
let mut _9: u32;
14+
scope 1 {
15+
debug delta => _7;
16+
let _7: u32;
17+
scope 2 (inlined core::num::<impl u32>::checked_sub) {
18+
let mut _10: bool;
19+
let mut _11: u32;
20+
}
21+
}
22+
23+
bb0: {
24+
StorageLive(_3);
25+
StorageLive(_4);
26+
_4 = copy _1;
27+
StorageLive(_5);
28+
_5 = copy _2;
29+
StorageLive(_10);
30+
- _10 = Lt(copy _4, copy _5);
31+
+ _10 = Lt(copy _1, copy _2);
32+
switchInt(move _10) -> [0: bb5, otherwise: bb4];
33+
}
34+
35+
bb1: {
36+
- StorageLive(_7);
37+
+ nop;
38+
_7 = copy ((_3 as Some).0: u32);
39+
StorageLive(_9);
40+
_9 = copy _7;
41+
- _8 = do_something(move _9) -> [return: bb2, unwind continue];
42+
+ _8 = do_something(copy _7) -> [return: bb2, unwind continue];
43+
}
44+
45+
bb2: {
46+
StorageDead(_9);
47+
- StorageDead(_7);
48+
+ nop;
49+
goto -> bb3;
50+
}
51+
52+
bb3: {
53+
StorageDead(_3);
54+
return;
55+
}
56+
57+
bb4: {
58+
_3 = const Option::<u32>::None;
59+
goto -> bb6;
60+
}
61+
62+
bb5: {
63+
StorageLive(_11);
64+
- _11 = SubUnchecked(copy _4, copy _5);
65+
+ _11 = SubUnchecked(copy _1, copy _2);
66+
_3 = Option::<u32>::Some(move _11);
67+
StorageDead(_11);
68+
goto -> bb6;
69+
}
70+
71+
bb6: {
72+
StorageDead(_10);
73+
StorageDead(_5);
74+
StorageDead(_4);
75+
_6 = discriminant(_3);
76+
switchInt(move _6) -> [1: bb1, 0: bb3, otherwise: bb7];
77+
}
78+
79+
bb7: {
80+
unreachable;
81+
}
82+
}
83+
84+
ALLOC0 (size: 8, align: 4) {
85+
00 00 00 00 __ __ __ __ │ ....░░░░
86+
}
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// MIR for `use_checked_sub` after PreCodegen
2+
3+
fn use_checked_sub(_1: u32, _2: u32) -> () {
4+
debug x => _1;
5+
debug rhs => _2;
6+
let mut _0: ();
7+
let mut _5: std::option::Option<u32>;
8+
let _7: ();
9+
scope 1 {
10+
debug delta => _6;
11+
let _6: u32;
12+
scope 2 (inlined core::num::<impl u32>::checked_sub) {
13+
let mut _3: bool;
14+
let mut _4: u32;
15+
}
16+
}
17+
18+
bb0: {
19+
StorageLive(_5);
20+
StorageLive(_3);
21+
_3 = Lt(copy _1, copy _2);
22+
switchInt(move _3) -> [0: bb1, otherwise: bb2];
23+
}
24+
25+
bb1: {
26+
StorageLive(_4);
27+
_4 = SubUnchecked(copy _1, copy _2);
28+
_5 = Option::<u32>::Some(move _4);
29+
StorageDead(_4);
30+
StorageDead(_3);
31+
_6 = copy ((_5 as Some).0: u32);
32+
_7 = do_something(move _6) -> [return: bb3, unwind unreachable];
33+
}
34+
35+
bb2: {
36+
StorageDead(_3);
37+
goto -> bb3;
38+
}
39+
40+
bb3: {
41+
StorageDead(_5);
42+
return;
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// MIR for `use_checked_sub` after PreCodegen
2+
3+
fn use_checked_sub(_1: u32, _2: u32) -> () {
4+
debug x => _1;
5+
debug rhs => _2;
6+
let mut _0: ();
7+
let mut _5: std::option::Option<u32>;
8+
let _7: ();
9+
scope 1 {
10+
debug delta => _6;
11+
let _6: u32;
12+
scope 2 (inlined core::num::<impl u32>::checked_sub) {
13+
let mut _3: bool;
14+
let mut _4: u32;
15+
}
16+
}
17+
18+
bb0: {
19+
StorageLive(_5);
20+
StorageLive(_3);
21+
_3 = Lt(copy _1, copy _2);
22+
switchInt(move _3) -> [0: bb1, otherwise: bb2];
23+
}
24+
25+
bb1: {
26+
StorageLive(_4);
27+
_4 = SubUnchecked(copy _1, copy _2);
28+
_5 = Option::<u32>::Some(move _4);
29+
StorageDead(_4);
30+
StorageDead(_3);
31+
_6 = copy ((_5 as Some).0: u32);
32+
_7 = do_something(move _6) -> [return: bb3, unwind continue];
33+
}
34+
35+
bb2: {
36+
StorageDead(_3);
37+
goto -> bb3;
38+
}
39+
40+
bb3: {
41+
StorageDead(_5);
42+
return;
43+
}
44+
}

0 commit comments

Comments
 (0)