about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDianQK <dianqk@dianqk.net>2024-02-28 22:35:41 +0800
committerDianQK <dianqk@dianqk.net>2024-03-08 08:15:14 +0800
commitb5bd98d5403c1376dadbc635ae426888320f3f9a (patch)
tree0c0d230ff21dbbe8e662e61828ad975c5c5e82fd
parent3d7f8b4e5b650efc628de9bf4bd5246d3493d261 (diff)
Update MIR with `MirPatch` in `UninhabitedEnumBranching`
-rw-r--r--compiler/rustc_middle/src/mir/patch.rs27
-rw-r--r--compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs67
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff20
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff20
-rw-r--r--tests/mir-opt/separate_const_switch.identity.JumpThreading.diff28
-rw-r--r--tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff34
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff8
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff8
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff7
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff7
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.rs30
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff6
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff6
15 files changed, 155 insertions, 165 deletions
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs
index b81e9fa1aab..33412297017 100644
--- a/compiler/rustc_middle/src/mir/patch.rs
+++ b/compiler/rustc_middle/src/mir/patch.rs
@@ -11,6 +11,8 @@ pub struct MirPatch<'tcx> {
     resume_block: Option<BasicBlock>,
     // Only for unreachable in cleanup path.
     unreachable_cleanup_block: Option<BasicBlock>,
+    // Only for unreachable not in cleanup path.
+    unreachable_no_cleanup_block: Option<BasicBlock>,
     // Cached block for UnwindTerminate (with reason)
     terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
     body_span: Span,
@@ -27,6 +29,7 @@ impl<'tcx> MirPatch<'tcx> {
             next_local: body.local_decls.len(),
             resume_block: None,
             unreachable_cleanup_block: None,
+            unreachable_no_cleanup_block: None,
             terminate_block: None,
             body_span: body.span,
         };
