Skip to content

Commit 9949d31

Browse files
committed
Implement a few basic InstCombine optimizations
1 parent 6bba061 commit 9949d31

31 files changed

+1211
-458
lines changed

compiler/rustc_mir_transform/src/instcombine.rs

+424
Large diffs are not rendered by default.

compiler/rustc_mir_transform/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ mod ffi_unwind_calls;
7676
mod function_item_references;
7777
mod generator;
7878
mod inline;
79+
mod instcombine;
7980
mod instsimplify;
8081
mod large_enums;
8182
mod lower_intrinsics;
@@ -575,6 +576,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
575576
&simplify_comparison_integral::SimplifyComparisonIntegral,
576577
&dead_store_elimination::DeadStoreElimination,
577578
&dest_prop::DestinationPropagation,
579+
&instcombine::InstCombine,
578580
&o1(simplify_branches::SimplifyConstCondition::Final),
579581
&o1(remove_noop_landing_pads::RemoveNoopLandingPads),
580582
&o1(simplify::SimplifyCfg::Final),

tests/mir-opt/casts.roundtrip.PreCodegen.after.mir

+1-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@
33
fn roundtrip(_1: *const u8) -> *const u8 {
44
debug x => _1;
55
let mut _0: *const u8;
6-
let mut _2: *mut u8;
76

87
bb0: {
9-
StorageLive(_2);
10-
_2 = _1 as *mut u8 (PtrToPtr);
11-
_0 = move _2 as *const u8 (Pointer(MutToConstPointer));
12-
StorageDead(_2);
8+
_0 = _1 as *const u8 (PtrToPtr);
139
return;
1410
}
1511
}

tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff

+3-5
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,11 @@
158158
+ StorageLive(_17);
159159
+ StorageLive(_18);
160160
+ _18 = (_11.0: *const [u8]);
161-
+ _17 = move _18 as *mut [u8] (PtrToPtr);
162-
+ StorageDead(_18);
163-
+ _16 = _17 as *mut u8 (PtrToPtr);
164-
+ StorageDead(_17);
165161
+ StorageLive(_19);
162+
+ _19 = move _18 as *const u8 (PtrToPtr);
163+
+ StorageDead(_18);
166164
+ StorageLive(_20);
167-
+ _19 = _16 as *const u8 (Pointer(MutToConstPointer));
165+
+ StorageDead(_17);
168166
+ _15 = NonNull::<u8> { pointer: _19 };
169167
+ StorageDead(_20);
170168
+ StorageDead(_19);

tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff

