From 5bf50e66f9a7b1de3e074c276afc2e048afe65d1 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 12:12:34 +0200
Subject: [PATCH 1/7] Move a function

---
 .../rustc_mir_build/src/build/matches/mod.rs  | 38 +++++++++----------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 5695c881ecc22..cc46a5603c3d5 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1624,6 +1624,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         otherwise_block
     }
 
+    /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
+    /// subcandidate. Any candidate that has been expanded that way should be passed to
+    /// `finalize_or_candidate` after its subcandidates have been processed.
+    fn create_or_subcandidates<'pat>(
+        &mut self,
+        candidate: &mut Candidate<'pat, 'tcx>,
+        match_pair: MatchPair<'pat, 'tcx>,
+    ) {
+        let TestCase::Or { pats } = match_pair.test_case else { bug!() };
+        debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
+        candidate.or_span = Some(match_pair.pattern.span);
+        candidate.subcandidates = pats
+            .into_vec()
+            .into_iter()
+            .map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
+            .collect();
+        candidate.subcandidates[0].false_edge_start_block = candidate.false_edge_start_block;
+    }
+
     /// Simplify subcandidates and process any leftover match pairs. The candidate should have been
     /// expanded with `create_or_subcandidates`.
     ///
@@ -1724,25 +1743,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
-    /// subcandidate. Any candidate that has been expanded that way should be passed to
-    /// `finalize_or_candidate` after its subcandidates have been processed.
-    fn create_or_subcandidates<'pat>(
-        &mut self,
-        candidate: &mut Candidate<'pat, 'tcx>,
-        match_pair: MatchPair<'pat, 'tcx>,
-    ) {
-        let TestCase::Or { pats } = match_pair.test_case else { bug!() };
-        debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
-        candidate.or_span = Some(match_pair.pattern.span);
-        candidate.subcandidates = pats
-            .into_vec()
-            .into_iter()
-            .map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
-            .collect();
-        candidate.subcandidates[0].false_edge_start_block = candidate.false_edge_start_block;
-    }
-
     /// Try to merge all of the subcandidates of the given candidate into one. This avoids
     /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The candidate should have been
     /// expanded with `create_or_subcandidates`.

From bff4d213fac5ba32b51d320800700124205f6565 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 12:18:31 +0200
Subject: [PATCH 2/7] Factor out the special handling of or-patterns

---
 .../rustc_mir_build/src/build/matches/mod.rs  | 185 ++++++++++--------
 1 file changed, 104 insertions(+), 81 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index cc46a5603c3d5..47f4fd0d07b59 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1427,108 +1427,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Note how we test `x` twice. This is the tradeoff of backtracking automata: we prefer smaller
     /// code size at the expense of non-optimal code paths.
     #[instrument(skip(self), level = "debug")]
-    fn match_candidates<'pat>(
+    fn match_candidates(
         &mut self,
         span: Span,
         scrutinee_span: Span,
         start_block: BasicBlock,
         otherwise_block: BasicBlock,
-        candidates: &mut [&mut Candidate<'pat, 'tcx>],
+        candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) {
-        // We process or-patterns here. If any candidate starts with an or-pattern, we have to
-        // expand the or-pattern before we can proceed further.
-        //
-        // We can't expand them freely however. The rule is: if the candidate has an or-pattern as
-        // its only remaining match pair, we can expand it freely. If it has other match pairs, we
-        // can expand it but we can't process more candidates after it.
-        //
-        // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the following,
-        // or-pattern simplification (in `merge_trivial_subcandidates`) makes it so the `1` and `2`
-        // cases branch to a same block (which then tests `false`). If we took `(2, _)` in the same
-        // set of candidates, when we reach the block that tests `false` we don't know whether we
-        // came from `1` or `2`, hence we can't know where to branch on failure.
-        // ```ignore(illustrative)
-        // match (1, true) {
-        //     (1 | 2, false) => {},
-        //     (2, _) => {},
-        //     _ => {}
-        // }
-        // ```
-        //
-        // We therefore split the `candidates` slice in two, expand or-patterns in the first half,
-        // and process both halves separately.
-        let mut expand_until = 0;
-        for (i, candidate) in candidates.iter().enumerate() {
-            if matches!(
+        // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
+        // can proceed further.
+        let expand_ors = candidates.iter().any(|candidate| {
+            matches!(
                 &*candidate.match_pairs,
                 [MatchPair { test_case: TestCase::Or { .. }, .. }, ..]
-            ) {
-                expand_until = i + 1;
-                if candidate.match_pairs.len() > 1 {
-                    break;
-                }
-            }
-            if expand_until != 0 {
-                expand_until = i + 1;
-            }
-        }
-        let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
-
+            )
+        });
         ensure_sufficient_stack(|| {
-            if candidates_to_expand.is_empty() {
+            if !expand_ors {
                 // No candidates start with an or-pattern, we can continue.
                 self.match_expanded_candidates(
                     span,
                     scrutinee_span,
                     start_block,
                     otherwise_block,
-                    remaining_candidates,
+                    candidates,
                 );
             } else {
-                // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
-                let mut expanded_candidates = Vec::new();
-                for candidate in candidates_to_expand.iter_mut() {
-                    if let [MatchPair { test_case: TestCase::Or { .. }, .. }, ..] =
-                        &*candidate.match_pairs
-                    {
-                        let or_match_pair = candidate.match_pairs.remove(0);
-                        // Expand the or-pattern into subcandidates.
-                        self.create_or_subcandidates(candidate, or_match_pair);
-                        // Collect the newly created subcandidates.
-                        for subcandidate in candidate.subcandidates.iter_mut() {
-                            expanded_candidates.push(subcandidate);
-                        }
-                    } else {
-                        expanded_candidates.push(candidate);
-                    }
-                }
-
-                // Process the expanded candidates.
-                let remainder_start = self.cfg.start_new_block();
-                // There might be new or-patterns obtained from expanding the old ones, so we call
-                // `match_candidates` again.
-                self.match_candidates(
+                self.expand_and_match_or_candidates(
                     span,
                     scrutinee_span,
                     start_block,
-                    remainder_start,
-                    expanded_candidates.as_mut_slice(),
-                );
-
-                // Simplify subcandidates and process any leftover match pairs.
-                for candidate in candidates_to_expand {
-                    if !candidate.subcandidates.is_empty() {
-                        self.finalize_or_candidate(span, scrutinee_span, candidate);
-                    }
-                }
-
-                // Process the remaining candidates.
-                self.match_candidates(
-                    span,
-                    scrutinee_span,
-                    remainder_start,
                     otherwise_block,
-                    remaining_candidates,
+                    candidates,
                 );
             }
         });
@@ -1624,6 +1555,98 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         otherwise_block
     }
 
+    /// Takes a list of candidates such that some of the candidates' first match pairs are
+    /// or-patterns, expands as many or-patterns as possible, and processes the resulting
+    /// candidates.
+    fn expand_and_match_or_candidates(
+        &mut self,
+        span: Span,
+        scrutinee_span: Span,
+        start_block: BasicBlock,
+        otherwise_block: BasicBlock,
+        candidates: &mut [&mut Candidate<'_, 'tcx>],
+    ) {
+        // We can't expand or-patterns freely. The rule is: if the candidate has an
+        // or-pattern as its only remaining match pair, we can expand it freely. If it has
+        // other match pairs, we can expand it but we can't process more candidates after
+        // it.
+        //
+        // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
+        // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
+        // so the `1` and `2` cases branch to a same block (which then tests `false`). If we
+        // took `(2, _)` in the same set of candidates, when we reach the block that tests
+        // `false` we don't know whether we came from `1` or `2`, hence we can't know where
+        // to branch on failure.
+        //
+        // ```ignore(illustrative)
+        // match (1, true) {
+        //     (1 | 2, false) => {},
+        //     (2, _) => {},
+        //     _ => {}
+        // }
+        // ```
+        //
+        // We therefore split the `candidates` slice in two, expand or-patterns in the first half,
+        // and process the rest separately.
+        let mut expand_until = 0;
+        for (i, candidate) in candidates.iter().enumerate() {
+            expand_until = i + 1;
+            if candidate.match_pairs.len() > 1
+                && matches!(&candidate.match_pairs[0].test_case, TestCase::Or { .. })
+            {
+                // The candidate has an or-pattern as well as more match pairs: we must
+                // split the candidates list here.
+                break;
+            }
+        }
+        let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
+
+        // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
+        let mut expanded_candidates = Vec::new();
+        for candidate in candidates_to_expand.iter_mut() {
+            if let [MatchPair { test_case: TestCase::Or { .. }, .. }, ..] = &*candidate.match_pairs
+            {
+                let or_match_pair = candidate.match_pairs.remove(0);
+                // Expand the or-pattern into subcandidates.
+                self.create_or_subcandidates(candidate, or_match_pair);
+                // Collect the newly created subcandidates.
+                for subcandidate in candidate.subcandidates.iter_mut() {
+                    expanded_candidates.push(subcandidate);
+                }
+            } else {
+                expanded_candidates.push(candidate);
+            }
+        }
+
+        // Process the expanded candidates.
+        let remainder_start = self.cfg.start_new_block();
+        // There might be new or-patterns obtained from expanding the old ones, so we call
+        // `match_candidates` again.
+        self.match_candidates(
+            span,
+            scrutinee_span,
+            start_block,
+            remainder_start,
+            expanded_candidates.as_mut_slice(),
+        );
+
+        // Simplify subcandidates and process any leftover match pairs.
+        for candidate in candidates_to_expand {
+            if !candidate.subcandidates.is_empty() {
+                self.finalize_or_candidate(span, scrutinee_span, candidate);
+            }
+        }
+
+        // Process the remaining candidates.
+        self.match_candidates(
+            span,
+            scrutinee_span,
+            remainder_start,
+            otherwise_block,
+            remaining_candidates,
+        );
+    }
+
     /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
     /// subcandidate. Any candidate that has been expanded that way should be passed to
     /// `finalize_or_candidate` after its subcandidates have been processed.

From c5062f73181778af278321827ceedf1682ee0a8b Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 12:25:07 +0200
Subject: [PATCH 3/7] Move or-pattern expansion inside the main part of the
 algorithm

---
 .../rustc_mir_build/src/build/matches/mod.rs  | 60 ++++++++-----------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 47f4fd0d07b59..cc8a0e4b03822 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1119,6 +1119,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
         }
     }
 
+    /// Returns whether the first match pair of this candidate is an or-pattern.
+    fn starts_with_or_pattern(&self) -> bool {
+        matches!(&*self.match_pairs, [MatchPair { test_case: TestCase::Or { .. }, .. }, ..])
+    }
+
     /// Visit the leaf candidates (those with no subcandidates) contained in
     /// this candidate.
     fn visit_leaves<'a>(&'a mut self, mut visit_leaf: impl FnMut(&'a mut Self)) {
@@ -1435,39 +1440,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         otherwise_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) {
-        // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
-        // can proceed further.
-        let expand_ors = candidates.iter().any(|candidate| {
-            matches!(
-                &*candidate.match_pairs,
-                [MatchPair { test_case: TestCase::Or { .. }, .. }, ..]
-            )
-        });
         ensure_sufficient_stack(|| {
-            if !expand_ors {
-                // No candidates start with an or-pattern, we can continue.
-                self.match_expanded_candidates(
-                    span,
-                    scrutinee_span,
-                    start_block,
-                    otherwise_block,
-                    candidates,
-                );
-            } else {
-                self.expand_and_match_or_candidates(
-                    span,
-                    scrutinee_span,
-                    start_block,
-                    otherwise_block,
-                    candidates,
-                );
-            }
+            self.match_candidates_with_enough_stack(
+                span,
+                scrutinee_span,
+                start_block,
+                otherwise_block,
+                candidates,
+            )
         });
     }
 
