Skip to content

Commit 79e961f

Browse files
committed
Auto merge of rust-lang#117783 - tmiasko:inline-ret, r=cjgillot
Fix insertion of statements to be executed along return edge in inlining Inlining creates additional statements to be executed along the return edge: an assignment to the destination, storage end for temporaries. Previously those statements where inserted directly into a call target, but this is incorrect when the target has other predecessors. Avoid the issue by creating a new dedicated block for those statements. When the block happens to be redundant it will be removed by CFG simplification that follows inlining. Fixes rust-lang#117355
2 parents 19079cf + 1be1c2e commit 79e961f

13 files changed

+356
-725
lines changed

compiler/rustc_mir_transform/src/inline.rs

+163-134
Large diffs are not rendered by default.

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

+22-22
Original file line numberDiff line numberDiff line change
@@ -69,66 +69,66 @@
6969
+ }
7070
+
7171
+ bb2: {
72+
+ _4 = <() as F>::call() -> [return: bb1, unwind unreachable];
73+
+ }
74+
+
75+
+ bb3: {
7276
+ StorageDead(_7);
7377
+ StorageDead(_6);
7478
+ StorageDead(_5);
75-
+ _3 = <() as F>::call() -> [return: bb3, unwind unreachable];
79+
+ _3 = <() as F>::call() -> [return: bb2, unwind unreachable];
7680
+ }
7781
+
78-
+ bb3: {
79-
+ _4 = <() as F>::call() -> [return: bb1, unwind unreachable];
82+
+ bb4: {
83+
+ _7 = <() as E>::call() -> [return: bb3, unwind unreachable];
8084
+ }
8185
+
82-
+ bb4: {
86+
+ bb5: {
8387
+ StorageDead(_10);
8488
+ StorageDead(_9);
8589
+ StorageDead(_8);
86-
+ _6 = <() as E>::call() -> [return: bb5, unwind unreachable];
90+
+ _6 = <() as E>::call() -> [return: bb4, unwind unreachable];
8791
+ }
8892
+
89-
+ bb5: {
90-
+ _7 = <() as E>::call() -> [return: bb2, unwind unreachable];
93+
+ bb6: {
94+
+ _10 = <() as D>::call() -> [return: bb5, unwind unreachable];
9195
+ }
9296
+
93-
+ bb6: {
97+
+ bb7: {
9498
+ StorageDead(_13);
9599
+ StorageDead(_12);
96100
+ StorageDead(_11);
97-
+ _9 = <() as D>::call() -> [return: bb7, unwind unreachable];
101+
+ _9 = <() as D>::call() -> [return: bb6, unwind unreachable];
98102
+ }
99103
+
100-
+ bb7: {
101-
+ _10 = <() as D>::call() -> [return: bb4, unwind unreachable];
104+
+ bb8: {
105+
+ _13 = <() as C>::call() -> [return: bb7, unwind unreachable];
102106
+ }
103107
+
104-
+ bb8: {
108+
+ bb9: {
105109
+ StorageDead(_16);
106110
+ StorageDead(_15);
107111
+ StorageDead(_14);
108-
+ _12 = <() as C>::call() -> [return: bb9, unwind unreachable];
112+
+ _12 = <() as C>::call() -> [return: bb8, unwind unreachable];
109113
+ }
110114
+
111-
+ bb9: {
112-
+ _13 = <() as C>::call() -> [return: bb6, unwind unreachable];
115+
+ bb10: {
116+
+ _16 = <() as B>::call() -> [return: bb9, unwind unreachable];
113117
+ }
114118
+
115-
+ bb10: {
119+
+ bb11: {
116120
+ StorageDead(_19);
117121
+ StorageDead(_18);
118122
+ StorageDead(_17);
119-
+ _15 = <() as B>::call() -> [return: bb11, unwind unreachable];
120-
+ }
121-
+
122-
+ bb11: {
123-
+ _16 = <() as B>::call() -> [return: bb8, unwind unreachable];
123+
+ _15 = <() as B>::call() -> [return: bb10, unwind unreachable];
124124
+ }
125125
+
126126
+ bb12: {
127127
+ _18 = <() as A>::call() -> [return: bb13, unwind unreachable];
128128
+ }
129129
+
130130
+ bb13: {
131-
+ _19 = <() as A>::call() -> [return: bb10, unwind unreachable];
131+
+ _19 = <() as A>::call() -> [return: bb11, unwind unreachable];
132132
}
133133
}
134134

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

+22-22
Original file line numberDiff line numberDiff line change
@@ -69,66 +69,66 @@
6969
+ }
7070
+
7171
+ bb2: {
72+
+ _4 = <() as F>::call() -> [return: bb1, unwind continue];
73+
+ }
74+
+
75+
+ bb3: {
7276
+ StorageDead(_7);
7377
+ StorageDead(_6);
7478
+ StorageDead(_5);
75-
+ _3 = <() as F>::call() -> [return: bb3, unwind continue];
79+
+ _3 = <() as F>::call() -> [return: bb2, unwind continue];
7680
+ }
7781
+
78-
+ bb3: {
79-
+ _4 = <() as F>::call() -> [return: bb1, unwind continue];
82+
+ bb4: {
83+
+ _7 = <() as E>::call() -> [return: bb3, unwind continue];
8084
+ }
8185
+
82-
+ bb4: {
86+
+ bb5: {
8387
+ StorageDead(_10);
8488
+ StorageDead(_9);
8589
+ StorageDead(_8);
86-
+ _6 = <() as E>::call() -> [return: bb5, unwind continue];
90+
+ _6 = <() as E>::call() -> [return: bb4, unwind continue];
8791
+ }
8892
+
89-
+ bb5: {
90-
+ _7 = <() as E>::call() -> [return: bb2, unwind continue];
93+
+ bb6: {
94+
+ _10 = <() as D>::call() -> [return: bb5, unwind continue];
9195
+ }
9296
+
93-
+ bb6: {
97+
+ bb7: {
9498
+ StorageDead(_13);
9599
+ StorageDead(_12);
96100
+ StorageDead(_11);
97-
+ _9 = <() as D>::call() -> [return: bb7, unwind continue];
101+
+ _9 = <() as D>::call() -> [return: bb6, unwind continue];
98102
+ }
99103
+
100-
+ bb7: {
101-
+ _10 = <() as D>::call() -> [return: bb4, unwind continue];
104+
+ bb8: {
105+
+ _13 = <() as C>::call() -> [return: bb7, unwind continue];
102106
+ }
103107
+
104-
+ bb8: {
108+
+ bb9: {
105109
+ StorageDead(_16);
106110
+ StorageDead(_15);
107111
+ StorageDead(_14);
108-
+ _12 = <() as C>::call() -> [return: bb9, unwind continue];
112+
+ _12 = <() as C>::call() -> [return: bb8, unwind continue];
109113
+ }
110114
+
111-
+ bb9: {
112-
+ _13 = <() as C>::call() -> [return: bb6, unwind continue];
115+
+ bb10: {
116+
+ _16 = <() as B>::call() -> [return: bb9, unwind continue];
113117
+ }
114118
+
115-
+ bb10: {
119+
+ bb11: {
116120
+ StorageDead(_19);
117121
+ StorageDead(_18);
118122
+ StorageDead(_17);
119-
+ _15 = <() as B>::call() -> [return: bb11, unwind continue];
120-
+ }
121-
+
122-
+ bb11: {
123-
+ _16 = <() as B>::call() -> [return: bb8, unwind continue];
123+
+ _15 = <() as B>::call() -> [return: bb10, unwind continue];
124124
+ }
125125
+
126126
+ bb12: {
127127
+ _18 = <() as A>::call() -> [return: bb13, unwind continue];
128128
+ }
129129
+
130130
+ bb13: {
131-
+ _19 = <() as A>::call() -> [return: bb10, unwind continue];
131+
+ _19 = <() as A>::call() -> [return: bb11, unwind continue];
132132
}
133133
}
134134

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Test for inlining with an indirect destination place.
2+
//
3+
// unit-test: Inline
4+
// edition: 2021
5+
// needs-unwind
6+
#![crate_type = "lib"]
7+
#![feature(custom_mir, core_intrinsics)]
8+
use core::intrinsics::mir::*;
9+
10+
#[custom_mir(dialect = "runtime", phase = "initial")]
11+
// CHECK-LABEL: fn f(
12+
// CHECK: bb1: {
13+
// CHECK-NEXT: StorageLive([[A:.*]]);
14+
// CHECK-NEXT: [[A]] = &mut (*_1);
15+
// CHECK-NEXT: StorageLive([[B:.*]]);
16+
// CHECK-NEXT: [[B]] = const 42_u8;
17+
// CHECK-NEXT: (*[[A]]) = move [[B]];
18+
// CHECK-NEXT: StorageDead([[B]]);
19+
// CHECK-NEXT: StorageDead([[A]]);
20+
// CHECK-NEXT: goto -> bb1;
21+
// CHECK-NEXT: }
22+
pub fn f(a: *mut u8) {
23+
mir! {
24+
{
25+
Goto(bb1)
26+
}
27+
bb1 = {
28+
Call(*a = g(), bb1, UnwindUnreachable())
29+
}
30+
}
31+
}
32+
33+
#[custom_mir(dialect = "runtime", phase = "initial")]
34+
#[inline(always)]
35+
fn g() -> u8 {
36+
mir! {
37+
{
38+
RET = 42;
39+
Return()
40+
}
41+
}
42+
}

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

+11-11
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@
5050
bb1: {
5151
- _3 = &mut _4;
5252
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind unreachable];
53-
+ StorageDead(_7);
54-
+ StorageDead(_6);
55-
+ StorageDead(_5);
56-
+ StorageDead(_2);
57-
+ drop(_4) -> [return: bb2, unwind unreachable];
53+
+ StorageDead(_4);
54+
+ _0 = const ();
55+
+ StorageDead(_1);
56+
+ return;
5857
}
5958

6059
bb2: {
6160
- StorageDead(_3);
6261
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
63-
+ StorageDead(_4);
64-
+ _0 = const ();
65-
+ StorageDead(_1);
66-
+ return;
62+
+ StorageDead(_7);
63+
+ StorageDead(_6);
64+
+ StorageDead(_5);
65+
+ StorageDead(_2);
66+
+ drop(_4) -> [return: bb1, unwind unreachable];
6767
}
6868

6969
bb3: {
@@ -90,7 +90,7 @@
9090
+ bb6: {
9191
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
9292
+ discriminant((*_6)) = 3;
93-
+ goto -> bb1;
93+
+ goto -> bb2;
9494
+ }
9595
+
9696
+ bb7: {
@@ -102,7 +102,7 @@
102102
+ StorageDead(_8);
103103
+ _1 = CoroutineState::<i32, bool>::Complete(_5);
104104
+ discriminant((*_6)) = 1;
105-
+ goto -> bb1;
105+
+ goto -> bb2;
106106
+ }
107107
+
108108
+ bb9: {

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

+38-36
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,10 @@
3434
StorageLive(_3);
3535
StorageLive(_4);
3636
- _4 = g() -> [return: bb1, unwind continue];
37-
- }
38-
-
39-
- bb1: {
4037
+ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)};
41-
_3 = &mut _4;
42-
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5];
43-
- }
44-
-
45-
- bb2: {
38+
+ _3 = &mut _4;
4639
+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: move _3 };
47-
StorageDead(_3);
48-
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
40+
+ StorageDead(_3);
4941
+ StorageLive(_5);
5042
+ _5 = const false;
5143
+ StorageLive(_6);
@@ -55,40 +47,50 @@
5547
+ switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
5648
}
5749

50+
bb1: {
51+
- _3 = &mut _4;
52+
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5];
53+
+ StorageDead(_4);
54+
+ _0 = const ();
55+
+ StorageDead(_1);
56+
+ return;
57+
}
58+
59+
- bb2: {
60+
- StorageDead(_3);
61+
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
62+
+ bb2 (cleanup): {
63+
+ drop(_4) -> [return: bb3, unwind terminate(cleanup)];
64+
}
65+
5866
- bb3: {
59-
+ bb1: {
60-
+ StorageDead(_7);
61-
+ StorageDead(_6);
62-
+ StorageDead(_5);
63-
StorageDead(_2);
67+
- StorageDead(_2);
6468
- drop(_4) -> [return: bb4, unwind: bb6];
65-
+ drop(_4) -> [return: bb2, unwind: bb4];
69+
+ bb3 (cleanup): {
70+
+ resume;
6671
}
6772

68-
- bb4: {
69-
+ bb2: {
70-
StorageDead(_4);
71-
_0 = const ();
72-
StorageDead(_1);
73-
return;
73+
bb4: {
74+
- StorageDead(_4);
75+
- _0 = const ();
76+
- StorageDead(_1);
77+
- return;
78+
+ StorageDead(_7);
79+
+ StorageDead(_6);
80+
+ StorageDead(_5);
81+
+ StorageDead(_2);
82+
+ drop(_4) -> [return: bb1, unwind: bb3];
7483
}
7584

7685
- bb5 (cleanup): {
7786
- drop(_4) -> [return: bb6, unwind terminate(cleanup)];
78-
+ bb3 (cleanup): {
79-
+ drop(_4) -> [return: bb4, unwind terminate(cleanup)];
80-
}
81-
82-
- bb6 (cleanup): {
83-
+ bb4 (cleanup): {
84-
resume;
85-
+ }
86-
+
8787
+ bb5: {
8888
+ StorageLive(_8);
8989
+ switchInt(_5) -> [0: bb6, otherwise: bb7];
90-
+ }
91-
+
90+
}
91+
92+
- bb6 (cleanup): {
93+
- resume;
9294
+ bb6: {
9395
+ _8 = const 13_i32;
9496
+ goto -> bb8;
@@ -102,19 +104,19 @@
102104
+ bb8: {
103105
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
104106
+ discriminant((*_6)) = 3;
105-
+ goto -> bb1;
107+
+ goto -> bb4;
106108
+ }
107109
+
108110
+ bb9: {
109-
+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb3];
111+
+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb2];
110112
+ }
111113
+
112114
+ bb10: {
113115
+ StorageLive(_8);
114116
+ StorageDead(_8);
115117
+ _1 = CoroutineState::<i32, bool>::Complete(_5);
116118
+ discriminant((*_6)) = 1;
117-
+ goto -> bb1;
119+
+ goto -> bb4;
118120
+ }
119121
+
120122
+ bb11: {

0 commit comments

Comments
 (0)