@@ -43,9 +46,12 @@ impl<'tcx> MirPatch<'tcx> {
             // Check if we already have an unreachable block
             if matches!(block.terminator().kind, TerminatorKind::Unreachable)
                 && block.statements.is_empty()
-                && block.is_cleanup
             {
-                result.unreachable_cleanup_block = Some(bb);
+                if block.is_cleanup {
+                    result.unreachable_cleanup_block = Some(bb);
+                } else {
+                    result.unreachable_no_cleanup_block = Some(bb);
+                }
                 continue;
             }
 
@@ -95,6 +101,23 @@ impl<'tcx> MirPatch<'tcx> {
         bb
     }
 
+    pub fn unreachable_no_cleanup_block(&mut self) -> BasicBlock {
+        if let Some(bb) = self.unreachable_no_cleanup_block {
+            return bb;
+        }
+
+        let bb = self.new_block(BasicBlockData {
+            statements: vec![],
+            terminator: Some(Terminator {
+                source_info: SourceInfo::outermost(self.body_span),
+                kind: TerminatorKind::Unreachable,
+            }),
+            is_cleanup: false,
+        });
+        self.unreachable_no_cleanup_block = Some(bb);
+        bb
+    }
+
     pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock {
         if let Some((cached_bb, cached_reason)) = self.terminate_block
             && reason == cached_reason
diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
index 0ab60259732..840a7eda27b 100644
--- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
@@ -2,8 +2,9 @@
 
 use crate::MirPass;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::{
-    BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, Terminator, TerminatorKind,
+    BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, TerminatorKind,
 };
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{Ty, TyCtxt};
@@ -77,8 +78,8 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("UninhabitedEnumBranching starting for {:?}", body.source);
 
-        let mut removable_switchs = Vec::new();
-        let mut otherwise_is_last_variant_switchs = Vec::new();
+        let mut unreachable_targets = Vec::new();
+        let mut patch = MirPatch::new(body);
 
         for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
             trace!("processing block {:?}", bb);
@@ -107,49 +108,41 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
 
             trace!("allowed_variants = {:?}", allowed_variants);
 
-            let terminator = bb_data.terminator();
-            let TerminatorKind::SwitchInt { targets, .. } = &terminator.kind else { bug!() };
+            unreachable_targets.clear();
+            let TerminatorKind::SwitchInt { targets, discr } = &bb_data.terminator().kind else {
+                bug!()
+            };
 
             for (index, (val, _)) in targets.iter().enumerate() {
                 if !allowed_variants.remove(&val) {
-                    removable_switchs.push((bb, index));
+                    unreachable_targets.push(index);
                 }
             }
 
-            if allowed_variants.is_empty() {
-                removable_switchs.push((bb, targets.iter().count()));
-            } else if allowed_variants.len() == 1
-                && !body.basic_blocks[targets.otherwise()].is_empty_unreachable()
-            {
-                #[allow(rustc::potential_query_instability)]
-                let last_variant = *allowed_variants.iter().next().unwrap();
-                otherwise_is_last_variant_switchs.push((bb, last_variant));
-            }
-        }
+            let replace_otherwise_to_unreachable = allowed_variants.len() <= 1
+                && !body.basic_blocks[targets.otherwise()].is_empty_unreachable();
 
-        for (bb, last_variant) in otherwise_is_last_variant_switchs {
-            let bb_data = &mut body.basic_blocks.as_mut()[bb];
-            let terminator = bb_data.terminator_mut();
-            let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind else { bug!() };
-            targets.add_target(last_variant, targets.otherwise());
-            removable_switchs.push((bb, targets.iter().count()));
-        }
+            if unreachable_targets.is_empty() && !replace_otherwise_to_unreachable {
+                continue;
+            }
 
-        if removable_switchs.is_empty() {
-            return;
+            let unreachable_block = patch.unreachable_no_cleanup_block();
+            let mut targets = targets.clone();
+            if replace_otherwise_to_unreachable {
+                let otherwise_is_last_variant = !allowed_variants.is_empty();
+                if otherwise_is_last_variant {
+                    #[allow(rustc::potential_query_instability)]
+                    let last_variant = *allowed_variants.iter().next().unwrap();
+                    targets.add_target(last_variant, targets.otherwise());
+                }
+                unreachable_targets.push(targets.iter().count());
+            }
+            for index in unreachable_targets.iter() {
+                targets.all_targets_mut()[*index] = unreachable_block;
+            }
+            patch.patch_terminator(bb, TerminatorKind::SwitchInt { targets, discr: discr.clone() });
         }
 
-        let new_block = BasicBlockData::new(Some(Terminator {
-            source_info: body.basic_blocks[removable_switchs[0].0].terminator().source_info,
-            kind: TerminatorKind::Unreachable,
-        }));
-        let unreachable_block = body.basic_blocks.as_mut().push(new_block);
-
-        for (bb, index) in removable_switchs {
-            let bb = &mut body.basic_blocks.as_mut()[bb];
-            let terminator = bb.terminator_mut();
-            let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind else { bug!() };
-            targets.all_targets_mut()[index] = unreachable_block;
-        }
+        patch.apply(body);
     }
 }
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
index 5c586fbc2fc..84181462f67 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
@@ -58,16 +58,20 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb1, 1: bb2, otherwise: bb6];
+-         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb1, 1: bb2, otherwise: bb6];
++         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
   
       bb1: {
-          _11 = option::unwrap_failed() -> unwind unreachable;
+          unreachable;
       }
   
       bb2: {
+          _11 = option::unwrap_failed() -> unwind unreachable;
+      }
+  
+      bb3: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -82,21 +86,21 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb3, unwind unreachable];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb3, unwind unreachable];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable];
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_8);
           StorageDead(_7);
           StorageLive(_12);
           StorageLive(_15);
           _12 = discriminant(_6);
