diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index dc35381fe22..bf5f0ca7cbd 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -568,10 +568,11 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &[ &check_alignment::CheckAlignment, &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first - &unreachable_prop::UnreachablePropagation, - &uninhabited_enum_branching::UninhabitedEnumBranching, - &o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching), &inline::Inline, + // Substitutions during inlining may introduce switch on enums with uninhabited branches. + &uninhabited_enum_branching::UninhabitedEnumBranching, + &unreachable_prop::UnreachablePropagation, + &o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching), &remove_storage_markers::RemoveStorageMarkers, &remove_zsts::RemoveZsts, &normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index ea7aafd866b..c7e22dfe842 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -2,7 +2,6 @@ //! when all of their successors are unreachable. This is achieved through a //! post-order traversal of the blocks. -use crate::simplify; use crate::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::*; @@ -52,8 +51,6 @@ impl MirPass<'_> for UnreachablePropagation { body.basic_blocks_mut()[bb].statements.clear(); } - let replaced = !replacements.is_empty(); - for (bb, terminator_kind) in replacements { if !tcx.consider_optimizing(|| { format!("UnreachablePropagation {:?} ", body.source.def_id()) @@ -64,9 +61,7 @@ impl MirPass<'_> for UnreachablePropagation { body.basic_blocks_mut()[bb].terminator_mut().kind = terminator_kind; } - if replaced { - simplify::remove_dead_blocks(body); - } + // Do not remove dead blocks, let `SimplifyCfg` do it. } } diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index 491db551a7d..fe4b33001fc 100644 --- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -52,7 +52,7 @@ StorageLive(_10); StorageLive(_11); _9 = discriminant(_1); - switchInt(move _9) -> [0: bb7, 1: bb5, otherwise: bb6]; + switchInt(move _9) -> [0: bb6, 1: bb5, otherwise: bb3]; } bb1: { @@ -92,10 +92,6 @@ } bb6: { - unreachable; - } - - bb7: { _10 = ((_1 as Ok).0: i32); _3 = ControlFlow::, i32>::Continue(move _10); goto -> bb1; diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff index eb5a0c39b0b..aec22e0328c 100644 --- a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff +++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff @@ -24,8 +24,7 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [1: bb2, otherwise: bb6]; -+ switchInt(move _2) -> [1: bb2, otherwise: bb3]; + switchInt(move _2) -> [1: bb2, otherwise: bb6]; } bb2: { @@ -36,29 +35,31 @@ - StorageLive(_6); - _6 = const true; - switchInt(move _6) -> [0: bb4, otherwise: bb3]; -- } -- -- bb3: { ++ unreachable; + } + + bb3: { - _4 = const 21_i32; - _5 = const (); - goto -> bb5; -- } -- -- bb4: { ++ unreachable; + } + + bb4: { - _4 = const 42_i32; - _5 = const (); - goto -> bb5; -- } -- -- bb5: { ++ unreachable; + } + + bb5: { - StorageDead(_6); - StorageDead(_5); - StorageLive(_7); unreachable; } -- bb6: { -+ bb3: { + bb6: { _0 = const (); StorageDead(_1); return; diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff index 906dce9819f..b2e8ab95d94 100644 --- a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff +++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff @@ -24,8 +24,7 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [1: bb2, otherwise: bb6]; -+ switchInt(move _2) -> [1: bb2, otherwise: bb3]; + switchInt(move _2) -> [1: bb2, otherwise: bb6]; } bb2: { @@ -36,29 +35,31 @@ - StorageLive(_6); - _6 = const true; - switchInt(move _6) -> [0: bb4, otherwise: bb3]; -- } -- -- bb3: { ++ unreachable; + } + + bb3: { - _4 = const 21_i32; - _5 = const (); - goto -> bb5; -- } -- -- bb4: { ++ unreachable; + } + + bb4: { - _4 = const 42_i32; - _5 = const (); - goto -> bb5; -- } -- -- bb5: { ++ unreachable; + } + + bb5: { - StorageDead(_6); - StorageDead(_5); - StorageLive(_7); unreachable; } -- bb6: { -+ bb3: { + bb6: { _0 = const (); StorageDead(_1); return; diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index 5c0df09b752..9e8b0600b19 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -1,5 +1,6 @@ -// skip-filecheck +// unit-test: UnreachablePropagation // EMIT_MIR_FOR_EACH_PANIC_STRATEGY + enum Empty {} fn empty() -> Option { @@ -8,6 +9,21 @@ fn empty() -> Option { // EMIT_MIR unreachable.main.UnreachablePropagation.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: bb0: { + // CHECK: {{_.*}} = empty() + // CHECK: bb1: { + // CHECK: switchInt({{.*}}) -> [1: bb2, otherwise: bb6]; + // CHECK: bb2: { + // CHECK: unreachable; + // CHECK: bb3: { + // CHECK: unreachable; + // CHECK: bb4: { + // CHECK: unreachable; + // CHECK: bb5: { + // CHECK: unreachable; + // CHECK: bb6: { + // CHECK: return; if let Some(_x) = empty() { let mut _y; diff --git a/tests/mir-opt/unreachable_diverging.rs b/tests/mir-opt/unreachable_diverging.rs index 3713bcaea16..95ea6cb00f9 100644 --- a/tests/mir-opt/unreachable_diverging.rs +++ b/tests/mir-opt/unreachable_diverging.rs @@ -1,5 +1,6 @@ -// skip-filecheck +// unit-test: UnreachablePropagation // EMIT_MIR_FOR_EACH_PANIC_STRATEGY + pub enum Empty {} fn empty() -> Option { @@ -12,6 +13,21 @@ fn loop_forever() { // EMIT_MIR unreachable_diverging.main.UnreachablePropagation.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: bb0: { + // CHECK: {{_.*}} = empty() + // CHECK: bb1: { + // CHECK: switchInt({{.*}}) -> [1: bb2, otherwise: bb6]; + // CHECK: bb2: { + // CHECK: switchInt({{.*}}) -> [0: bb4, otherwise: bb3]; + // CHECK: bb3: { + // CHECK: {{_.*}} = loop_forever() + // CHECK: bb4: { + // CHECK: unreachable; + // CHECK: bb5: { + // CHECK: unreachable; + // CHECK: bb6: { + // CHECK: return; let x = true; if let Some(bomb) = empty() { if x {