Skip to content

Commit f2f297a

Browse files
authored
Rollup merge of #105420 - tmiasko:dest-prop-dead-code, r=JakobDegen
Remove dead code after destination propagation Fixes #105428. cc `@JakobDegen`
2 parents 3fb5d8e + adf53d4 commit f2f297a

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

compiler/rustc_mir_transform/src/dest_prop.rs

+7
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
130130
use std::collections::hash_map::{Entry, OccupiedEntry};
131131

132+
use crate::simplify::remove_dead_blocks;
132133
use crate::MirPass;
133134
use rustc_data_structures::fx::FxHashMap;
134135
use rustc_index::bit_set::BitSet;
@@ -235,6 +236,12 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
235236
apply_merges(body, tcx, &merges, &merged_locals);
236237
}
237238

239+
if round_count != 0 {
240+
// Merging can introduce overlap between moved arguments and/or call destination in an
241+
// unreachable code, which validator considers to be ill-formed.
242+
remove_dead_blocks(tcx, body);
243+
}
244+
238245
trace!(round_count);
239246
}
240247
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
- // MIR for `f` before DestinationPropagation
2+
+ // MIR for `f` after DestinationPropagation
3+
4+
fn f(_1: T) -> () {
5+
debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20
6+
let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25
7+
let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10
8+
let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13
9+
let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16
10+
let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12
11+
let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15
12+
let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16
13+
let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12
14+
let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15
15+
scope 1 {
16+
- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
17+
+ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
18+
}
19+
20+
bb0: {
21+
- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
22+
- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
23+
+ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
24+
+ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
25+
StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
26+
_3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
27+
- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
28+
+ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
29+
}
30+
31+
bb1: {
32+
- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
33+
- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
34+
- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
35+
- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
36+
- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
37+
- _4 = g::<T>(move _5, move _6) -> bb2; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
38+
- // mir::Constant
39+
- // + span: $DIR/unreachable.rs:11:9: 11:10
40+
- // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
41+
- }
42+
-
43+
- bb2: {
44+
- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
45+
- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
46+
- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17
47+
- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6
48+
- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
49+
- }
50+
-
51+
- bb3: {
52+
StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
53+
- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
54+
- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
55+
+ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
56+
+ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
57+
StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
58+
- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
59+
- _7 = g::<T>(move _8, move _9) -> bb4; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
60+
+ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
61+
+ _7 = g::<T>(move _1, move _9) -> bb2; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
62+
// mir::Constant
63+
// + span: $DIR/unreachable.rs:13:9: 13:10
64+
// + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
65+
}
66+
67+
- bb4: {
68+
+ bb2: {
69+
StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
70+
- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
71+
+ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
72+
StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17
73+
_0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6
74+
- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
75+
+ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
76+
}
77+
78+
- bb5: {
79+
+ bb3: {
80+
StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6
81+
- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
82+
+ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
83+
return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2
84+
}
85+
}
86+
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Check that unreachable code is removed after the destination propagation.
2+
// Regression test for issue #105428.
3+
//
4+
// compile-flags: --crate-type=lib -Zmir-opt-level=0
5+
// compile-flags: -Zmir-enable-passes=+ConstProp,+SimplifyConstCondition-after-const-prop,+DestinationPropagation
6+
7+
// EMIT_MIR unreachable.f.DestinationPropagation.diff
8+
pub fn f<T: Copy>(a: T) {
9+
let b = a;
10+
if false {
11+
g(a, b);
12+
} else {
13+
g(b, b);
14+
}
15+
}
16+
17+
#[inline(never)]
18+
pub fn g<T: Copy>(_: T, _: T) {}

0 commit comments

Comments
 (0)