-          switchInt(move _12) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
-      bb4: {
+      bb5: {
           _15 = const "called `Result::unwrap()` on an `Err` value";
           StorageLive(_16);
           StorageLive(_17);
@@ -106,7 +110,7 @@
           _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable;
       }
   
-      bb5: {
+      bb6: {
           _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
           StorageDead(_15);
           StorageDead(_12);
@@ -127,10 +131,6 @@
 +         nop;
           return;
       }
-  
-      bb6: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 8, align: 4) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
index bfb2319dac1..820d02e26cd 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
@@ -43,9 +43,9 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb5];
+-         switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb5];
++         switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2];
       }
   
       bb1: {
@@ -68,10 +68,14 @@
       }
   
       bb2: {
-          _11 = option::unwrap_failed() -> unwind continue;
+          unreachable;
       }
   
       bb3: {
+          _11 = option::unwrap_failed() -> unwind continue;
+      }
+  
+      bb4: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -86,20 +90,16 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind continue];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind continue];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue];
       }
   
-      bb4: {
+      bb5: {
           StorageDead(_8);
           StorageDead(_7);
           _5 = Result::<NonNull<[u8]>, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue];
       }
-  
-      bb5: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 8, align: 4) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
index ce55a8265e5..f478f7cb903 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
@@ -58,16 +58,20 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb1, 1: bb2, otherwise: bb6];
+-         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb1, 1: bb2, otherwise: bb6];
++         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
   
       bb1: {
-          _11 = option::unwrap_failed() -> unwind unreachable;
+          unreachable;
       }
   
       bb2: {
+          _11 = option::unwrap_failed() -> unwind unreachable;
+      }
+  
+      bb3: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -82,21 +86,21 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb3, unwind unreachable];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb3, unwind unreachable];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable];
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_8);
           StorageDead(_7);
           StorageLive(_12);
           StorageLive(_15);
           _12 = discriminant(_6);
-          switchInt(move _12) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
-      bb4: {
+      bb5: {
           _15 = const "called `Result::unwrap()` on an `Err` value";
           StorageLive(_16);
           StorageLive(_17);
@@ -106,7 +110,7 @@
           _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable;
       }
   
-      bb5: {
+      bb6: {
           _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
           StorageDead(_15);
           StorageDead(_12);
@@ -127,10 +131,6 @@
 +         nop;
           return;
       }
-  
-      bb6: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 16, align: 8) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
index ddf4223bb49..1fba8b5059a 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
@@ -43,9 +43,9 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb5];
+-         switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb5];
++         switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2];
       }
   
       bb1: {
@@ -68,10 +68,14 @@
       }
   
       bb2: {
-          _11 = option::unwrap_failed() -> unwind continue;
+          unreachable;
       }
   
       bb3: {
+          _11 = option::unwrap_failed() -> unwind continue;
+      }
+  
+      bb4: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -86,20 +90,16 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind continue];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind continue];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue];
       }
   
-      bb4: {
+      bb5: {
           StorageDead(_8);
           StorageDead(_7);
           _5 = Result::<NonNull<[u8]>, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue];
       }
-  
-      bb5: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 16, align: 8) {
diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
index ab3d91ab918..d0abebff214 100644
--- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
+++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
@@ -52,17 +52,21 @@
           StorageLive(_9);
           StorageLive(_10);
           _8 = discriminant(_1);
-          switchInt(move _8) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
       bb1: {
+          unreachable;
+      }
+  
+      bb2: {
           _7 = ((_2 as Continue).0: i32);
           _0 = Result::<i32, i32>::Ok(_7);
           StorageDead(_2);
           return;
       }
   
-      bb2: {
+      bb3: {
           _5 = ((_2 as Break).0: std::result::Result<std::convert::Infallible, i32>);
           StorageLive(_6);
           _6 = _5;
@@ -73,34 +77,30 @@
           return;
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_10);
           StorageDead(_9);
           StorageDead(_8);
           StorageDead(_3);
           _4 = discriminant(_2);
--         switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb6];
-+         goto -> bb1;
+-         switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1];
++         goto -> bb2;
       }
   
