Skip to content

Commit 145d226

Browse files
committed
mir-opt: Create an indirect BB to add StorageDead
1 parent 80c3498 commit 145d226

File tree

3 files changed

+82
-4
lines changed

3 files changed

+82
-4
lines changed

compiler/rustc_mir_transform/src/early_otherwise_branch.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,20 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
193193
let eq_bb = patch.new_block(eq_switch);
194194

195195
// Jump to it on the basis of the inequality comparison
196-
let true_case = opt_data.destination;
197-
let false_case = eq_bb;
196+
let mut true_case = opt_data.destination;
197+
let mut false_case = eq_bb;
198+
// Create an indirect BB to add `StorageDead` If the jump target is itself.
199+
for bb in [&mut false_case, &mut true_case].into_iter() {
200+
if *bb == parent {
201+
*bb = patch.new_block(BasicBlockData::new(
202+
Some(Terminator {
203+
kind: TerminatorKind::Goto { target: parent },
204+
source_info: bbs[parent].terminator().source_info,
205+
}),
206+
bbs[parent].is_cleanup,
207+
));
208+
}
209+
}
198210
patch.patch_terminator(
199211
parent,
200212
TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case),
@@ -210,9 +222,9 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
210222

211223
// Generate a StorageDead for comp_temp in each of the targets, since we moved it into
212224
// the switch
213-
for bb in [false_case, true_case].iter() {
225+
for bb in [false_case, true_case].into_iter() {
214226
patch.add_statement(
215-
Location { block: *bb, statement_index: 0 },
227+
Location { block: bb, statement_index: 0 },
216228
StatementKind::StorageDead(comp_temp),
217229
);
218230
}

tests/mir-opt/early_otherwise_branch.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//@ test-mir-pass: EarlyOtherwiseBranch
22
//@ compile-flags: -Zmir-enable-passes=+UnreachableEnumBranching
33

4+
#![feature(custom_mir, core_intrinsics)]
5+
6+
use std::intrinsics::mir::*;
7+
48
enum Option2<T> {
59
Some(T),
610
None,
@@ -124,11 +128,38 @@ fn opt5_failed_type(x: u32, y: u64) -> u32 {
124128
}
125129
}
126130

131+
// EMIT_MIR early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff
132+
#[custom_mir(dialect = "runtime")]
133+
fn target_self(val: i32) {
134+
// CHECK-LABEL: fn target_self(
135+
mir! {
136+
{
137+
Goto(bb1)
138+
}
139+
bb1 = {
140+
match val {
141+
0 => bb2,
142+
_ => bb1,
143+
}
144+
}
145+
bb2 = {
146+
match val {
147+
0 => bb3,
148+
_ => bb1,
149+
}
150+
}
151+
bb3 = {
152+
Return()
153+
}
154+
}
155+
}
156+
127157
fn main() {
128158
opt1(None, Some(0));
129159
opt2(None, Some(0));
130160
opt3(Option2::None, Option2::Some(false));
131161
opt4(Option2::None, Option2::Some(0));
132162
opt5(0, 0);
133163
opt5_failed(0, 0);
164+
target_self(1);
134165
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
- // MIR for `target_self` before EarlyOtherwiseBranch
2+
+ // MIR for `target_self` after EarlyOtherwiseBranch
3+
4+
fn target_self(_1: i32) -> () {
5+
let mut _0: ();
6+
+ let mut _2: bool;
7+
8+
bb0: {
9+
goto -> bb1;
10+
}
11+
12+
bb1: {
13+
- switchInt(copy _1) -> [0: bb2, otherwise: bb1];
14+
+ StorageLive(_2);
15+
+ _2 = Ne(copy _1, copy _1);
16+
+ switchInt(move _2) -> [0: bb3, otherwise: bb4];
17+
}
18+
19+
bb2: {
20+
- switchInt(copy _1) -> [0: bb3, otherwise: bb1];
21+
+ return;
22+
}
23+
24+
bb3: {
25+
- return;
26+
+ StorageDead(_2);
27+
+ switchInt(copy _1) -> [0: bb2, otherwise: bb1];
28+
+ }
29+
+
30+
+ bb4: {
31+
+ StorageDead(_2);
32+
+ goto -> bb1;
33+
}
34+
}
35+

0 commit comments

Comments
 (0)