+3-5
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,11 @@
175175
+ StorageLive(_17);
176176
+ StorageLive(_18);
177177
+ _18 = (_11.0: *const [u8]);
178-
+ _17 = move _18 as *mut [u8] (PtrToPtr);
179-
+ StorageDead(_18);
180-
+ _16 = _17 as *mut u8 (PtrToPtr);
181-
+ StorageDead(_17);
182178
+ StorageLive(_19);
179+
+ _19 = move _18 as *const u8 (PtrToPtr);
180+
+ StorageDead(_18);
183181
+ StorageLive(_20);
184-
+ _19 = _16 as *const u8 (Pointer(MutToConstPointer));
182+
+ StorageDead(_17);
185183
+ _15 = NonNull::<u8> { pointer: _19 };
186184
+ StorageDead(_20);
187185
+ StorageDead(_19);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- // MIR for `place_projection` before InstCombine
2+
+ // MIR for `place_projection` after InstCombine
3+
4+
fn place_projection(_1: Outer) -> u8 {
5+
debug o => _1;
6+
let mut _0: u8;
7+
let _2: Inner;
8+
scope 1 {
9+
debug temp => _2;
10+
}
11+
12+
bb0: {
13+
StorageLive(_2);
14+
- _2 = move (_1.0: Inner);
15+
- _0 = (_2.0: u8);
16+
+ _0 = ((_1.0: Inner).0: u8);
17+
+ nop;
18+
StorageDead(_2);
19+
return;
20+
}
21+
}
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// unit-test: InstCombine
2+
#![crate_type = "lib"]
3+
4+
pub struct Outer {
5+
inner: Inner,
6+
}
7+
8+
struct Inner {
9+
field: u8,
10+
}
11+
12+
// EMIT_MIR place_projection.place_projection.InstCombine.diff
13+
pub fn place_projection(o: Outer) -> u8 {
14+
let temp = o.inner;
15+
temp.field
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
- // MIR for `ptr_cast` before InstCombine
2+
+ // MIR for `ptr_cast` after InstCombine
3+
4+
fn ptr_cast(_1: *const u8) -> *mut () {
5+
debug p => _1;
6+
let mut _0: *mut ();
7+
let mut _2: *mut u8;
8+
let mut _3: *const u8;
9+
10+
bb0: {
11+
StorageLive(_2);
12+
StorageLive(_3);
13+
_3 = _1;
14+
- _2 = move _3 as *mut u8 (PtrToPtr);
15+
+ _0 = move _3 as *mut () (PtrToPtr);
16+
+ nop;
17+
StorageDead(_3);
18+
- _0 = move _2 as *mut () (PtrToPtr);
19+
StorageDead(_2);
20+
return;
21+
}
22+
}
23+

tests/mir-opt/instcombine/ptr_cast.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// unit-test: InstCombine
2+
#![crate_type = "lib"]
3+
4+
// EMIT_MIR ptr_cast.ptr_cast.InstCombine.diff
5+
pub fn ptr_cast(p: *const u8) -> *mut () {
6+
p as *mut u8 as *mut ()
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
- // MIR for `ref_addressof` before InstCombine
2+
+ // MIR for `ref_addressof` after InstCombine
3+
4+
fn ref_addressof(_1: T) -> () {
5+
debug t => _1;
6+
let mut _0: ();
7+
let _2: &T;
8+
let _4: ();
9+
let mut _5: *const T;
10+
scope 1 {
11+
debug r => _2;
12+
let _3: *const T;
13+
scope 2 {
14+
debug ptr => _3;
15+
}
16+
}
17+
18+
bb0: {
19+
StorageLive(_2);
20+
- _2 = &_1;
21+
StorageLive(_3);
22+
- _3 = &raw const (*_2);
23+
+ _3 = &raw const _1;
24+
+ nop;
25+
StorageLive(_4);
26+
StorageLive(_5);
27+
_5 = _3;
28+
_4 = std::mem::drop::<*const T>(move _5) -> [return: bb1, unwind unreachable];
29+
}
30+
31+
bb1: {
32+
StorageDead(_5);
33+
StorageDead(_4);
34+
_0 = const ();
35+
StorageDead(_3);
36+
StorageDead(_2);
37+
drop(_1) -> [return: bb2, unwind unreachable];
38+
}
39+
40+
bb2: {
41+
return;
42+
}
43+
}
44+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// unit-test: InstCombine
2+
#![crate_type = "lib"]
3+
4+
// EMIT_MIR ref_addressof.ref_addressof.InstCombine.diff
5+
pub fn ref_addressof<T>(t: T) {
6+
let r = &t;
7+
let ptr = std::ptr::addr_of!(*r);
8+
drop(ptr);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- // MIR for `ref_deref` before InstCombine
2+
+ // MIR for `ref_deref` after InstCombine
3+
4+
fn ref_deref(_1: T) -> T {
5+
debug t => _1;
6+
let mut _0: T;
7+
let _2: &T;
8+
scope 1 {
9+
debug r => _2;
10+
}
11+
12+
bb0: {
13+
StorageLive(_2);
14+
- _2 = &_1;
15+
- _0 = (*_2);
16+
+ _0 = _1;
17+
+ nop;
18+
StorageDead(_2);
19+
return;
20+
}
21+
}
22+
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// unit-test: InstCombine
2+
#![crate_type = "lib"]
3+
4+
// EMIT_MIR ref_deref.ref_deref.InstCombine.diff
5+
pub fn ref_deref<T: Copy>(t: T) -> T {
6+
let r = &t;
7+
*r
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
- // MIR for `outer_get` before InstCombine
2+
+ // MIR for `outer_get` after InstCombine
3+
4+
fn outer_get(_1: &Outer) -> u8 {
5+
debug this => _1;
6+
let mut _0: u8;
7+
let mut _2: &Inner;
8+
let _3: &Inner;
9+
scope 1 (inlined inner_get) {
10+
debug this => &((*_1).0: Inner);
11+
}
12+
13+
bb0: {
14+
_0 = (((*_1).0: Inner).0: u8);
15+
return;
16+
}
17+
}
18+

tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir

+26-30
Original file line numberDiff line numberDiff line change
@@ -6,76 +6,72 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
66
let mut _0: ();
77
let mut _3: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
88
let mut _4: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
9-
let mut _5: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
10-
let mut _6: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
11-
let mut _9: std::option::Option<U>;
12-
let mut _10: isize;
13-
let _12: ();
9+
let mut _5: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
10+
let mut _8: std::option::Option<U>;
11+
let mut _9: isize;
12+
let _11: ();
1413
scope 1 {
15-
debug iter => _5;
16-
let _11: U;
14+
debug iter => _4;
15+
let _10: U;
1716
scope 2 {
18-
debug x => _11;
17+
debug x => _10;
1918
}
2019
scope 4 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as Iterator>::next) {
21-
debug self => _6;
22-
let mut _7: &mut impl Iterator<Item = T>;
23-
let mut _8: &mut impl Fn(T) -> Option<U>;
20+
debug self => _5;
21+
let mut _6: &mut impl Iterator<Item = T>;
22+
let mut _7: &mut impl Fn(T) -> Option<U>;
2423
}
2524
}
2625
scope 3 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as IntoIterator>::into_iter) {
2726
debug self => _3;
2827
}
2928

3029
bb0: {
31-
StorageLive(_4);
3230
StorageLive(_3);
3331
_3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> bb1;
3432
}
3533

3634
bb1: {
35+
StorageLive(_4);
3736
_4 = move _3;
3837
StorageDead(_3);
39-
StorageLive(_5);
40-
_5 = move _4;
4138
goto -> bb2;
4239
}
4340

4441
bb2: {
45-
StorageLive(_9);
46-
_6 = &mut _5;
47-
StorageLive(_7);
48-
_7 = &mut ((*_6).0: impl Iterator<Item = T>);
4942
StorageLive(_8);
50-
_8 = &mut ((*_6).1: impl Fn(T) -> Option<U>);
51-
_9 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _7, move _8) -> [return: bb3, unwind: bb9];
43+
_5 = &mut _4;
44+
StorageLive(_6);
45+
_6 = &mut ((*_5).0: impl Iterator<Item = T>);
46+
StorageLive(_7);
47+
_7 = &mut ((*_5).1: impl Fn(T) -> Option<U>);
48+
_8 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _6, move _7) -> [return: bb3, unwind: bb9];
5249
}
5350