-      bb4: {
+      bb5: {
           _10 = ((_1 as Err).0: i32);
           StorageLive(_11);
           _11 = Result::<Infallible, i32>::Err(_10);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _11);
           StorageDead(_11);
--         goto -> bb3;
+-         goto -> bb4;
 +         goto -> bb7;
       }
   
-      bb5: {
+      bb6: {
           _9 = ((_1 as Ok).0: i32);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(_9);
-          goto -> bb3;
-      }
-  
-      bb6: {
-          unreachable;
+          goto -> bb4;
 +     }
 + 
 +     bb7: {
@@ -109,7 +109,7 @@
 +         StorageDead(_8);
 +         StorageDead(_3);
 +         _4 = discriminant(_2);
-+         goto -> bb2;
++         goto -> bb3;
       }
   }
   
diff --git a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff b/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
index 1ac527e9338..f7495862992 100644
--- a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
+++ b/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
@@ -27,54 +27,54 @@
       bb0: {
           StorageLive(_2);
           _3 = discriminant(_1);
-          switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb7];
+          switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1];
       }
   
       bb1: {
+          unreachable;
+      }
+  
+      bb2: {
           _5 = ((_1 as Err).0: usize);
           _2 = ControlFlow::<usize, i32>::Break(_5);
--         goto -> bb3;
+-         goto -> bb4;
 +         goto -> bb8;
       }
   
-      bb2: {
+      bb3: {
           _4 = ((_1 as Ok).0: i32);
           _2 = ControlFlow::<usize, i32>::Continue(_4);
-          goto -> bb3;
+          goto -> bb4;
       }
   
-      bb3: {
+      bb4: {
           _6 = discriminant(_2);
--         switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb7];
-+         goto -> bb5;
+-         switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb1];
++         goto -> bb6;
       }
   
-      bb4: {
+      bb5: {
           StorageLive(_8);
           _8 = ((_2 as Break).0: usize);
           _0 = const Option::<i32>::None;
           StorageDead(_8);
-          goto -> bb6;
+          goto -> bb7;
       }
   
-      bb5: {
+      bb6: {
           _7 = ((_2 as Continue).0: i32);
           _0 = Option::<i32>::Some(_7);
-          goto -> bb6;
+          goto -> bb7;
       }
   
-      bb6: {
+      bb7: {
           StorageDead(_2);
           return;
-      }
-  
-      bb7: {
-          unreachable;
 +     }
 + 
 +     bb8: {
 +         _6 = discriminant(_2);
-+         goto -> bb4;
++         goto -> bb5;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
index 5a3544f8538..1b7517c8d01 100644
--- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
@@ -31,7 +31,7 @@
           _4 = &(_1.1: Test3);
           _5 = discriminant((*_4));
 -         switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb2, otherwise: bb1];
-+         switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb2, otherwise: bb12];
++         switchInt(move _5) -> [0: bb1, 1: bb1, 2: bb5, 3: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -73,7 +73,7 @@
           StorageLive(_9);
           _10 = discriminant((_1.1: Test3));
 -         switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb1];
-+         switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
++         switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb10, 3: bb7, otherwise: bb1];
       }
   
       bb7: {
@@ -110,10 +110,6 @@
           _0 = const ();
           StorageDead(_1);
           return;
-+     }
-+ 
-+     bb12: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
index 5a3544f8538..1b7517c8d01 100644
--- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
@@ -31,7 +31,7 @@
           _4 = &(_1.1: Test3);
           _5 = discriminant((*_4));
 -         switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb2, otherwise: bb1];
-+         switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb2, otherwise: bb12];
++         switchInt(move _5) -> [0: bb1, 1: bb1, 2: bb5, 3: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -73,7 +73,7 @@
           StorageLive(_9);
           _10 = discriminant((_1.1: Test3));
 -         switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb1];