-    /// Construct the decision tree for `candidates`. Caller must ensure that no candidate in
-    /// `candidates` starts with an or-pattern.
-    fn match_expanded_candidates(
+    /// Construct the decision tree for `candidates`. Don't call this, call `match_candidates`
+    /// instead to reserve sufficient stack space.
+    fn match_candidates_with_enough_stack(
         &mut self,
         span: Span,
         scrutinee_span: Span,
@@ -1492,12 +1478,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // The first candidate has satisfied all its match pairs; we link it up and continue
                 // with the remaining candidates.
                 start_block = self.select_matched_candidate(first, start_block);
-                self.match_expanded_candidates(
+                self.match_candidates(span, scrutinee_span, start_block, otherwise_block, remaining)
+            }
+            candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => {
+                // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
+                // can proceed further.
+                self.expand_and_match_or_candidates(
                     span,
                     scrutinee_span,
                     start_block,
                     otherwise_block,
-                    remaining,
+                    candidates,
                 )
             }
             candidates => {
@@ -1591,9 +1582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let mut expand_until = 0;
         for (i, candidate) in candidates.iter().enumerate() {
             expand_until = i + 1;
-            if candidate.match_pairs.len() > 1
-                && matches!(&candidate.match_pairs[0].test_case, TestCase::Or { .. })
-            {
+            if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
                 // The candidate has an or-pattern as well as more match pairs: we must
                 // split the candidates list here.
                 break;
@@ -1604,8 +1593,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
         let mut expanded_candidates = Vec::new();
         for candidate in candidates_to_expand.iter_mut() {
-            if let [MatchPair { test_case: TestCase::Or { .. }, .. }, ..] = &*candidate.match_pairs
-            {
+            if candidate.starts_with_or_pattern() {
                 let or_match_pair = candidate.match_pairs.remove(0);
                 // Expand the or-pattern into subcandidates.
                 self.create_or_subcandidates(candidate, or_match_pair);

From 8a222ffd6bb37a79bf517b3552008d9695cc8ae1 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 12:29:46 +0200
Subject: [PATCH 4/7] Don't try to save an extra block

This is preparation for the next commit.
---
 .../rustc_mir_build/src/build/matches/mod.rs  |  22 ++--
 .../issue_101867.main.built.after.mir         |  18 ++-
 .../building/issue_49232.main.built.after.mir |  34 ++---
 ...n_conditional.test_complex.built.after.mir | 122 ++++++++++--------
 ...se_edges.full_tested_match.built.after.mir |  50 +++----
 ...e_edges.full_tested_match2.built.after.mir |  54 ++++----
 .../match_false_edges.main.built.after.mir    |  34 ++---
 .../simple_match.match_bool.built.after.mir   |   8 +-
 .../simple_match.match_enum.built.after.mir   |  26 ++--
 ....constant_eq.SimplifyCfg-initial.after.mir |  28 ++--
 ...mment_2.DeduplicateBlocks.panic-abort.diff |  48 ++++---
 ...ment_2.DeduplicateBlocks.panic-unwind.diff |  48 ++++---
 ...fg-initial.after-ElaborateDrops.after.diff |  26 ++--
 ...fg-initial.after-ElaborateDrops.after.diff |  26 ++--
 ...ut_second_or.SimplifyCfg-initial.after.mir |   8 +-
 15 files changed, 284 insertions(+), 268 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index cc8a0e4b03822..458e2c5c40693 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -2021,19 +2021,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         // The block that we should branch to if none of the
         // `target_candidates` match.
-        let remainder_start = if !remaining_candidates.is_empty() {
-            let remainder_start = self.cfg.start_new_block();
-            self.match_candidates(
-                span,
-                scrutinee_span,
-                remainder_start,
-                otherwise_block,
-                remaining_candidates,
-            );
-            remainder_start
-        } else {
-            otherwise_block
-        };
+        let remainder_start = self.cfg.start_new_block();
 
         // For each outcome of test, process the candidates that still apply.
         let target_blocks: FxIndexMap<_, _> = target_candidates
@@ -2061,6 +2049,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             &test,
             target_blocks,
         );
+
+        self.match_candidates(
+            span,
+            scrutinee_span,
+            remainder_start,
+            otherwise_block,
+            remaining_candidates,
+        );
     }
 }
 
diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir
index 5c50b3db5cad6..728b5b23c6a63 100644
--- a/tests/mir-opt/building/issue_101867.main.built.after.mir
+++ b/tests/mir-opt/building/issue_101867.main.built.after.mir
@@ -27,13 +27,13 @@ fn main() -> () {
         StorageLive(_5);
         PlaceMention(_1);
         _6 = discriminant(_1);
-        switchInt(move _6) -> [1: bb4, otherwise: bb3];
+        switchInt(move _6) -> [1: bb5, otherwise: bb4];
     }
 
     bb1: {
         StorageLive(_3);
         StorageLive(_4);
-        _4 = begin_panic::<&str>(const "explicit panic") -> bb8;
+        _4 = begin_panic::<&str>(const "explicit panic") -> bb9;
     }
 
     bb2: {
@@ -43,18 +43,22 @@ fn main() -> () {
     }
 
     bb3: {
-        goto -> bb7;
+        goto -> bb8;
     }
 
     bb4: {
-        falseEdge -> [real: bb6, imaginary: bb3];
+        goto -> bb3;
     }
 
     bb5: {
-        goto -> bb3;
+        falseEdge -> [real: bb7, imaginary: bb3];
     }
 
     bb6: {
+        goto -> bb4;
+    }
+
+    bb7: {
         _5 = ((_1 as Some).0: u8);
         _0 = const ();
         StorageDead(_5);
@@ -62,12 +66,12 @@ fn main() -> () {
         return;
     }
 
-    bb7: {
+    bb8: {
         StorageDead(_5);
         goto -> bb1;
     }
 
-    bb8 (cleanup): {
+    bb9 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir
index d09a1748a8b36..ac7e530520a34 100644
--- a/tests/mir-opt/building/issue_49232.main.built.after.mir
+++ b/tests/mir-opt/building/issue_49232.main.built.after.mir
@@ -17,7 +17,7 @@ fn main() -> () {
     }
 
     bb1: {
-        falseUnwind -> [real: bb2, unwind: bb14];
+        falseUnwind -> [real: bb2, unwind: bb15];
     }
 
     bb2: {
@@ -25,7 +25,7 @@ fn main() -> () {
         StorageLive(_3);
         _3 = const true;
         PlaceMention(_3);
-        switchInt(_3) -> [0: bb4, otherwise: bb6];
+        switchInt(_3) -> [0: bb5, otherwise: bb7];
     }
 
     bb3: {
@@ -34,45 +34,49 @@ fn main() -> () {
     }
 
     bb4: {
-        falseEdge -> [real: bb8, imaginary: bb6];
+        goto -> bb3;
     }
 
     bb5: {
-        goto -> bb3;
+        falseEdge -> [real: bb9, imaginary: bb7];
     }
 
     bb6: {
-        _0 = const ();
-        goto -> bb13;
+        goto -> bb4;
     }
 
     bb7: {
-        goto -> bb3;
+        _0 = const ();
+        goto -> bb14;
     }
 
     bb8: {
-        _2 = const 4_i32;
-        goto -> bb11;
+        goto -> bb4;
     }
 
     bb9: {
-        unreachable;
+        _2 = const 4_i32;
+        goto -> bb12;
     }
 
     bb10: {
-        goto -> bb11;
+        unreachable;
     }
 
     bb11: {
+        goto -> bb12;
+    }
+
+    bb12: {
         FakeRead(ForLet(None), _2);
         StorageDead(_3);
         StorageLive(_5);
         StorageLive(_6);
         _6 = &_2;
-        _5 = std::mem::drop::<&i32>(move _6) -> [return: bb12, unwind: bb14];
+        _5 = std::mem::drop::<&i32>(move _6) -> [return: bb13, unwind: bb15];
     }
 
-    bb12: {
+    bb13: {
         StorageDead(_6);
         StorageDead(_5);
         _1 = const ();
@@ -80,13 +84,13 @@ fn main() -> () {
         goto -> bb1;
     }
 
-    bb13: {
+    bb14: {
         StorageDead(_3);
         StorageDead(_2);
         return;
     }
 
-    bb14 (cleanup): {
+    bb15 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
index 3e16efe6980d9..395b8b82bff41 100644
--- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
+++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
@@ -19,180 +19,188 @@ fn test_complex() -> () {
     bb0: {
         StorageLive(_1);
         StorageLive(_2);
-        _2 = E::f() -> [return: bb1, unwind: bb34];
+        _2 = E::f() -> [return: bb1, unwind: bb36];
     }
 
     bb1: {
         PlaceMention(_2);
         _3 = discriminant(_2);
-        switchInt(move _3) -> [0: bb3, otherwise: bb2];
+        switchInt(move _3) -> [0: bb4, otherwise: bb3];
     }
 
     bb2: {
-        goto -> bb21;
+        goto -> bb22;
     }
 
     bb3: {
-        falseEdge -> [real: bb5, imaginary: bb2];
+        goto -> bb2;
     }
 
     bb4: {
-        goto -> bb2;
+        falseEdge -> [real: bb6, imaginary: bb2];
     }
 
     bb5: {
-        StorageLive(_4);
-        _4 = always_true() -> [return: bb6, unwind: bb34];
+        goto -> bb3;
     }
 
     bb6: {
-        switchInt(move _4) -> [0: bb8, otherwise: bb7];
+        StorageLive(_4);
+        _4 = always_true() -> [return: bb7, unwind: bb36];
     }
 
     bb7: {
+        switchInt(move _4) -> [0: bb9, otherwise: bb8];
+    }
+
+    bb8: {
         StorageLive(_5);
         StorageLive(_6);
         StorageLive(_7);
         _7 = Droppy(const 0_u8);
         _6 = (_7.0: u8);
         _5 = Gt(move _6, const 0_u8);
-        switchInt(move _5) -> [0: bb10, otherwise: bb9];
-    }
-
-    bb8: {
-        goto -> bb14;
+        switchInt(move _5) -> [0: bb11, otherwise: bb10];
     }
 
     bb9: {
-        drop(_7) -> [return: bb11, unwind: bb34];
+        goto -> bb15;
     }
 
     bb10: {
-        goto -> bb12;
+        drop(_7) -> [return: bb12, unwind: bb36];
     }
 
     bb11: {
-        StorageDead(_7);
-        StorageDead(_6);
-        goto -> bb18;
+        goto -> bb13;
     }
 
     bb12: {
-        drop(_7) -> [return: bb13, unwind: bb34];
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb19;
     }
 
     bb13: {
+        drop(_7) -> [return: bb14, unwind: bb36];
+    }
+
+    bb14: {
         StorageDead(_7);
         StorageDead(_6);
-        goto -> bb14;
+        goto -> bb15;
     }
 
-    bb14: {
+    bb15: {
         StorageLive(_8);
         StorageLive(_9);
         StorageLive(_10);
         _10 = Droppy(const 1_u8);
         _9 = (_10.0: u8);
         _8 = Gt(move _9, const 1_u8);
-        switchInt(move _8) -> [0: bb16, otherwise: bb15];
-    }
-
-    bb15: {
-        drop(_10) -> [return: bb17, unwind: bb34];
+        switchInt(move _8) -> [0: bb17, otherwise: bb16];
     }
 
     bb16: {
-        goto -> bb19;
+        drop(_10) -> [return: bb18, unwind: bb36];
     }
 
     bb17: {
-        StorageDead(_10);
-        StorageDead(_9);
-        goto -> bb18;
+        goto -> bb20;
     }
 
     bb18: {
-        _1 = const ();
-        goto -> bb22;
+        StorageDead(_10);
+        StorageDead(_9);
+        goto -> bb19;
     }
 
     bb19: {
-        drop(_10) -> [return: bb20, unwind: bb34];
+        _1 = const ();
+        goto -> bb23;
     }
 
     bb20: {
-        StorageDead(_10);
-        StorageDead(_9);
-        goto -> bb21;
+        drop(_10) -> [return: bb21, unwind: bb36];
     }
 
     bb21: {
-        _1 = const ();
+        StorageDead(_10);
+        StorageDead(_9);
         goto -> bb22;
     }
 
     bb22: {
+        _1 = const ();
+        goto -> bb23;
+    }
+
+    bb23: {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_4);
         StorageDead(_2);
         StorageDead(_1);
         StorageLive(_11);
-        _11 = always_true() -> [return: bb23, unwind: bb34];
-    }
-
-    bb23: {
-        switchInt(move _11) -> [0: bb25, otherwise: bb24];
+        _11 = always_true() -> [return: bb24, unwind: bb36];
     }
 
     bb24: {
-        goto -> bb32;
+        switchInt(move _11) -> [0: bb26, otherwise: bb25];
     }
 
     bb25: {
-        goto -> bb26;
+        goto -> bb34;
     }
 
     bb26: {
-        StorageLive(_12);
-        _12 = E::f() -> [return: bb27, unwind: bb34];
+        goto -> bb27;
     }
 
     bb27: {
-        PlaceMention(_12);
-        _13 = discriminant(_12);
-        switchInt(move _13) -> [1: bb29, otherwise: bb28];
+        StorageLive(_12);
+        _12 = E::f() -> [return: bb28, unwind: bb36];
     }
 
     bb28: {
-        goto -> bb32;
+        PlaceMention(_12);
+        _13 = discriminant(_12);
+        switchInt(move _13) -> [1: bb31, otherwise: bb30];
     }
 
     bb29: {
-        falseEdge -> [real: bb31, imaginary: bb28];
+        goto -> bb34;
     }
 
     bb30: {
-        goto -> bb28;
+        goto -> bb29;
     }
 
     bb31: {
-        _0 = const ();
-        goto -> bb33;
+        falseEdge -> [real: bb33, imaginary: bb29];
     }
 
     bb32: {
-        _0 = const ();
-        goto -> bb33;
+        goto -> bb30;
     }
 
     bb33: {
+        _0 = const ();
+        goto -> bb35;
+    }
+
+    bb34: {
+        _0 = const ();
+        goto -> bb35;
+    }
+
+    bb35: {
         StorageDead(_11);
         StorageDead(_12);
         return;
     }
 
-    bb34 (cleanup): {
+    bb36 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
index bade0fa4b45c8..623dd51c35849 100644
--- a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
@@ -28,7 +28,7 @@ fn full_tested_match() -> () {
         _2 = Option::<i32>::Some(const 42_i32);
         PlaceMention(_2);
         _4 = discriminant(_2);
-        switchInt(move _4) -> [0: bb5, 1: bb2, otherwise: bb1];
+        switchInt(move _4) -> [0: bb6, 1: bb3, otherwise: bb2];
     }
 
     bb1: {
@@ -37,39 +37,43 @@ fn full_tested_match() -> () {
     }
 
     bb2: {
-        falseEdge -> [real: bb7, imaginary: bb3];
+        goto -> bb1;
     }
 
     bb3: {
-        falseEdge -> [real: bb12, imaginary: bb5];
+        falseEdge -> [real: bb8, imaginary: bb4];
     }
 
     bb4: {
-        goto -> bb1;
+        falseEdge -> [real: bb13, imaginary: bb6];
     }
 
     bb5: {
-        _1 = (const 3_i32, const 3_i32);
-        goto -> bb13;
+        goto -> bb2;
     }
 
     bb6: {
-        goto -> bb1;
+        _1 = (const 3_i32, const 3_i32);
+        goto -> bb14;
     }
 
     bb7: {
+        goto -> bb2;
+    }
+
+    bb8: {
         StorageLive(_6);
         _6 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_7);
-        _7 = guard() -> [return: bb8, unwind: bb16];
+        _7 = guard() -> [return: bb9, unwind: bb17];
     }
 
-    bb8: {
-        switchInt(move _7) -> [0: bb10, otherwise: bb9];
+    bb9: {
+        switchInt(move _7) -> [0: bb11, otherwise: bb10];
     }
 
-    bb9: {
+    bb10: {
         StorageDead(_7);
         FakeRead(ForMatchGuard, _3);
         FakeRead(ForGuardBinding, _6);
@@ -81,20 +85,20 @@ fn full_tested_match() -> () {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_6);
-        goto -> bb13;
+        goto -> bb14;
     }
 
-    bb10: {
-        goto -> bb11;
+    bb11: {
+        goto -> bb12;
     }
 
-    bb11: {
+    bb12: {
         StorageDead(_7);
         StorageDead(_6);
-        goto -> bb3;
+        goto -> bb4;
     }
 
-    bb12: {
+    bb13: {
         StorageLive(_9);
         _9 = ((_2 as Some).0: i32);
         StorageLive(_10);
@@ -102,10 +106,10 @@ fn full_tested_match() -> () {
         _1 = (const 2_i32, move _10);
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb13;
+        goto -> bb14;
     }
 
-    bb13: {
+    bb14: {
         PlaceMention(_1);
         StorageDead(_2);
         StorageDead(_1);
@@ -113,16 +117,16 @@ fn full_tested_match() -> () {
         return;
     }
 
-    bb14: {
+    bb15: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb15: {
-        goto -> bb14;
+    bb16: {
+        goto -> bb15;
     }
 
-    bb16 (cleanup): {
+    bb17 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
index 0d78bb8b23587..3cb037bf95601 100644
--- a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
@@ -28,7 +28,7 @@ fn full_tested_match2() -> () {
         _2 = Option::<i32>::Some(const 42_i32);
         PlaceMention(_2);
         _4 = discriminant(_2);
-        switchInt(move _4) -> [0: bb5, 1: bb2, otherwise: bb1];
+        switchInt(move _4) -> [0: bb6, 1: bb3, otherwise: bb2];
     }
 
     bb1: {
@@ -37,10 +37,14 @@ fn full_tested_match2() -> () {
     }
 
     bb2: {
-        falseEdge -> [real: bb7, imaginary: bb5];
+        goto -> bb1;
     }
 
     bb3: {
+        falseEdge -> [real: bb8, imaginary: bb6];
+    }
+
+    bb4: {
         StorageLive(_9);
         _9 = ((_2 as Some).0: i32);
         StorageLive(_10);
@@ -48,34 +52,34 @@ fn full_tested_match2() -> () {
         _1 = (const 2_i32, move _10);
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb13;
-    }
-
-    bb4: {
-        goto -> bb1;
+        goto -> bb14;
     }
 
     bb5: {
-        falseEdge -> [real: bb12, imaginary: bb3];
+        goto -> bb2;
     }
 
     bb6: {
-        goto -> bb1;
+        falseEdge -> [real: bb13, imaginary: bb4];
     }
 
     bb7: {
+        goto -> bb2;
+    }
+
+    bb8: {
         StorageLive(_6);
         _6 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_7);
-        _7 = guard() -> [return: bb8, unwind: bb16];
+        _7 = guard() -> [return: bb9, unwind: bb17];
     }
 
-    bb8: {
-        switchInt(move _7) -> [0: bb10, otherwise: bb9];
+    bb9: {
+        switchInt(move _7) -> [0: bb11, otherwise: bb10];
     }
 
-    bb9: {
+    bb10: {
         StorageDead(_7);
         FakeRead(ForMatchGuard, _3);
         FakeRead(ForGuardBinding, _6);
@@ -87,25 +91,25 @@ fn full_tested_match2() -> () {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_6);
-        goto -> bb13;
+        goto -> bb14;
     }
 
-    bb10: {
-        goto -> bb11;
+    bb11: {
+        goto -> bb12;
     }
 
-    bb11: {
+    bb12: {
         StorageDead(_7);
         StorageDead(_6);
-        falseEdge -> [real: bb3, imaginary: bb5];
+        falseEdge -> [real: bb4, imaginary: bb6];
     }
 
-    bb12: {
+    bb13: {
         _1 = (const 3_i32, const 3_i32);
-        goto -> bb13;
+        goto -> bb14;
     }
 
-    bb13: {
+    bb14: {
         PlaceMention(_1);
         StorageDead(_2);
         StorageDead(_1);
@@ -113,16 +117,16 @@ fn full_tested_match2() -> () {
         return;
     }
 
-    bb14: {
+    bb15: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb15: {
-        goto -> bb14;
+    bb16: {
+        goto -> bb15;
     }
 
-    bb16 (cleanup): {
+    bb17 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
index ebb75ae141a33..134517ad2aec2 100644
--- a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
@@ -38,8 +38,8 @@ fn main() -> () {
         StorageLive(_2);
         _2 = Option::<i32>::Some(const 1_i32);
         PlaceMention(_2);
-        _5 = discriminant(_2);
-        switchInt(move _5) -> [1: bb8, otherwise: bb2];
+        _4 = discriminant(_2);
+        switchInt(move _4) -> [1: bb3, otherwise: bb2];
     }
 
     bb1: {
@@ -48,40 +48,40 @@ fn main() -> () {
     }
 
     bb2: {
-        falseEdge -> [real: bb15, imaginary: bb3];
+        falseEdge -> [real: bb15, imaginary: bb5];
     }
 
     bb3: {
-        _4 = discriminant(_2);
-        switchInt(move _4) -> [1: bb6, otherwise: bb4];
+        falseEdge -> [real: bb10, imaginary: bb2];
     }
 
     bb4: {
-        StorageLive(_14);
-        _14 = _2;
-        _1 = const 4_i32;
-        StorageDead(_14);
-        goto -> bb21;
+        goto -> bb2;
     }
 
     bb5: {
-        goto -> bb1;
+        _5 = discriminant(_2);
+        switchInt(move _5) -> [1: bb7, otherwise: bb6];
     }
 
     bb6: {
-        falseEdge -> [real: bb16, imaginary: bb4];
+        StorageLive(_14);
+        _14 = _2;
+        _1 = const 4_i32;
+        StorageDead(_14);
+        goto -> bb21;
     }
 
     bb7: {
-        goto -> bb4;
+        falseEdge -> [real: bb16, imaginary: bb6];
     }
 
     bb8: {
-        falseEdge -> [real: bb10, imaginary: bb2];
+        goto -> bb6;
     }
 
     bb9: {
-        goto -> bb2;
+        goto -> bb1;
     }
 
     bb10: {
@@ -115,7 +115,7 @@ fn main() -> () {
     bb14: {
         StorageDead(_8);
         StorageDead(_7);
-        falseEdge -> [real: bb9, imaginary: bb2];
+        falseEdge -> [real: bb4, imaginary: bb2];
     }
 
     bb15: {
@@ -161,7 +161,7 @@ fn main() -> () {
         StorageDead(_13);
         StorageDead(_12);
         StorageDead(_11);
-        falseEdge -> [real: bb7, imaginary: bb4];
+        falseEdge -> [real: bb8, imaginary: bb6];
     }
 
     bb21: {
diff --git a/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
index faa2456fd1007..81b5ce304d0e9 100644
--- a/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
+++ b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
@@ -6,7 +6,7 @@ fn match_bool(_1: bool) -> usize {
 
     bb0: {
         PlaceMention(_1);
-        switchInt(_1) -> [0: bb2, otherwise: bb4];
+        switchInt(_1) -> [0: bb2, otherwise: bb3];
     }
 
     bb1: {
@@ -20,15 +20,15 @@ fn match_bool(_1: bool) -> usize {
     }
 
     bb3: {
-        goto -> bb1;
+        falseEdge -> [real: bb6, imaginary: bb2];
     }
 
     bb4: {
-        falseEdge -> [real: bb6, imaginary: bb2];
+        goto -> bb2;
     }
 
     bb5: {
-        goto -> bb2;
+        goto -> bb1;
     }
 
     bb6: {
diff --git a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
index 905aa19da706a..c2ea5bd441c31 100644
--- a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
+++ b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
@@ -8,7 +8,7 @@ fn match_enum(_1: E1) -> bool {
     bb0: {
         PlaceMention(_1);
         _2 = discriminant(_1);
-        switchInt(move _2) -> [0: bb3, 1: bb5, 2: bb7, otherwise: bb2];
+        switchInt(move _2) -> [0: bb4, 1: bb6, 2: bb8, otherwise: bb3];
     }
 
     bb1: {
@@ -21,40 +21,44 @@ fn match_enum(_1: E1) -> bool {
     }
 
     bb3: {
-        goto -> bb9;
+        goto -> bb2;
     }
 
     bb4: {
-        goto -> bb2;
+        goto -> bb10;
     }
 
     bb5: {
-        goto -> bb9;
+        goto -> bb3;
     }
 
     bb6: {
-        goto -> bb2;
+        goto -> bb10;
     }
 
     bb7: {
-        _0 = const false;
-        goto -> bb11;
+        goto -> bb3;
     }
 
     bb8: {
-        goto -> bb2;
+        _0 = const false;
+        goto -> bb12;
     }
 
     bb9: {
-        falseEdge -> [real: bb10, imaginary: bb7];
+        goto -> bb3;
     }
 
     bb10: {
-        _0 = const true;
-        goto -> bb11;
+        falseEdge -> [real: bb11, imaginary: bb8];
     }
 
     bb11: {
+        _0 = const true;
+        goto -> bb12;
+    }
+
+    bb12: {
         return;
     }
 }
diff --git a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
index 060cd6132e3a0..2b5dbacc2d928 100644
--- a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
@@ -23,52 +23,52 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
         StorageDead(_5);
         StorageDead(_4);
         PlaceMention(_3);
-        _9 = <str as PartialEq>::eq((_3.0: &str), const "a") -> [return: bb11, unwind: bb19];
+        _9 = <str as PartialEq>::eq((_3.0: &str), const "a") -> [return: bb9, unwind: bb19];
     }
 
     bb1: {
-        switchInt((_3.1: bool)) -> [0: bb2, otherwise: bb3];
+        switchInt((_3.1: bool)) -> [0: bb10, otherwise: bb11];
     }
 
     bb2: {
-        _0 = const 5_u32;
-        goto -> bb18;
+        falseEdge -> [real: bb12, imaginary: bb5];
     }
 
     bb3: {
-        falseEdge -> [real: bb17, imaginary: bb2];
+        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb4];
     }
 
     bb4: {
-        falseEdge -> [real: bb12, imaginary: bb7];
+        falseEdge -> [real: bb16, imaginary: bb1];
     }
 
     bb5: {
-        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb6];
+        _8 = <str as PartialEq>::eq((_3.0: &str), const "b") -> [return: bb8, unwind: bb19];
     }
 
     bb6: {
-        falseEdge -> [real: bb16, imaginary: bb1];
+        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb7];
     }
 
     bb7: {
-        _8 = <str as PartialEq>::eq((_3.0: &str), const "b") -> [return: bb10, unwind: bb19];
+        falseEdge -> [real: bb15, imaginary: bb3];
     }
 
     bb8: {
-        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb9];
+        switchInt(move _8) -> [0: bb1, otherwise: bb6];
     }
 
     bb9: {
-        falseEdge -> [real: bb15, imaginary: bb5];
+        switchInt(move _9) -> [0: bb5, otherwise: bb2];
     }
 
     bb10: {
-        switchInt(move _8) -> [0: bb1, otherwise: bb8];
+        _0 = const 5_u32;
+        goto -> bb18;
     }
 
     bb11: {
-        switchInt(move _9) -> [0: bb7, otherwise: bb4];
+        falseEdge -> [real: bb17, imaginary: bb10];
     }
 
     bb12: {
@@ -89,7 +89,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
 
     bb14: {
         StorageDead(_10);
-        falseEdge -> [real: bb5, imaginary: bb7];
+        falseEdge -> [real: bb3, imaginary: bb5];
     }
 
     bb15: {
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
index 938b9bb14ade2..3a5762e4f3d1e 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
@@ -22,59 +22,55 @@
   
       bb1: {
           StorageDead(_3);
-          _7 = Len((*_2));
-          _8 = const 4_usize;
-          _9 = Ge(move _7, move _8);
--         switchInt(move _9) -> [0: bb2, otherwise: bb7];
-+         switchInt(move _9) -> [0: bb2, otherwise: bb6];
+          _4 = Len((*_2));
+          _5 = const 4_usize;
+          _6 = Ge(move _4, move _5);
+          switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _4 = Len((*_2));
-          _5 = const 3_usize;
-          _6 = Ge(move _4, move _5);
--         switchInt(move _6) -> [0: bb3, otherwise: bb4];
-+         switchInt(move _6) -> [0: bb10, otherwise: bb3];
+          _7 = Len((*_2));
+          _8 = const 3_usize;
+          _9 = Ge(move _7, move _8);
+-         switchInt(move _9) -> [0: bb7, otherwise: bb8];
++         switchInt(move _9) -> [0: bb10, otherwise: bb7];
       }
   
       bb3: {
--         _0 = const false;
--         goto -> bb14;
-+         switchInt((*_2)[0 of 3]) -> [47: bb4, otherwise: bb10];
+          switchInt((*_2)[0 of 4]) -> [47: bb4, otherwise: bb2];
       }
   
       bb4: {
--         switchInt((*_2)[0 of 3]) -> [47: bb5, otherwise: bb3];
-+         switchInt((*_2)[1 of 3]) -> [47: bb5, otherwise: bb10];
+          switchInt((*_2)[1 of 4]) -> [47: bb5, otherwise: bb2];
       }
   
       bb5: {
--         switchInt((*_2)[1 of 3]) -> [47: bb6, otherwise: bb3];
-+         switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10];
+          switchInt((*_2)[2 of 4]) -> [47: bb6, otherwise: bb2];
       }
   
       bb6: {
--         switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb3];
-+         switchInt((*_2)[0 of 4]) -> [47: bb7, otherwise: bb2];
+-         switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2];
++         switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2];
       }
   
       bb7: {
--         switchInt((*_2)[0 of 4]) -> [47: bb8, otherwise: bb2];
-+         switchInt((*_2)[1 of 4]) -> [47: bb8, otherwise: bb2];
+-         _0 = const false;
+-         goto -> bb14;
++         switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10];
       }
   
       bb8: {
--         switchInt((*_2)[1 of 4]) -> [47: bb9, otherwise: bb2];
-+         switchInt((*_2)[2 of 4]) -> [47: bb9, otherwise: bb2];
+-         switchInt((*_2)[0 of 3]) -> [47: bb9, otherwise: bb7];
++         switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10];
       }
   
       bb9: {
--         switchInt((*_2)[2 of 4]) -> [47: bb10, otherwise: bb2];
-+         switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2];
+-         switchInt((*_2)[1 of 3]) -> [47: bb10, otherwise: bb7];
++         switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10];
       }
   
       bb10: {
--         switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2];
+-         switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb7];
 -     }
 - 
 -     bb11: {
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
index ce89694076b04..21b197d2f270c 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
@@ -22,59 +22,55 @@
   
       bb1: {
           StorageDead(_3);
-          _7 = Len((*_2));
-          _8 = const 4_usize;
-          _9 = Ge(move _7, move _8);
--         switchInt(move _9) -> [0: bb2, otherwise: bb7];
-+         switchInt(move _9) -> [0: bb2, otherwise: bb6];
+          _4 = Len((*_2));
+          _5 = const 4_usize;
+          _6 = Ge(move _4, move _5);
+          switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _4 = Len((*_2));
-          _5 = const 3_usize;
-          _6 = Ge(move _4, move _5);
--         switchInt(move _6) -> [0: bb3, otherwise: bb4];
-+         switchInt(move _6) -> [0: bb10, otherwise: bb3];
+          _7 = Len((*_2));
+          _8 = const 3_usize;
+          _9 = Ge(move _7, move _8);
+-         switchInt(move _9) -> [0: bb7, otherwise: bb8];
++         switchInt(move _9) -> [0: bb10, otherwise: bb7];
       }
   
       bb3: {
--         _0 = const false;
--         goto -> bb14;
-+         switchInt((*_2)[0 of 3]) -> [47: bb4, otherwise: bb10];
+          switchInt((*_2)[0 of 4]) -> [47: bb4, otherwise: bb2];
       }
   
       bb4: {
--         switchInt((*_2)[0 of 3]) -> [47: bb5, otherwise: bb3];
-+         switchInt((*_2)[1 of 3]) -> [47: bb5, otherwise: bb10];
+          switchInt((*_2)[1 of 4]) -> [47: bb5, otherwise: bb2];
       }
   
       bb5: {
--         switchInt((*_2)[1 of 3]) -> [47: bb6, otherwise: bb3];
-+         switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10];
+          switchInt((*_2)[2 of 4]) -> [47: bb6, otherwise: bb2];
       }
   
       bb6: {
--         switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb3];
-+         switchInt((*_2)[0 of 4]) -> [47: bb7, otherwise: bb2];
+-         switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2];
++         switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2];
       }
   
       bb7: {
--         switchInt((*_2)[0 of 4]) -> [47: bb8, otherwise: bb2];
-+         switchInt((*_2)[1 of 4]) -> [47: bb8, otherwise: bb2];
+-         _0 = const false;
+-         goto -> bb14;
++         switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10];
       }
   
       bb8: {
--         switchInt((*_2)[1 of 4]) -> [47: bb9, otherwise: bb2];
-+         switchInt((*_2)[2 of 4]) -> [47: bb9, otherwise: bb2];
+-         switchInt((*_2)[0 of 3]) -> [47: bb9, otherwise: bb7];
++         switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10];
       }
   
       bb9: {
--         switchInt((*_2)[2 of 4]) -> [47: bb10, otherwise: bb2];
-+         switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2];
+-         switchInt((*_2)[1 of 3]) -> [47: bb10, otherwise: bb7];
++         switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10];
       }
   
       bb10: {
--         switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2];
+-         switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb7];
 -     }
 - 
 -     bb11: {
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 209f0d09c2943..4f29e5244d7c2 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -32,25 +32,33 @@
   
       bb0: {
           PlaceMention(_2);
--         switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb1];
+-         switchInt((_2.0: bool)) -> [0: bb2, otherwise: bb1];
 +         switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1];
       }
   
       bb1: {
--         switchInt((_2.1: bool)) -> [0: bb5, otherwise: bb2];
+-         switchInt((_2.1: bool)) -> [0: bb4, otherwise: bb3];
 +         switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2];
       }
   
       bb2: {
--         switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
+-         falseEdge -> [real: bb8, imaginary: bb1];
 +         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
       }
   
       bb3: {
--         falseEdge -> [real: bb20, imaginary: bb4];
+-         switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5];
 -     }
 - 
 -     bb4: {
+-         falseEdge -> [real: bb13, imaginary: bb3];
+-     }
+- 
+-     bb5: {
+-         falseEdge -> [real: bb20, imaginary: bb6];
+-     }
+- 
+-     bb6: {
           StorageLive(_15);
           _15 = (_2.1: bool);
           StorageLive(_16);
@@ -59,14 +67,6 @@
 +         goto -> bb16;
       }
   
--     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb2];
--     }
-- 
--     bb6: {
--         falseEdge -> [real: bb8, imaginary: bb1];
--     }
-- 
 -     bb7: {
 +     bb4: {
           _0 = const 1_i32;
@@ -184,7 +184,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb2];
+-         falseEdge -> [real: bb3, imaginary: bb3];
 +         goto -> bb2;
       }
   
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 209f0d09c2943..4f29e5244d7c2 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -32,25 +32,33 @@
   
       bb0: {
           PlaceMention(_2);
--         switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb1];
+-         switchInt((_2.0: bool)) -> [0: bb2, otherwise: bb1];
 +         switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1];
       }
   
       bb1: {
--         switchInt((_2.1: bool)) -> [0: bb5, otherwise: bb2];
+-         switchInt((_2.1: bool)) -> [0: bb4, otherwise: bb3];
 +         switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2];
       }
   
       bb2: {
--         switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
+-         falseEdge -> [real: bb8, imaginary: bb1];
 +         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
       }
   
       bb3: {
--         falseEdge -> [real: bb20, imaginary: bb4];
+-         switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5];
 -     }
 - 
 -     bb4: {
+-         falseEdge -> [real: bb13, imaginary: bb3];
+-     }
+- 
+-     bb5: {
+-         falseEdge -> [real: bb20, imaginary: bb6];
+-     }
+- 
+-     bb6: {
           StorageLive(_15);
           _15 = (_2.1: bool);
           StorageLive(_16);
@@ -59,14 +67,6 @@
 +         goto -> bb16;
       }
   
--     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb2];
--     }
-- 
--     bb6: {
--         falseEdge -> [real: bb8, imaginary: bb1];
--     }
-- 
 -     bb7: {
 +     bb4: {
           _0 = const 1_i32;
@@ -184,7 +184,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb2];
+-         falseEdge -> [real: bb3, imaginary: bb3];
 +         goto -> bb2;
       }
   
diff --git a/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
index 56edd38a6da4c..775bc8afd7bdb 100644
--- a/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
@@ -18,7 +18,7 @@ fn shortcut_second_or() -> () {
         _1 = (move _2, const 0_i32);
         StorageDead(_2);
         PlaceMention(_1);
-        switchInt(((_1.0: (i32, i32)).0: i32)) -> [0: bb4, otherwise: bb2];
+        switchInt(((_1.0: (i32, i32)).0: i32)) -> [0: bb3, otherwise: bb2];
     }
 
     bb1: {
@@ -27,15 +27,15 @@ fn shortcut_second_or() -> () {
     }
 
     bb2: {
-        switchInt(((_1.0: (i32, i32)).1: i32)) -> [1: bb3, otherwise: bb1];
+        switchInt(((_1.0: (i32, i32)).1: i32)) -> [1: bb4, otherwise: bb1];
     }
 
     bb3: {
-        switchInt((_1.1: i32)) -> [2: bb7, 3: bb8, otherwise: bb1];
+        switchInt((_1.1: i32)) -> [2: bb5, 3: bb6, otherwise: bb1];
     }
 
     bb4: {
-        switchInt((_1.1: i32)) -> [2: bb5, 3: bb6, otherwise: bb1];
+        switchInt((_1.1: i32)) -> [2: bb7, 3: bb8, otherwise: bb1];
     }
 
     bb5: {

From fc40247c6b8d67da1a48d0ee73f42d9a239d2ae0 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 12:56:13 +0200
Subject: [PATCH 5/7] Factor out the "process remaining candidates" cases

---
 .../rustc_mir_build/src/build/matches/mod.rs  | 74 ++++++++-----------
 1 file changed, 30 insertions(+), 44 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 458e2c5c40693..6eb8efc54ec3c 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1457,7 +1457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         &mut self,
         span: Span,
         scrutinee_span: Span,
-        mut start_block: BasicBlock,
+        start_block: BasicBlock,
         otherwise_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) {
@@ -1467,41 +1467,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         }
 
-        match candidates {
+        // Process a prefix of the candidates.
+        let rest = match candidates {
             [] => {
-                // If there are no candidates that still need testing, we're done. Since all matches are
-                // exhaustive, execution should never reach this point.
+                // If there are no candidates that still need testing, we're done.
                 let source_info = self.source_info(span);
                 self.cfg.goto(start_block, source_info, otherwise_block);
+                return;
             }
             [first, remaining @ ..] if first.match_pairs.is_empty() => {
                 // The first candidate has satisfied all its match pairs; we link it up and continue
                 // with the remaining candidates.
-                start_block = self.select_matched_candidate(first, start_block);
-                self.match_candidates(span, scrutinee_span, start_block, otherwise_block, remaining)
+                let remainder_start = self.select_matched_candidate(first, start_block);
+                remainder_start.and(remaining)
             }
             candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => {
                 // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
                 // can proceed further.
-                self.expand_and_match_or_candidates(
-                    span,
-                    scrutinee_span,
-                    start_block,
-                    otherwise_block,
-                    candidates,
-                )
+                self.expand_and_match_or_candidates(span, scrutinee_span, start_block, candidates)
             }
             candidates => {
                 // The first candidate has some unsatisfied match pairs; we proceed to do more tests.
-                self.test_candidates(
-                    span,
-                    scrutinee_span,
-                    candidates,
-                    start_block,
-                    otherwise_block,
-                );
+                self.test_candidates(span, scrutinee_span, candidates, start_block)
             }
-        }
+        };
+
+        // Process any candidates that remain.
+        let BlockAnd(start_block, remaining_candidates) = rest;
+        self.match_candidates(
+            span,
+            scrutinee_span,
+            start_block,
+            otherwise_block,
+            remaining_candidates,
+        );
     }
 
     /// Link up matched candidates.
@@ -1547,16 +1546,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Takes a list of candidates such that some of the candidates' first match pairs are
-    /// or-patterns, expands as many or-patterns as possible, and processes the resulting
-    /// candidates.
-    fn expand_and_match_or_candidates(
+    /// or-patterns. This expands as many or-patterns as possible and processes the resulting
+    /// candidates. Returns the unprocessed candidates if any.
+    fn expand_and_match_or_candidates<'pat, 'b, 'c>(
         &mut self,
         span: Span,
         scrutinee_span: Span,
         start_block: BasicBlock,
-        otherwise_block: BasicBlock,
-        candidates: &mut [&mut Candidate<'_, 'tcx>],
-    ) {
+        candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
+    ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
         // We can't expand or-patterns freely. The rule is: if the candidate has an
         // or-pattern as its only remaining match pair, we can expand it freely. If it has
         // other match pairs, we can expand it but we can't process more candidates after
@@ -1625,14 +1623,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         }
 
-        // Process the remaining candidates.
-        self.match_candidates(
-            span,
-            scrutinee_span,
-            remainder_start,
-            otherwise_block,
-            remaining_candidates,
-        );
+        remainder_start.and(remaining_candidates)
     }
 
     /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
@@ -2003,14 +1994,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// }
     /// # }
     /// ```
+    ///
+    /// We return the unprocessed candidates.
     fn test_candidates<'pat, 'b, 'c>(
         &mut self,
         span: Span,
         scrutinee_span: Span,
         candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
         start_block: BasicBlock,
-        otherwise_block: BasicBlock,
-    ) {
+    ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
         // Extract the match-pair from the highest priority candidate and build a test from it.
         let (match_place, test) = self.pick_test(candidates);
 
@@ -2050,13 +2042,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             target_blocks,
         );
 
-        self.match_candidates(
-            span,
-            scrutinee_span,
-            remainder_start,
-            otherwise_block,
-            remaining_candidates,
-        );
+        remainder_start.and(remaining_candidates)
     }
 }
 

From 3e030b38ef1593592d6f4eb4144630d9abeb43b4 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 30 Jun 2024 13:21:12 +0200
Subject: [PATCH 6/7] Return the `otherwise_block` instead of passing it as
 argument

This saves a few blocks and matches the common `unpack!` paradigm.
---
 .../rustc_mir_build/src/build/matches/mod.rs  |  86 +++++-------
 .../issue_101867.main.built.after.mir         |  18 +--
 .../building/issue_49232.main.built.after.mir |  34 +++--
 ...n_conditional.test_complex.built.after.mir | 122 ++++++++----------
 ...se_edges.full_tested_match.built.after.mir |  50 +++----
 ...e_edges.full_tested_match2.built.after.mir |  54 ++++----
 .../match_false_edges.main.built.after.mir    |  84 ++++++------
 .../simple_match.match_bool.built.after.mir   |  22 ++--
 .../simple_match.match_enum.built.after.mir   |  28 ++--
 ...e_out.move_out_by_subslice.built.after.mir |  34 +++--
 ...move_out.move_out_from_end.built.after.mir |  34 +++--
 tests/mir-opt/issue_72181.bar.built.after.mir |   4 -
 .../mir-opt/issue_72181.main.built.after.mir  |  16 +--
 tests/mir-opt/issue_72181_1.f.built.after.mir |   6 +-
 tests/mir-opt/issue_91633.bar.built.after.mir |  14 +-
 tests/mir-opt/issue_91633.hey.built.after.mir |   8 +-
 .../issue_99325.main.built.after.32bit.mir    |  82 ++++++------
 .../issue_99325.main.built.after.64bit.mir    |  82 ++++++------
 ...ut_second_or.SimplifyCfg-initial.after.mir |  16 +--
 19 files changed, 333 insertions(+), 461 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 6eb8efc54ec3c..2fc510a222b60 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1313,11 +1313,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         candidates: &mut [&mut Candidate<'pat, 'tcx>],
         refutable: bool,
     ) -> BasicBlock {
+        // This will generate code to test scrutinee_place and branch to the appropriate arm block.
         // See the doc comment on `match_candidates` for why we have an otherwise block.
-        let otherwise_block = self.cfg.start_new_block();
-
-        // This will generate code to test scrutinee_place and branch to the appropriate arm block
-        self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates);
+        let otherwise_block =
+            self.match_candidates(match_start_span, scrutinee_span, block, candidates);
 
         // Link each leaf candidate to the `false_edge_start_block` of the next one.
         let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None;
@@ -1368,27 +1367,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         otherwise_block
     }
 
-    /// The main match algorithm. It begins with a set of candidates
-    /// `candidates` and has the job of generating code to determine
-    /// which of these candidates, if any, is the correct one. The
+    /// The main match algorithm. It begins with a set of candidates `candidates` and has the job of
+    /// generating code that branches to an appropriate block if the scrutinee matches one of these
+    /// candidates. The
     /// candidates are sorted such that the first item in the list
     /// has the highest priority. When a candidate is found to match
     /// the value, we will set and generate a branch to the appropriate
     /// pre-binding block.
     ///
-    /// If we find that *NONE* of the candidates apply, we branch to `otherwise_block`.
+    /// If none of the candidates apply, we continue to the returned `otherwise_block`.
     ///
     /// It might be surprising that the input can be non-exhaustive.
-    /// Indeed, initially, it is not, because all matches are
+    /// Indeed, for matches, initially, it is not, because all matches are
     /// exhaustive in Rust. But during processing we sometimes divide
     /// up the list of candidates and recurse with a non-exhaustive
     /// list. This is how our lowering approach (called "backtracking
     /// automaton" in the literature) works.
     /// See [`Builder::test_candidates`] for more details.
     ///
-    /// If `fake_borrows` is `Some`, then places which need fake borrows
-    /// will be added to it.
-    ///
     /// For an example of how we use `otherwise_block`, consider:
     /// ```
     /// # fn foo((x, y): (bool, bool)) -> u32 {
@@ -1413,7 +1409,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// }
     /// if y {
     ///     if x {
-    ///         // This is actually unreachable because the `(true, true)` case was handled above.
+    ///         // This is actually unreachable because the `(true, true)` case was handled above,
+    ///         // but we don't know that from within the lowering algorithm.
     ///         // continue
     ///     } else {
     ///         return 3
@@ -1430,25 +1427,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// the algorithm. For more details on why we lower like this, see [`Builder::test_candidates`].
     ///
     /// Note how we test `x` twice. This is the tradeoff of backtracking automata: we prefer smaller
-    /// code size at the expense of non-optimal code paths.
+    /// code size so we accept non-optimal code paths.
     #[instrument(skip(self), level = "debug")]
     fn match_candidates(
         &mut self,
         span: Span,
         scrutinee_span: Span,
         start_block: BasicBlock,
-        otherwise_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
-    ) {
+    ) -> BasicBlock {
         ensure_sufficient_stack(|| {
-            self.match_candidates_with_enough_stack(
-                span,
-                scrutinee_span,
-                start_block,
-                otherwise_block,
-                candidates,
-            )
-        });
+            self.match_candidates_with_enough_stack(span, scrutinee_span, start_block, candidates)
+        })
     }
 
     /// Construct the decision tree for `candidates`. Don't call this, call `match_candidates`
@@ -1458,9 +1448,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         span: Span,
         scrutinee_span: Span,
         start_block: BasicBlock,
-        otherwise_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
-    ) {
+    ) -> BasicBlock {
         if let [first, ..] = candidates {
             if first.false_edge_start_block.is_none() {
                 first.false_edge_start_block = Some(start_block);
@@ -1471,9 +1460,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let rest = match candidates {
             [] => {
                 // If there are no candidates that still need testing, we're done.
-                let source_info = self.source_info(span);
-                self.cfg.goto(start_block, source_info, otherwise_block);
-                return;
+                return start_block;
             }
             [first, remaining @ ..] if first.match_pairs.is_empty() => {
                 // The first candidate has satisfied all its match pairs; we link it up and continue
@@ -1494,13 +1481,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         // Process any candidates that remain.
         let BlockAnd(start_block, remaining_candidates) = rest;
-        self.match_candidates(
-            span,
-            scrutinee_span,
-            start_block,
-            otherwise_block,
-            remaining_candidates,
-        );
+        self.match_candidates(span, scrutinee_span, start_block, remaining_candidates)
     }
 
     /// Link up matched candidates.
@@ -1605,14 +1586,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         // Process the expanded candidates.
-        let remainder_start = self.cfg.start_new_block();
-        // There might be new or-patterns obtained from expanding the old ones, so we call
-        // `match_candidates` again.
-        self.match_candidates(
+        let remainder_start = self.match_candidates(
             span,
             scrutinee_span,
             start_block,
-            remainder_start,
             expanded_candidates.as_mut_slice(),
         );
 
@@ -1711,6 +1688,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.merge_trivial_subcandidates(candidate);
 
         if !candidate.match_pairs.is_empty() {
+            let or_span = candidate.or_span.unwrap_or(candidate.extra_data.span);
+            let source_info = self.source_info(or_span);
             // If more match pairs remain, test them after each subcandidate.
             // We could add them to the or-candidates before the call to `test_or_pattern` but this
             // would make it impossible to detect simplifiable or-patterns. That would guarantee
@@ -1724,6 +1703,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 assert!(leaf_candidate.match_pairs.is_empty());
                 leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
                 let or_start = leaf_candidate.pre_binding_block.unwrap();
+                let otherwise =
+                    self.match_candidates(span, scrutinee_span, or_start, &mut [leaf_candidate]);
                 // In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
                 // R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
                 // directly to `last_otherwise`. If there is a guard,
@@ -1734,13 +1715,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 } else {
                     last_otherwise.unwrap()
                 };
-                self.match_candidates(
-                    span,
-                    scrutinee_span,
-                    or_start,
-                    or_otherwise,
-                    &mut [leaf_candidate],
-                );
+                self.cfg.goto(otherwise, source_info, or_otherwise);
             });
         }
     }
@@ -2019,15 +1994,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let target_blocks: FxIndexMap<_, _> = target_candidates
             .into_iter()
             .map(|(branch, mut candidates)| {
-                let candidate_start = self.cfg.start_new_block();
-                self.match_candidates(
-                    span,
-                    scrutinee_span,
-                    candidate_start,
-                    remainder_start,
-                    &mut *candidates,
-                );
-                (branch, candidate_start)
+                let branch_start = self.cfg.start_new_block();
+                let branch_otherwise =
+                    self.match_candidates(span, scrutinee_span, branch_start, &mut *candidates);
+                let source_info = self.source_info(span);
+                self.cfg.goto(branch_otherwise, source_info, remainder_start);
+                (branch, branch_start)
             })
             .collect();
 
diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir
index 728b5b23c6a63..5c50b3db5cad6 100644
--- a/tests/mir-opt/building/issue_101867.main.built.after.mir
+++ b/tests/mir-opt/building/issue_101867.main.built.after.mir
@@ -27,13 +27,13 @@ fn main() -> () {
         StorageLive(_5);
         PlaceMention(_1);
         _6 = discriminant(_1);
-        switchInt(move _6) -> [1: bb5, otherwise: bb4];
+        switchInt(move _6) -> [1: bb4, otherwise: bb3];
     }
 
     bb1: {
         StorageLive(_3);
         StorageLive(_4);
-        _4 = begin_panic::<&str>(const "explicit panic") -> bb9;
+        _4 = begin_panic::<&str>(const "explicit panic") -> bb8;
     }
 
     bb2: {
@@ -43,22 +43,18 @@ fn main() -> () {
     }
 
     bb3: {
-        goto -> bb8;
+        goto -> bb7;
     }
 
     bb4: {
-        goto -> bb3;
+        falseEdge -> [real: bb6, imaginary: bb3];
     }
 
     bb5: {
-        falseEdge -> [real: bb7, imaginary: bb3];
+        goto -> bb3;
     }
 
     bb6: {
-        goto -> bb4;
-    }
-
-    bb7: {
         _5 = ((_1 as Some).0: u8);
         _0 = const ();
         StorageDead(_5);
@@ -66,12 +62,12 @@ fn main() -> () {
         return;
     }
 
-    bb8: {
+    bb7: {
         StorageDead(_5);
         goto -> bb1;
     }
 
-    bb9 (cleanup): {
+    bb8 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir
index ac7e530520a34..d09a1748a8b36 100644
--- a/tests/mir-opt/building/issue_49232.main.built.after.mir
+++ b/tests/mir-opt/building/issue_49232.main.built.after.mir
@@ -17,7 +17,7 @@ fn main() -> () {
     }
 
     bb1: {
-        falseUnwind -> [real: bb2, unwind: bb15];
+        falseUnwind -> [real: bb2, unwind: bb14];
     }
 
     bb2: {
@@ -25,7 +25,7 @@ fn main() -> () {
         StorageLive(_3);
         _3 = const true;
         PlaceMention(_3);
-        switchInt(_3) -> [0: bb5, otherwise: bb7];
+        switchInt(_3) -> [0: bb4, otherwise: bb6];
     }
 
     bb3: {
@@ -34,49 +34,45 @@ fn main() -> () {
     }
 
     bb4: {
-        goto -> bb3;
+        falseEdge -> [real: bb8, imaginary: bb6];
     }
 
     bb5: {
-        falseEdge -> [real: bb9, imaginary: bb7];
+        goto -> bb3;
     }
 
     bb6: {
-        goto -> bb4;
+        _0 = const ();
+        goto -> bb13;
     }
 
     bb7: {
-        _0 = const ();
-        goto -> bb14;
+        goto -> bb3;
     }
 
     bb8: {
-        goto -> bb4;
+        _2 = const 4_i32;
+        goto -> bb11;
     }
 
     bb9: {
-        _2 = const 4_i32;
-        goto -> bb12;
+        unreachable;
     }
 
     bb10: {
-        unreachable;
+        goto -> bb11;
     }
 
     bb11: {
-        goto -> bb12;
-    }
-
-    bb12: {
         FakeRead(ForLet(None), _2);
         StorageDead(_3);
         StorageLive(_5);
         StorageLive(_6);
         _6 = &_2;
-        _5 = std::mem::drop::<&i32>(move _6) -> [return: bb13, unwind: bb15];
+        _5 = std::mem::drop::<&i32>(move _6) -> [return: bb12, unwind: bb14];
     }
 
-    bb13: {
+    bb12: {
         StorageDead(_6);
         StorageDead(_5);
         _1 = const ();
@@ -84,13 +80,13 @@ fn main() -> () {
         goto -> bb1;
     }
 
-    bb14: {
+    bb13: {
         StorageDead(_3);
         StorageDead(_2);
         return;
     }
 
-    bb15 (cleanup): {
+    bb14 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
index 395b8b82bff41..3e16efe6980d9 100644
--- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
+++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
@@ -19,188 +19,180 @@ fn test_complex() -> () {
     bb0: {
         StorageLive(_1);
         StorageLive(_2);
-        _2 = E::f() -> [return: bb1, unwind: bb36];
+        _2 = E::f() -> [return: bb1, unwind: bb34];
     }
 
     bb1: {
         PlaceMention(_2);
         _3 = discriminant(_2);
-        switchInt(move _3) -> [0: bb4, otherwise: bb3];
+        switchInt(move _3) -> [0: bb3, otherwise: bb2];
     }
 
     bb2: {
-        goto -> bb22;
+        goto -> bb21;
     }
 
     bb3: {
-        goto -> bb2;
+        falseEdge -> [real: bb5, imaginary: bb2];
     }
 
     bb4: {
-        falseEdge -> [real: bb6, imaginary: bb2];
+        goto -> bb2;
     }
 
     bb5: {
-        goto -> bb3;
+        StorageLive(_4);
+        _4 = always_true() -> [return: bb6, unwind: bb34];
     }
 
     bb6: {
-        StorageLive(_4);
-        _4 = always_true() -> [return: bb7, unwind: bb36];
+        switchInt(move _4) -> [0: bb8, otherwise: bb7];
     }
 
     bb7: {
-        switchInt(move _4) -> [0: bb9, otherwise: bb8];
-    }
-
-    bb8: {
         StorageLive(_5);
         StorageLive(_6);
         StorageLive(_7);
         _7 = Droppy(const 0_u8);
         _6 = (_7.0: u8);
         _5 = Gt(move _6, const 0_u8);
-        switchInt(move _5) -> [0: bb11, otherwise: bb10];
+        switchInt(move _5) -> [0: bb10, otherwise: bb9];
+    }
+
+    bb8: {
+        goto -> bb14;
     }
 
     bb9: {
-        goto -> bb15;
+        drop(_7) -> [return: bb11, unwind: bb34];
     }
 
     bb10: {
-        drop(_7) -> [return: bb12, unwind: bb36];
+        goto -> bb12;
     }
 
     bb11: {
-        goto -> bb13;
-    }
-
-    bb12: {
         StorageDead(_7);
         StorageDead(_6);
-        goto -> bb19;
+        goto -> bb18;
     }
 
-    bb13: {
-        drop(_7) -> [return: bb14, unwind: bb36];
+    bb12: {
+        drop(_7) -> [return: bb13, unwind: bb34];
     }
 
-    bb14: {
+    bb13: {
         StorageDead(_7);
         StorageDead(_6);
-        goto -> bb15;
+        goto -> bb14;
     }
 
-    bb15: {
+    bb14: {
         StorageLive(_8);
         StorageLive(_9);
         StorageLive(_10);
         _10 = Droppy(const 1_u8);
         _9 = (_10.0: u8);
         _8 = Gt(move _9, const 1_u8);
-        switchInt(move _8) -> [0: bb17, otherwise: bb16];
+        switchInt(move _8) -> [0: bb16, otherwise: bb15];
     }
 
-    bb16: {
-        drop(_10) -> [return: bb18, unwind: bb36];
+    bb15: {
+        drop(_10) -> [return: bb17, unwind: bb34];
     }
 
-    bb17: {
-        goto -> bb20;
+    bb16: {
+        goto -> bb19;
     }
 
-    bb18: {
+    bb17: {
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb19;
+        goto -> bb18;
     }
 
-    bb19: {
+    bb18: {
         _1 = const ();
-        goto -> bb23;
+        goto -> bb22;
     }
 
-    bb20: {
-        drop(_10) -> [return: bb21, unwind: bb36];
+    bb19: {
+        drop(_10) -> [return: bb20, unwind: bb34];
     }
 
-    bb21: {
+    bb20: {
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb22;
+        goto -> bb21;
     }
 
-    bb22: {
+    bb21: {
         _1 = const ();
-        goto -> bb23;
+        goto -> bb22;
     }
 
-    bb23: {
+    bb22: {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_4);
         StorageDead(_2);
         StorageDead(_1);
         StorageLive(_11);
-        _11 = always_true() -> [return: bb24, unwind: bb36];
+        _11 = always_true() -> [return: bb23, unwind: bb34];
+    }
+
+    bb23: {
+        switchInt(move _11) -> [0: bb25, otherwise: bb24];
     }
 
     bb24: {
-        switchInt(move _11) -> [0: bb26, otherwise: bb25];
+        goto -> bb32;
     }
 
     bb25: {
-        goto -> bb34;
+        goto -> bb26;
     }
 
     bb26: {
-        goto -> bb27;
+        StorageLive(_12);
+        _12 = E::f() -> [return: bb27, unwind: bb34];
     }
 
     bb27: {
-        StorageLive(_12);
-        _12 = E::f() -> [return: bb28, unwind: bb36];
+        PlaceMention(_12);
+        _13 = discriminant(_12);
+        switchInt(move _13) -> [1: bb29, otherwise: bb28];
     }
 
     bb28: {
-        PlaceMention(_12);
-        _13 = discriminant(_12);
-        switchInt(move _13) -> [1: bb31, otherwise: bb30];
+        goto -> bb32;
     }
 
     bb29: {
-        goto -> bb34;
+        falseEdge -> [real: bb31, imaginary: bb28];
     }
 
     bb30: {
-        goto -> bb29;
+        goto -> bb28;
     }
 
     bb31: {
-        falseEdge -> [real: bb33, imaginary: bb29];
-    }
-
-    bb32: {
-        goto -> bb30;
-    }
-
-    bb33: {
         _0 = const ();
-        goto -> bb35;
+        goto -> bb33;
     }
 
-    bb34: {
+    bb32: {
         _0 = const ();
-        goto -> bb35;
+        goto -> bb33;
     }
 
-    bb35: {
+    bb33: {
         StorageDead(_11);
         StorageDead(_12);
         return;
     }
 
-    bb36 (cleanup): {
+    bb34 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
index 623dd51c35849..9ebfff18f4830 100644
--- a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
@@ -28,7 +28,7 @@ fn full_tested_match() -> () {
         _2 = Option::<i32>::Some(const 42_i32);
         PlaceMention(_2);
         _4 = discriminant(_2);
-        switchInt(move _4) -> [0: bb6, 1: bb3, otherwise: bb2];
+        switchInt(move _4) -> [0: bb5, 1: bb2, otherwise: bb1];
     }
 
     bb1: {
@@ -37,43 +37,39 @@ fn full_tested_match() -> () {
     }
 
     bb2: {
-        goto -> bb1;
+        falseEdge -> [real: bb7, imaginary: bb3];
     }
 
     bb3: {
-        falseEdge -> [real: bb8, imaginary: bb4];
+        falseEdge -> [real: bb12, imaginary: bb5];
     }
 
     bb4: {
-        falseEdge -> [real: bb13, imaginary: bb6];
+        goto -> bb1;
     }
 
     bb5: {
-        goto -> bb2;
+        _1 = (const 3_i32, const 3_i32);
+        goto -> bb13;
     }
 
     bb6: {
-        _1 = (const 3_i32, const 3_i32);
-        goto -> bb14;
+        goto -> bb1;
     }
 
     bb7: {
-        goto -> bb2;
-    }
-
-    bb8: {
         StorageLive(_6);
         _6 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_7);
-        _7 = guard() -> [return: bb9, unwind: bb17];
+        _7 = guard() -> [return: bb8, unwind: bb15];
     }
 
-    bb9: {
-        switchInt(move _7) -> [0: bb11, otherwise: bb10];
+    bb8: {
+        switchInt(move _7) -> [0: bb10, otherwise: bb9];
     }
 
-    bb10: {
+    bb9: {
         StorageDead(_7);
         FakeRead(ForMatchGuard, _3);
         FakeRead(ForGuardBinding, _6);
@@ -85,20 +81,20 @@ fn full_tested_match() -> () {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_6);
-        goto -> bb14;
+        goto -> bb13;
     }
 
-    bb11: {
-        goto -> bb12;
+    bb10: {
+        goto -> bb11;
     }
 
-    bb12: {
+    bb11: {
         StorageDead(_7);
         StorageDead(_6);
-        goto -> bb4;
+        goto -> bb3;
     }
 
-    bb13: {
+    bb12: {
         StorageLive(_9);
         _9 = ((_2 as Some).0: i32);
         StorageLive(_10);
@@ -106,10 +102,10 @@ fn full_tested_match() -> () {
         _1 = (const 2_i32, move _10);
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb14;
+        goto -> bb13;
     }
 
-    bb14: {
+    bb13: {
         PlaceMention(_1);
         StorageDead(_2);
         StorageDead(_1);
@@ -117,16 +113,12 @@ fn full_tested_match() -> () {
         return;
     }
 
-    bb15: {
+    bb14: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb16: {
-        goto -> bb15;
-    }
-
-    bb17 (cleanup): {
+    bb15 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
index 3cb037bf95601..4d2989ea93ece 100644
--- a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
@@ -28,7 +28,7 @@ fn full_tested_match2() -> () {
         _2 = Option::<i32>::Some(const 42_i32);
         PlaceMention(_2);
         _4 = discriminant(_2);
-        switchInt(move _4) -> [0: bb6, 1: bb3, otherwise: bb2];
+        switchInt(move _4) -> [0: bb5, 1: bb2, otherwise: bb1];
     }
 
     bb1: {
@@ -37,14 +37,10 @@ fn full_tested_match2() -> () {
     }
 
     bb2: {
-        goto -> bb1;
+        falseEdge -> [real: bb7, imaginary: bb5];
     }
 
     bb3: {
-        falseEdge -> [real: bb8, imaginary: bb6];
-    }
-
-    bb4: {
         StorageLive(_9);
         _9 = ((_2 as Some).0: i32);
         StorageLive(_10);
@@ -52,34 +48,34 @@ fn full_tested_match2() -> () {
         _1 = (const 2_i32, move _10);
         StorageDead(_10);
         StorageDead(_9);
-        goto -> bb14;
+        goto -> bb13;
+    }
+
+    bb4: {
+        goto -> bb1;
     }
 
     bb5: {
-        goto -> bb2;
+        falseEdge -> [real: bb12, imaginary: bb3];
     }
 
     bb6: {
-        falseEdge -> [real: bb13, imaginary: bb4];
+        goto -> bb1;
     }
 
     bb7: {
-        goto -> bb2;
-    }
-
-    bb8: {
         StorageLive(_6);
         _6 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_7);
-        _7 = guard() -> [return: bb9, unwind: bb17];
+        _7 = guard() -> [return: bb8, unwind: bb15];
     }
 
-    bb9: {
-        switchInt(move _7) -> [0: bb11, otherwise: bb10];
+    bb8: {
+        switchInt(move _7) -> [0: bb10, otherwise: bb9];
     }
 
-    bb10: {
+    bb9: {
         StorageDead(_7);
         FakeRead(ForMatchGuard, _3);
         FakeRead(ForGuardBinding, _6);
@@ -91,25 +87,25 @@ fn full_tested_match2() -> () {
         StorageDead(_8);
         StorageDead(_5);
         StorageDead(_6);
-        goto -> bb14;
+        goto -> bb13;
     }
 
-    bb11: {
-        goto -> bb12;
+    bb10: {
+        goto -> bb11;
     }
 
-    bb12: {
+    bb11: {
         StorageDead(_7);
         StorageDead(_6);
-        falseEdge -> [real: bb4, imaginary: bb6];
+        falseEdge -> [real: bb3, imaginary: bb5];
     }
 
-    bb13: {
+    bb12: {
         _1 = (const 3_i32, const 3_i32);
-        goto -> bb14;
+        goto -> bb13;
     }
 
-    bb14: {
+    bb13: {
         PlaceMention(_1);
         StorageDead(_2);
         StorageDead(_1);
@@ -117,16 +113,12 @@ fn full_tested_match2() -> () {
         return;
     }
 
-    bb15: {
+    bb14: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb16: {
-        goto -> bb15;
-    }
-
-    bb17 (cleanup): {
+    bb15 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
index 134517ad2aec2..4ed9361070662 100644
--- a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
@@ -39,64 +39,60 @@ fn main() -> () {
         _2 = Option::<i32>::Some(const 1_i32);
         PlaceMention(_2);
         _4 = discriminant(_2);
-        switchInt(move _4) -> [1: bb3, otherwise: bb2];
+        switchInt(move _4) -> [1: bb2, otherwise: bb1];
     }
 
     bb1: {
-        FakeRead(ForMatchedPlace(None), _2);
-        unreachable;
+        falseEdge -> [real: bb14, imaginary: bb4];
     }
 
     bb2: {
-        falseEdge -> [real: bb15, imaginary: bb5];
+        falseEdge -> [real: bb9, imaginary: bb1];
     }
 
     bb3: {
-        falseEdge -> [real: bb10, imaginary: bb2];
+        goto -> bb1;
     }
 
     bb4: {
-        goto -> bb2;
-    }
-
-    bb5: {
         _5 = discriminant(_2);
-        switchInt(move _5) -> [1: bb7, otherwise: bb6];
+        switchInt(move _5) -> [1: bb6, otherwise: bb5];
     }
 
-    bb6: {
+    bb5: {
         StorageLive(_14);
         _14 = _2;
         _1 = const 4_i32;
         StorageDead(_14);
-        goto -> bb21;
+        goto -> bb20;
+    }
+
+    bb6: {
+        falseEdge -> [real: bb15, imaginary: bb5];
     }
 
     bb7: {
-        falseEdge -> [real: bb16, imaginary: bb6];
+        goto -> bb5;
     }
 
     bb8: {
-        goto -> bb6;
+        FakeRead(ForMatchedPlace(None), _2);
+        unreachable;
     }
 
     bb9: {
-        goto -> bb1;
-    }
-
-    bb10: {
         StorageLive(_7);
         _7 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_8);
-        _8 = guard() -> [return: bb11, unwind: bb24];
+        _8 = guard() -> [return: bb10, unwind: bb22];
     }
 
-    bb11: {
-        switchInt(move _8) -> [0: bb13, otherwise: bb12];
+    bb10: {
+        switchInt(move _8) -> [0: bb12, otherwise: bb11];
     }
 
-    bb12: {
+    bb11: {
         StorageDead(_8);
         FakeRead(ForMatchGuard, _3);
         FakeRead(ForGuardBinding, _7);
@@ -105,42 +101,42 @@ fn main() -> () {
         _1 = const 1_i32;
         StorageDead(_6);
         StorageDead(_7);
-        goto -> bb21;
+        goto -> bb20;
     }
 
-    bb13: {
-        goto -> bb14;
+    bb12: {
+        goto -> bb13;
     }
 
-    bb14: {
+    bb13: {
         StorageDead(_8);
         StorageDead(_7);
-        falseEdge -> [real: bb4, imaginary: bb2];
+        falseEdge -> [real: bb3, imaginary: bb1];
     }
 
-    bb15: {
+    bb14: {
         StorageLive(_9);
         _9 = _2;
         _1 = const 2_i32;
         StorageDead(_9);
-        goto -> bb21;
+        goto -> bb20;
     }
 
-    bb16: {
+    bb15: {
         StorageLive(_11);
         _11 = &((_2 as Some).0: i32);
         _3 = &fake shallow _2;
         StorageLive(_12);
         StorageLive(_13);
         _13 = (*_11);
-        _12 = guard2(move _13) -> [return: bb17, unwind: bb24];
+        _12 = guard2(move _13) -> [return: bb16, unwind: bb22];
     }
 
-    bb17: {
-        switchInt(move _12) -> [0: bb19, otherwise: bb18];
+    bb16: {
+        switchInt(move _12) -> [0: bb18, otherwise: bb17];
     }
 
-    bb18: {
+    bb17: {
         StorageDead(_13);
         StorageDead(_12);
         FakeRead(ForMatchGuard, _3);
@@ -150,21 +146,21 @@ fn main() -> () {
         _1 = const 3_i32;
         StorageDead(_10);
         StorageDead(_11);
-        goto -> bb21;
+        goto -> bb20;
     }
 
-    bb19: {
-        goto -> bb20;
+    bb18: {
+        goto -> bb19;
     }
 
-    bb20: {
+    bb19: {
         StorageDead(_13);
         StorageDead(_12);
         StorageDead(_11);
-        falseEdge -> [real: bb8, imaginary: bb6];
+        falseEdge -> [real: bb7, imaginary: bb5];
     }
 
-    bb21: {
+    bb20: {
         PlaceMention(_1);
         StorageDead(_2);
         StorageDead(_1);
@@ -172,16 +168,12 @@ fn main() -> () {
         return;
     }
 
-    bb22: {
+    bb21: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb23: {
-        goto -> bb22;
-    }
-
-    bb24 (cleanup): {
+    bb22 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
index 81b5ce304d0e9..b0ebdc37b067d 100644
--- a/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
+++ b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
@@ -6,37 +6,33 @@ fn match_bool(_1: bool) -> usize {
 
     bb0: {
         PlaceMention(_1);
-        switchInt(_1) -> [0: bb2, otherwise: bb3];
+        switchInt(_1) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        FakeRead(ForMatchedPlace(None), _1);
-        unreachable;
+        _0 = const 20_usize;
+        goto -> bb6;
     }
 
     bb2: {
-        _0 = const 20_usize;
-        goto -> bb7;
+        falseEdge -> [real: bb5, imaginary: bb1];
     }
 
     bb3: {
-        falseEdge -> [real: bb6, imaginary: bb2];
+        goto -> bb1;
     }
 
     bb4: {
-        goto -> bb2;
+        FakeRead(ForMatchedPlace(None), _1);
+        unreachable;
     }
 
     bb5: {
-        goto -> bb1;
-    }
-
-    bb6: {
         _0 = const 10_usize;
-        goto -> bb7;
+        goto -> bb6;
     }
 
-    bb7: {
+    bb6: {
         return;
     }
 }
diff --git a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
index c2ea5bd441c31..5e685f43cd612 100644
--- a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
+++ b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir
@@ -8,7 +8,7 @@ fn match_enum(_1: E1) -> bool {
     bb0: {
         PlaceMention(_1);
         _2 = discriminant(_1);
-        switchInt(move _2) -> [0: bb4, 1: bb6, 2: bb8, otherwise: bb3];
+        switchInt(move _2) -> [0: bb2, 1: bb4, 2: bb6, otherwise: bb1];
     }
 
     bb1: {
@@ -17,48 +17,40 @@ fn match_enum(_1: E1) -> bool {
     }
 
     bb2: {
-        goto -> bb1;
+        goto -> bb8;
     }
 
     bb3: {
-        goto -> bb2;
+        goto -> bb1;
     }
 
     bb4: {
-        goto -> bb10;
+        goto -> bb8;
     }
 
     bb5: {
-        goto -> bb3;
+        goto -> bb1;
     }
 
     bb6: {
+        _0 = const false;
         goto -> bb10;
     }
 
     bb7: {
-        goto -> bb3;
+        goto -> bb1;
     }
 
     bb8: {
-        _0 = const false;
-        goto -> bb12;
+        falseEdge -> [real: bb9, imaginary: bb6];
     }
 
     bb9: {
-        goto -> bb3;
-    }
-
-    bb10: {
-        falseEdge -> [real: bb11, imaginary: bb8];
-    }
-
-    bb11: {
         _0 = const true;
-        goto -> bb12;
+        goto -> bb10;
     }
 
-    bb12: {
+    bb10: {
         return;
     }
 }
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index db758368a1388..6d3b2cf291038 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -26,7 +26,7 @@ fn move_out_by_subslice() -> () {
         StorageLive(_2);
         _3 = SizeOf(i32);
         _4 = AlignOf(i32);
-        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb14];
+        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13];
     }
 
     bb1: {
@@ -34,7 +34,7 @@ fn move_out_by_subslice() -> () {
         _6 = ShallowInitBox(move _5, i32);
         (*_6) = const 1_i32;
         _2 = move _6;
-        drop(_6) -> [return: bb2, unwind: bb13];
+        drop(_6) -> [return: bb2, unwind: bb12];
     }
 
     bb2: {
@@ -42,7 +42,7 @@ fn move_out_by_subslice() -> () {
         StorageLive(_7);
         _8 = SizeOf(i32);
         _9 = AlignOf(i32);
-        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb13];
+        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12];
     }
 
     bb3: {
@@ -50,18 +50,18 @@ fn move_out_by_subslice() -> () {
         _11 = ShallowInitBox(move _10, i32);
         (*_11) = const 2_i32;
         _7 = move _11;
-        drop(_11) -> [return: bb4, unwind: bb12];
+        drop(_11) -> [return: bb4, unwind: bb11];
     }
 
     bb4: {
         StorageDead(_11);
         _1 = [move _2, move _7];
-        drop(_7) -> [return: bb5, unwind: bb13];
+        drop(_7) -> [return: bb5, unwind: bb12];
     }
 
     bb5: {
         StorageDead(_7);
-        drop(_2) -> [return: bb6, unwind: bb14];
+        drop(_2) -> [return: bb6, unwind: bb13];
     }
 
     bb6: {
@@ -71,7 +71,7 @@ fn move_out_by_subslice() -> () {
         StorageLive(_12);
         _12 = move _1[0..2];
         _0 = const ();
-        drop(_12) -> [return: bb9, unwind: bb11];
+        drop(_12) -> [return: bb8, unwind: bb10];
     }
 
     bb7: {
@@ -80,32 +80,28 @@ fn move_out_by_subslice() -> () {
     }
 
     bb8: {
-        goto -> bb7;
-    }
-
-    bb9: {
         StorageDead(_12);
-        drop(_1) -> [return: bb10, unwind: bb14];
+        drop(_1) -> [return: bb9, unwind: bb13];
     }
 
-    bb10: {
+    bb9: {
         StorageDead(_1);
         return;
     }
 
+    bb10 (cleanup): {
+        drop(_1) -> [return: bb13, unwind terminate(cleanup)];
+    }
+
     bb11 (cleanup): {
-        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
+        drop(_7) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
-        drop(_7) -> [return: bb13, unwind terminate(cleanup)];
+        drop(_2) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb13 (cleanup): {
-        drop(_2) -> [return: bb14, unwind terminate(cleanup)];
-    }
-
-    bb14 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index 84cd557715c2a..003b90a912d25 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -26,7 +26,7 @@ fn move_out_from_end() -> () {
         StorageLive(_2);
         _3 = SizeOf(i32);
         _4 = AlignOf(i32);
-        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb14];
+        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13];
     }
 
     bb1: {
@@ -34,7 +34,7 @@ fn move_out_from_end() -> () {
         _6 = ShallowInitBox(move _5, i32);
         (*_6) = const 1_i32;
         _2 = move _6;
-        drop(_6) -> [return: bb2, unwind: bb13];
+        drop(_6) -> [return: bb2, unwind: bb12];
     }
 
     bb2: {
@@ -42,7 +42,7 @@ fn move_out_from_end() -> () {
         StorageLive(_7);
         _8 = SizeOf(i32);
         _9 = AlignOf(i32);
-        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb13];
+        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12];
     }
 
     bb3: {
@@ -50,18 +50,18 @@ fn move_out_from_end() -> () {
         _11 = ShallowInitBox(move _10, i32);
         (*_11) = const 2_i32;
         _7 = move _11;
-        drop(_11) -> [return: bb4, unwind: bb12];
+        drop(_11) -> [return: bb4, unwind: bb11];
     }
 
     bb4: {
         StorageDead(_11);
         _1 = [move _2, move _7];
-        drop(_7) -> [return: bb5, unwind: bb13];
+        drop(_7) -> [return: bb5, unwind: bb12];
     }
 
     bb5: {
         StorageDead(_7);
-        drop(_2) -> [return: bb6, unwind: bb14];
+        drop(_2) -> [return: bb6, unwind: bb13];
     }
 
     bb6: {
@@ -71,7 +71,7 @@ fn move_out_from_end() -> () {
         StorageLive(_12);
         _12 = move _1[1 of 2];
         _0 = const ();
-        drop(_12) -> [return: bb9, unwind: bb11];
+        drop(_12) -> [return: bb8, unwind: bb10];
     }
 
     bb7: {
@@ -80,32 +80,28 @@ fn move_out_from_end() -> () {
     }
 
     bb8: {
-        goto -> bb7;
-    }
-
-    bb9: {
         StorageDead(_12);
-        drop(_1) -> [return: bb10, unwind: bb14];
+        drop(_1) -> [return: bb9, unwind: bb13];
     }
 
-    bb10: {
+    bb9: {
         StorageDead(_1);
         return;
     }
 
+    bb10 (cleanup): {
+        drop(_1) -> [return: bb13, unwind terminate(cleanup)];
+    }
+
     bb11 (cleanup): {
-        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
+        drop(_7) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
-        drop(_7) -> [return: bb13, unwind terminate(cleanup)];
+        drop(_2) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb13 (cleanup): {
-        drop(_2) -> [return: bb14, unwind terminate(cleanup)];
-    }
-
-    bb14 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/issue_72181.bar.built.after.mir b/tests/mir-opt/issue_72181.bar.built.after.mir
index 3ab9152f8bb6b..b6cc7d2219569 100644
--- a/tests/mir-opt/issue_72181.bar.built.after.mir
+++ b/tests/mir-opt/issue_72181.bar.built.after.mir
@@ -19,8 +19,4 @@ fn bar(_1: [(Never, u32); 1]) -> u32 {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
-
-    bb2: {
-        goto -> bb1;
-    }
 }
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index fa101512d729f..89d351d5172ce 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -20,7 +20,7 @@ fn main() -> () {
 
     bb0: {
         StorageLive(_1);
-        _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb7];
+        _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb5];
     }
 
     bb1: {
@@ -40,7 +40,7 @@ fn main() -> () {
         _6 = const 0_usize;
         _7 = Len(_2);
         _8 = Lt(_6, _7);
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb4, unwind: bb7];
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb5];
     }
 
     bb2: {
@@ -49,10 +49,6 @@ fn main() -> () {
     }
 
     bb3: {
-        goto -> bb2;
-    }
-
-    bb4: {
         _5 = (_2[_6].0: u64);
         PlaceMention(_5);
         StorageDead(_6);
@@ -62,16 +58,12 @@ fn main() -> () {
         return;
     }
 
-    bb5: {
+    bb4: {
         FakeRead(ForMatchedPlace(None), _5);
         unreachable;
     }
 
-    bb6: {
-        goto -> bb5;
-    }
-
-    bb7 (cleanup): {
+    bb5 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir
index 674a4013fe773..89da9a8011361 100644
--- a/tests/mir-opt/issue_72181_1.f.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.f.built.after.mir
@@ -6,15 +6,11 @@ fn f(_1: Void) -> ! {
 
     bb0: {
         PlaceMention(_1);
-        goto -> bb1;
-    }
-
-    bb1: {
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
 
-    bb2: {
+    bb1: {
         return;
     }
 }
diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir
index 3dcdcab9dea3d..53829588a1b36 100644
--- a/tests/mir-opt/issue_91633.bar.built.after.mir
+++ b/tests/mir-opt/issue_91633.bar.built.after.mir
@@ -12,7 +12,7 @@ fn bar(_1: Box<[T]>) -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = &(*_1);
-        _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb5];
+        _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb4];
     }
 
     bb1: {
@@ -20,7 +20,7 @@ fn bar(_1: Box<[T]>) -> () {
         PlaceMention((*_2));
         StorageDead(_2);
         _0 = const ();
-        drop(_1) -> [return: bb4, unwind: bb6];
+        drop(_1) -> [return: bb3, unwind: bb5];
     }
 
     bb2: {
@@ -29,18 +29,14 @@ fn bar(_1: Box<[T]>) -> () {
     }
 
     bb3: {
-        goto -> bb2;
-    }
-
-    bb4: {
         return;
     }
 
-    bb5 (cleanup): {
-        drop(_1) -> [return: bb6, unwind terminate(cleanup)];
+    bb4 (cleanup): {
+        drop(_1) -> [return: bb5, unwind terminate(cleanup)];
     }
 
-    bb6 (cleanup): {
+    bb5 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir
index e782f4d1a23fa..a537e509996d7 100644
--- a/tests/mir-opt/issue_91633.hey.built.after.mir
+++ b/tests/mir-opt/issue_91633.hey.built.after.mir
@@ -14,7 +14,7 @@ fn hey(_1: &[T]) -> () {
         StorageLive(_3);
         StorageLive(_4);
         _4 = &(*_1);
-        _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb4];
+        _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb3];
     }
 
     bb1: {
@@ -32,11 +32,7 @@ fn hey(_1: &[T]) -> () {
         unreachable;
     }
 
-    bb3: {
-        goto -> bb2;
-    }
-
-    bb4 (cleanup): {
+    bb3 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
index b7a054b5d5409..72e7f4794f980 100644
--- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
@@ -67,7 +67,7 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         StorageLive(_4);
-        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb25];
+        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23];
     }
 
     bb1: {
@@ -91,7 +91,7 @@ fn main() -> () {
         _11 = &(*_8);
         StorageLive(_12);
         _12 = &(*_9);
-        _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb4, unwind: bb25];
+        _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23];
     }
 
     bb2: {
@@ -100,24 +100,20 @@ fn main() -> () {
     }
 
     bb3: {
-        goto -> bb2;
+        switchInt(move _10) -> [0: bb5, otherwise: bb4];
     }
 
     bb4: {
-        switchInt(move _10) -> [0: bb6, otherwise: bb5];
-    }
-
-    bb5: {
         StorageDead(_12);
         StorageDead(_11);
-        goto -> bb10;
+        goto -> bb9;
     }
 
-    bb6: {
-        goto -> bb7;
+    bb5: {
+        goto -> bb6;
     }
 
-    bb7: {
+    bb6: {
         StorageDead(_12);
         StorageDead(_11);
         StorageLive(_14);
@@ -136,10 +132,10 @@ fn main() -> () {
         _19 = &(*_20);
         StorageLive(_21);
         _21 = Option::<Arguments<'_>>::None;
-        _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb25;
+        _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23;
     }
 
-    bb8: {
+    bb7: {
         StorageDead(_21);
         StorageDead(_19);
         StorageDead(_17);
@@ -151,23 +147,23 @@ fn main() -> () {
         unreachable;
     }
 
-    bb9: {
-        goto -> bb11;
+    bb8: {
+        goto -> bb10;
     }
 
-    bb10: {
+    bb9: {
         _1 = const ();
-        goto -> bb11;
+        goto -> bb10;
     }
 
-    bb11: {
+    bb10: {
         StorageDead(_10);
         StorageDead(_9);
         StorageDead(_8);
-        goto -> bb12;
+        goto -> bb11;
     }
 
-    bb12: {
+    bb11: {
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
@@ -177,10 +173,10 @@ fn main() -> () {
         StorageLive(_23);
         StorageLive(_24);
         StorageLive(_25);
-        _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb13, unwind: bb25];
+        _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23];
     }
 
-    bb13: {
+    bb12: {
         _24 = &_25;
         StorageLive(_26);
         StorageLive(_27);
@@ -199,33 +195,29 @@ fn main() -> () {
         _31 = &(*_28);
         StorageLive(_32);
         _32 = &(*_29);
-        _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb16, unwind: bb25];
+        _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23];
     }
 
-    bb14: {
+    bb13: {
         FakeRead(ForMatchedPlace(None), _23);
         unreachable;
     }
 
-    bb15: {
-        goto -> bb14;
-    }
-
-    bb16: {
-        switchInt(move _30) -> [0: bb18, otherwise: bb17];
+    bb14: {
+        switchInt(move _30) -> [0: bb16, otherwise: bb15];
     }
 
-    bb17: {
+    bb15: {
         StorageDead(_32);
         StorageDead(_31);
-        goto -> bb22;
+        goto -> bb20;
     }
 
-    bb18: {
-        goto -> bb19;
+    bb16: {
+        goto -> bb17;
     }
 
-    bb19: {
+    bb17: {
         StorageDead(_32);
         StorageDead(_31);
         StorageLive(_34);
@@ -244,10 +236,10 @@ fn main() -> () {
         _39 = &(*_40);
         StorageLive(_41);
         _41 = Option::<Arguments<'_>>::None;
-        _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb25;
+        _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23;
     }
 
-    bb20: {
+    bb18: {
         StorageDead(_41);
         StorageDead(_39);
         StorageDead(_37);
@@ -259,23 +251,23 @@ fn main() -> () {
         unreachable;
     }
 
-    bb21: {
-        goto -> bb23;
+    bb19: {
+        goto -> bb21;
     }
 
-    bb22: {
+    bb20: {
         _22 = const ();
-        goto -> bb23;
+        goto -> bb21;
     }
 
-    bb23: {
+    bb21: {
         StorageDead(_30);
         StorageDead(_29);
         StorageDead(_28);
-        goto -> bb24;
+        goto -> bb22;
     }
 
-    bb24: {
+    bb22: {
         StorageDead(_27);
         StorageDead(_25);
         StorageDead(_23);
@@ -284,7 +276,7 @@ fn main() -> () {
         return;
     }
 
-    bb25 (cleanup): {
+    bb23 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
index b7a054b5d5409..72e7f4794f980 100644
--- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
@@ -67,7 +67,7 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         StorageLive(_4);
-        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb25];
+        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23];
     }
 
     bb1: {
@@ -91,7 +91,7 @@ fn main() -> () {
         _11 = &(*_8);
         StorageLive(_12);
         _12 = &(*_9);
-        _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb4, unwind: bb25];
+        _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23];
     }
 
     bb2: {
@@ -100,24 +100,20 @@ fn main() -> () {
     }
 
     bb3: {
-        goto -> bb2;
+        switchInt(move _10) -> [0: bb5, otherwise: bb4];
     }
 
     bb4: {
-        switchInt(move _10) -> [0: bb6, otherwise: bb5];
-    }
-
-    bb5: {
         StorageDead(_12);
         StorageDead(_11);
-        goto -> bb10;
+        goto -> bb9;
     }
 
-    bb6: {
-        goto -> bb7;
+    bb5: {
+        goto -> bb6;
     }
 
-    bb7: {
+    bb6: {
         StorageDead(_12);
         StorageDead(_11);
         StorageLive(_14);
@@ -136,10 +132,10 @@ fn main() -> () {
         _19 = &(*_20);
         StorageLive(_21);
         _21 = Option::<Arguments<'_>>::None;
-        _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb25;
+        _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23;
     }
 
-    bb8: {
+    bb7: {
         StorageDead(_21);
         StorageDead(_19);
         StorageDead(_17);
@@ -151,23 +147,23 @@ fn main() -> () {
         unreachable;
     }
 
-    bb9: {
-        goto -> bb11;
+    bb8: {
+        goto -> bb10;
     }
 
-    bb10: {
+    bb9: {
         _1 = const ();
-        goto -> bb11;
+        goto -> bb10;
     }
 
-    bb11: {
+    bb10: {
         StorageDead(_10);
         StorageDead(_9);
         StorageDead(_8);
-        goto -> bb12;
+        goto -> bb11;
     }
 
-    bb12: {
+    bb11: {
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
@@ -177,10 +173,10 @@ fn main() -> () {
         StorageLive(_23);
         StorageLive(_24);
         StorageLive(_25);
-        _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb13, unwind: bb25];
+        _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23];
     }
 
-    bb13: {
+    bb12: {
         _24 = &_25;
         StorageLive(_26);
         StorageLive(_27);
@@ -199,33 +195,29 @@ fn main() -> () {
         _31 = &(*_28);
         StorageLive(_32);
         _32 = &(*_29);
-        _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb16, unwind: bb25];
+        _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23];
     }
 
-    bb14: {
+    bb13: {
         FakeRead(ForMatchedPlace(None), _23);
         unreachable;
     }
 
-    bb15: {
-        goto -> bb14;
-    }
-
-    bb16: {
-        switchInt(move _30) -> [0: bb18, otherwise: bb17];
+    bb14: {
+        switchInt(move _30) -> [0: bb16, otherwise: bb15];
     }
 
-    bb17: {
+    bb15: {
         StorageDead(_32);
         StorageDead(_31);
-        goto -> bb22;
+        goto -> bb20;
     }
 
-    bb18: {
-        goto -> bb19;
+    bb16: {
+        goto -> bb17;
     }
 
-    bb19: {
+    bb17: {
         StorageDead(_32);
         StorageDead(_31);
         StorageLive(_34);
@@ -244,10 +236,10 @@ fn main() -> () {
         _39 = &(*_40);
         StorageLive(_41);
         _41 = Option::<Arguments<'_>>::None;
-        _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb25;
+        _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23;
     }
 
-    bb20: {
+    bb18: {
         StorageDead(_41);
         StorageDead(_39);
         StorageDead(_37);
@@ -259,23 +251,23 @@ fn main() -> () {
         unreachable;
     }
 
-    bb21: {
-        goto -> bb23;
+    bb19: {
+        goto -> bb21;
     }
 
-    bb22: {
+    bb20: {
         _22 = const ();
-        goto -> bb23;
+        goto -> bb21;
     }
 
-    bb23: {
+    bb21: {
         StorageDead(_30);
         StorageDead(_29);
         StorageDead(_28);
-        goto -> bb24;
+        goto -> bb22;
     }
 
-    bb24: {
+    bb22: {
         StorageDead(_27);
         StorageDead(_25);
         StorageDead(_23);
@@ -284,7 +276,7 @@ fn main() -> () {
         return;
     }
 
-    bb25 (cleanup): {
+    bb23 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
index 775bc8afd7bdb..e357e785e33ee 100644
--- a/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir
@@ -18,24 +18,24 @@ fn shortcut_second_or() -> () {
         _1 = (move _2, const 0_i32);
         StorageDead(_2);
         PlaceMention(_1);
-        switchInt(((_1.0: (i32, i32)).0: i32)) -> [0: bb3, otherwise: bb2];
+        switchInt(((_1.0: (i32, i32)).0: i32)) -> [0: bb2, otherwise: bb1];
     }
 
     bb1: {
-        _0 = const ();
-        goto -> bb14;
+        switchInt(((_1.0: (i32, i32)).1: i32)) -> [1: bb4, otherwise: bb3];
     }
 
     bb2: {
-        switchInt(((_1.0: (i32, i32)).1: i32)) -> [1: bb4, otherwise: bb1];
+        switchInt((_1.1: i32)) -> [2: bb5, 3: bb6, otherwise: bb3];
     }
 
     bb3: {
-        switchInt((_1.1: i32)) -> [2: bb5, 3: bb6, otherwise: bb1];
+        _0 = const ();
+        goto -> bb14;
     }
 
     bb4: {
-        switchInt((_1.1: i32)) -> [2: bb7, 3: bb8, otherwise: bb1];
+        switchInt((_1.1: i32)) -> [2: bb7, 3: bb8, otherwise: bb3];
     }
 
     bb5: {
@@ -43,7 +43,7 @@ fn shortcut_second_or() -> () {
     }
 
     bb6: {
-        falseEdge -> [real: bb11, imaginary: bb2];
+        falseEdge -> [real: bb11, imaginary: bb1];
     }
 
     bb7: {
@@ -51,7 +51,7 @@ fn shortcut_second_or() -> () {
     }
 
     bb8: {
-        falseEdge -> [real: bb13, imaginary: bb1];
+        falseEdge -> [real: bb13, imaginary: bb3];
     }
 
     bb9: {

From 42772e98e0d1d3ca0f6660c697e881f5de4b392e Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Fri, 5 Jul 2024 22:23:14 +0200
Subject: [PATCH 7/7] Address review comments

---
 compiler/rustc_mir_build/src/build/matches/mod.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 2fc510a222b60..841ef2719c99d 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1437,17 +1437,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) -> BasicBlock {
         ensure_sufficient_stack(|| {
-            self.match_candidates_with_enough_stack(span, scrutinee_span, start_block, candidates)
+            self.match_candidates_inner(span, scrutinee_span, start_block, candidates)
         })
     }
 
     /// Construct the decision tree for `candidates`. Don't call this, call `match_candidates`
     /// instead to reserve sufficient stack space.
-    fn match_candidates_with_enough_stack(
+    fn match_candidates_inner(
         &mut self,
         span: Span,
         scrutinee_span: Span,
-        start_block: BasicBlock,
+        mut start_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) -> BasicBlock {
         if let [first, ..] = candidates {
@@ -1480,7 +1480,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         // Process any candidates that remain.
-        let BlockAnd(start_block, remaining_candidates) = rest;
+        let remaining_candidates = unpack!(start_block = rest);
         self.match_candidates(span, scrutinee_span, start_block, remaining_candidates)
     }