Rollup merge of #105420 - tmiasko:dest-prop-dead-code, r=JakobDegen
Remove dead code after destination propagation Fixes #105428. cc `@JakobDegen`
This commit is contained in:
commit
f2f297a4f8
@ -129,6 +129,7 @@
|
||||
|
||||
use std::collections::hash_map::{Entry, OccupiedEntry};
|
||||
|
||||
use crate::simplify::remove_dead_blocks;
|
||||
use crate::MirPass;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
@ -235,6 +236,12 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
apply_merges(body, tcx, &merges, &merged_locals);
|
||||
}
|
||||
|
||||
if round_count != 0 {
|
||||
// Merging can introduce overlap between moved arguments and/or call destination in an
|
||||
// unreachable code, which validator considers to be ill-formed.
|
||||
remove_dead_blocks(tcx, body);
|
||||
}
|
||||
|
||||
trace!(round_count);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
- // MIR for `f` before DestinationPropagation
|
||||
+ // MIR for `f` after DestinationPropagation
|
||||
|
||||
fn f(_1: T) -> () {
|
||||
debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20
|
||||
let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25
|
||||
let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10
|
||||
let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13
|
||||
let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16
|
||||
let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12
|
||||
let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15
|
||||
let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16
|
||||
let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12
|
||||
let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15
|
||||
scope 1 {
|
||||
- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
|
||||
+ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
|
||||
- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
|
||||
+ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10
|
||||
+ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14
|
||||
StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
|
||||
_3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
|
||||
- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
|
||||
+ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
|
||||
- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
|
||||
- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12
|
||||
- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
|
||||
- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15
|
||||
- _4 = g::<T>(move _5, move _6) -> bb2; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/unreachable.rs:11:9: 11:10
|
||||
- // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
|
||||
- }
|
||||
-
|
||||
- bb2: {
|
||||
- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
|
||||
- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16
|
||||
- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17
|
||||
- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6
|
||||
- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
|
||||
- }
|
||||
-
|
||||
- bb3: {
|
||||
StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
|
||||
- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
|
||||
- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
|
||||
+ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
|
||||
+ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12
|
||||
StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
|
||||
- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
|
||||
- _7 = g::<T>(move _8, move _9) -> bb4; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
|
||||
+ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15
|
||||
+ _7 = g::<T>(move _1, move _9) -> bb2; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16
|
||||
// mir::Constant
|
||||
// + span: $DIR/unreachable.rs:13:9: 13:10
|
||||
// + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
- bb4: {
|
||||
+ bb2: {
|
||||
StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
|
||||
- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
|
||||
+ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16
|
||||
StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17
|
||||
_0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6
|
||||
- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
|
||||
+ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6
|
||||
}
|
||||
|
||||
- bb5: {
|
||||
+ bb3: {
|
||||
StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6
|
||||
- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
|
||||
+ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2
|
||||
return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2
|
||||
}
|
||||
}
|
||||
|
18
src/test/mir-opt/dest-prop/unreachable.rs
Normal file
18
src/test/mir-opt/dest-prop/unreachable.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Check that unreachable code is removed after the destination propagation.
|
||||
// Regression test for issue #105428.
|
||||
//
|
||||
// compile-flags: --crate-type=lib -Zmir-opt-level=0
|
||||
// compile-flags: -Zmir-enable-passes=+ConstProp,+SimplifyConstCondition-after-const-prop,+DestinationPropagation
|
||||
|
||||
// EMIT_MIR unreachable.f.DestinationPropagation.diff
|
||||
pub fn f<T: Copy>(a: T) {
|
||||
let b = a;
|
||||
if false {
|
||||
g(a, b);
|
||||
} else {
|
||||
g(b, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn g<T: Copy>(_: T, _: T) {}
|
Loading…
Reference in New Issue
Block a user