5451
bb3: {
55-
StorageDead(_8);
5652
StorageDead(_7);
57-
_10 = discriminant(_9);
58-
switchInt(move _10) -> [0: bb4, 1: bb6, otherwise: bb8];
53+
StorageDead(_6);
54+
_9 = discriminant(_8);
55+
switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8];
5956
}
6057

6158
bb4: {
62-
StorageDead(_9);
63-
drop(_5) -> bb5;
59+
StorageDead(_8);
60+
drop(_4) -> bb5;
6461
}
6562

6663
bb5: {
67-
StorageDead(_5);
6864
StorageDead(_4);
6965
return;
7066
}
7167

7268
bb6: {
73-
_11 = move ((_9 as Some).0: U);
74-
_12 = opaque::<U>(move _11) -> [return: bb7, unwind: bb9];
69+
_10 = move ((_8 as Some).0: U);
70+
_11 = opaque::<U>(move _10) -> [return: bb7, unwind: bb9];
7571
}
7672

7773
bb7: {
78-
StorageDead(_9);
74+
StorageDead(_8);
7975
goto -> bb2;
8076
}
8177

@@ -84,7 +80,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
8480
}
8581

8682
bb9 (cleanup): {
87-
drop(_5) -> [return: bb10, unwind terminate];
83+
drop(_4) -> [return: bb10, unwind terminate];
8884
}
8985

9086
bb10 (cleanup): {

0 commit comments

Comments
 (0)