-+         switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
++         switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb10, 3: bb7, otherwise: bb1];
       }
   
       bb7: {
@@ -110,10 +110,6 @@
           _0 = const ();
           StorageDead(_1);
           return;
-+     }
-+ 
-+     bb12: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
index 121374553ed..f9a43480917 100644
--- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
@@ -13,8 +13,7 @@
           StorageLive(_2);
           _2 = Test2::D;
           _3 = discriminant(_2);
--         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb5];
+          switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -39,10 +38,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb5: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
index 121374553ed..f9a43480917 100644
--- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
@@ -13,8 +13,7 @@
           StorageLive(_2);
           _2 = Test2::D;
           _3 = discriminant(_2);
--         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb5];
+          switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -39,10 +38,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb5: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs
index e31bf0227d5..6de001be979 100644
--- a/tests/mir-opt/uninhabited_enum_branching.rs
+++ b/tests/mir-opt/uninhabited_enum_branching.rs
@@ -63,8 +63,8 @@ fn simple() {
 fn custom_discriminant() {
     // CHECK-LABEL: fn custom_discriminant(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: bb5];
-    // CHECK: bb5: {
+    // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test2::D {
         Test2::D => "D",
@@ -76,8 +76,8 @@ fn custom_discriminant() {
 fn otherwise_t1() {
     // CHECK-LABEL: fn otherwise_t1(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5];
-    // CHECK: bb5: {
+    // CHECK: switchInt(move [[discr]]) -> [0: bb5, 1: bb5, 2: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test1::C {
         Test1::A(_) => "A(Empty)",
@@ -90,8 +90,8 @@ fn otherwise_t1() {
 fn otherwise_t2() {
     // CHECK-LABEL: fn otherwise_t2(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [4: bb2, 5: bb1, otherwise: bb4];
-    // CHECK: bb4: {
+    // CHECK: switchInt(move [[discr]]) -> [4: bb2, 5: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test2::D {
         Test2::D => "D",
@@ -120,8 +120,8 @@ fn otherwise_t3() {
 fn otherwise_t4_uninhabited_default() {
     // CHECK-LABEL: fn otherwise_t4_uninhabited_default(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: bb6];
-    // CHECK: bb6: {
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test4::C {
         Test4::A(_) => "A(i32)",
@@ -135,8 +135,8 @@ fn otherwise_t4_uninhabited_default() {
 fn otherwise_t4_uninhabited_default_2() {
     // CHECK-LABEL: fn otherwise_t4_uninhabited_default_2(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: bb8];
-    // CHECK: bb8: {
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test4::C {
         Test4::A(1) => "A(1)",
@@ -151,8 +151,8 @@ fn otherwise_t4_uninhabited_default_2() {
 fn otherwise_t4() {
     // CHECK-LABEL: fn otherwise_t4(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, otherwise: bb1];
-    // CHECK: bb1: {
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NOT: unreachable;
     // CHECK: }
     match Test4::C {
@@ -191,6 +191,9 @@ fn byref() {
         Test3::D => "D",
     };
 
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+
     // CHECK: [[discr:_.*]] = discriminant(
     // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable]], 1: [[unreachable]], 2: bb10, 3: bb7, otherwise: [[unreachable]]];
     match plop.test3 {
@@ -199,9 +202,6 @@ fn byref() {
         Test3::C => "C",
         Test3::D => "D",
     };
-
-    // CHECK: [[unreachable]]: {
-    // CHECK-NEXT: unreachable;
 }
 
 fn main() {
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
index 6ce61e15287..674d3a25504 100644
--- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
@@ -15,7 +15,7 @@
           _2 = Test1::C;
           _3 = discriminant(_2);
 -         switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb2, otherwise: bb6];
++         switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -48,10 +48,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
index 6ce61e15287..674d3a25504 100644
--- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
@@ -15,7 +15,7 @@
           _2 = Test1::C;
           _3 = discriminant(_2);
 -         switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb2, otherwise: bb6];
++         switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -48,10 +48,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
       }
   }