Merge pull request #19886 from atrick/silgen-critedge

SILGen: simplify cleanups and avoid critical edges.
diff --git a/include/swift/SIL/BasicBlockUtils.h b/include/swift/SIL/BasicBlockUtils.h
index 7f51651..eb8977c 100644
--- a/include/swift/SIL/BasicBlockUtils.h
+++ b/include/swift/SIL/BasicBlockUtils.h
@@ -20,6 +20,11 @@
 class SILFunction;
 class SILBasicBlock;
 
+/// \brief Merge a basic block ending in a branch with its successor
+/// if possible.
+void mergeBasicBlockWithSingleSuccessor(SILBasicBlock *BB,
+                                        SILBasicBlock *succBB);
+
 /// A utility for finding dead-end blocks.
 ///
 /// Dead-end blocks are blocks from which there is no path to the function exit
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 8aaf025..54359a5 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -173,11 +173,20 @@
   /// location.
   ///
   /// Clients should prefer this constructor.
-  SILBuilder(SILInstruction *I, SILBuilderContext &C)
+  SILBuilder(SILInstruction *I, const SILDebugScope *DS, SILBuilderContext &C)
       : TempContext(C.getModule()), C(C), F(I->getFunction()) {
+    assert(DS && "instruction has no debug scope");
+    setCurrentDebugScope(DS);
     setInsertionPoint(I);
   }
 
+  SILBuilder(SILBasicBlock *BB, const SILDebugScope *DS, SILBuilderContext &C)
+      : TempContext(C.getModule()), C(C), F(BB->getParent()) {
+    assert(DS && "block has no debug scope");
+    setCurrentDebugScope(DS);
+    setInsertionPoint(BB);
+  }
+
   // Allow a pass to override the current SIL module conventions. This should
   // only be done by a pass responsible for lowering SIL to a new stage
   // (e.g. AddressLowering).
@@ -2123,10 +2132,8 @@
   ///
   /// Clients should prefer this constructor.
   SILBuilderWithScope(SILInstruction *I, SILBuilderContext &C)
-    : SILBuilder(I, C) {
-    assert(I->getDebugScope() && "instruction has no debug scope");
-    setCurrentDebugScope(I->getDebugScope());
-  }
+    : SILBuilder(I, I->getDebugScope(), C)
+  {}
 
   explicit SILBuilderWithScope(
       SILInstruction *I,
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 57f00bd..2e65b6e 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -614,6 +614,10 @@
   assert(preorderBlocks.empty());
 
   // First clone the CFG region.
+  //
+  // FIXME: Add reverse iteration to SILSuccessor, then convert this to an RPOT
+  // traversal. We would prefer to keep CFG regions in RPO order, and this would
+  // be more scalable for functions with many large switches.
   SmallVector<SILBasicBlock *, 8> dfsWorklist(1, startBB);
   while (!dfsWorklist.empty()) {
     auto *BB = dfsWorklist.pop_back_val();
diff --git a/lib/SIL/BasicBlockUtils.cpp b/lib/SIL/BasicBlockUtils.cpp
index 0801381..100560b 100644
--- a/lib/SIL/BasicBlockUtils.cpp
+++ b/lib/SIL/BasicBlockUtils.cpp
@@ -11,11 +11,31 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/SIL/BasicBlockUtils.h"
-#include "swift/SIL/SILFunction.h"
+#include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILBasicBlock.h"
+#include "swift/SIL/SILFunction.h"
 
 using namespace swift;
 
+/// Merge the basic block with its successor if possible.
+void swift::mergeBasicBlockWithSingleSuccessor(SILBasicBlock *BB,
+                                               SILBasicBlock *succBB) {
+  auto *BI = cast<BranchInst>(BB->getTerminator());
+  assert(succBB->getSinglePredecessorBlock());
+
+  // If there are any BB arguments in the destination, replace them with the
+  // branch operands, since they must dominate the dest block.
+  for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i)
+    succBB->getArgument(i)->replaceAllUsesWith(BI->getArg(i));
+
+  BI->eraseFromParent();
+
+  // Move the instruction from the successor block to the current block.
+  BB->spliceAtEnd(succBB);
+
+  succBB->eraseFromParent();
+}
+
 //===----------------------------------------------------------------------===//
 //                              DeadEndBlocks
 //===----------------------------------------------------------------------===//
diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp
index 477ca21..5e1fdf7 100644
--- a/lib/SILGen/Cleanup.cpp
+++ b/lib/SILGen/Cleanup.cpp
@@ -154,16 +154,13 @@
 }
 
 /// Emit a new block that jumps to the specified location and runs necessary
-/// cleanups based on its level.  If there are no cleanups to run, this just
-/// returns the dest block.
+/// cleanups based on its level. Emit a block even if there are no cleanups;
+/// this is usually the destination of a conditional branch, so jumping
+/// straight to `dest` creates a critical edge.
 SILBasicBlock *CleanupManager::emitBlockForCleanups(JumpDest dest,
                                                     SILLocation branchLoc,
                                                     ArrayRef<SILValue> args,
                                                     ForUnwind_t forUnwind) {
-  // If there are no cleanups to run, just return the Dest block directly.
-  if (!hasAnyActiveCleanups(dest.getDepth()))
-    return dest.getBlock();
-
   // Otherwise, create and emit a new block.
   auto *newBlock = SGF.createBasicBlock();
   SILGenSavedInsertionPoint IPRAII(SGF, newBlock);
diff --git a/lib/SILGen/Condition.cpp b/lib/SILGen/Condition.cpp
index db91a0b..270b50f 100644
--- a/lib/SILGen/Condition.cpp
+++ b/lib/SILGen/Condition.cpp
@@ -19,14 +19,9 @@
 using namespace swift;
 using namespace Lowering;
 
-void Condition::enterTrue(SILGenFunction &SGF) {
-  assert(TrueBB && "Cannot call enterTrue without a True block!");
-  
-  // TrueBB has already been inserted somewhere unless there's a
-  // continuation block.
-  if (!ContBB) return;
-  
-  SGF.B.emitBlock(TrueBB);
+void Condition::enter(SILGenFunction &SGF, SILBasicBlock *destBB) {
+  assert(destBB && "Cannot reenter a finished block.");
+  SGF.B.emitBlock(destBB);
 }
 
 /// Extract the last SILLocation used in BB.
@@ -36,110 +31,24 @@
       return L;
   return Fallback;
 }
-void Condition::exitTrue(SILGenFunction &SGF, ArrayRef<SILValue> Args) {
-  // If there's no continuation block, it's because the condition was
-  // folded to true.  In that case, we just continue emitting code as
-  // if we were still in the true case, and we're unreachable iff the
-  // end of the true case is unreachable.  In other words, there's
-  // nothing to do.
-  if (!ContBB) {
-    assert(!FalseBB && "no continuation");
+void Condition::exit(SILGenFunction &SGF, SILBasicBlock *destBB,
+                     ArrayRef<SILValue> Args) {
+  // If the current point it reachable, branch to the continuation block.
+  if (!SGF.B.hasValidInsertionPoint())
     return;
-  }
   
-  // If there is a continuation block, we should branch to it if the
-  // current point is reachable.
-  if (!SGF.B.hasValidInsertionPoint()) {
-    // If there is no false code, the continuation block has a use
-    // because the main condition jumps directly to it.
-    assert(ContBB->pred_empty() || !FalseBB);
-    return;
-  }
-  
-  // Otherwise, resume into the continuation block.  This branch might
-  // be folded by exitFalse if it turns out that that point is
-  // unreachable.
   SGF.B.createBranch(getContinuationLoc(*SGF.B.getInsertionBB(), Loc),
                      ContBB, Args);
-  
-  // Coming out of exitTrue, we can be in one of three states:
-  //   - a valid non-terminal IP, but only if there is no continuation
-  //     block, which is only possible if there is no false block;
-  //   - a valid terminal IP, if the end of the true block was reachable; or
-  //   - a cleared IP, if the end of the true block was not reachable.
-}
-
-void Condition::enterFalse(SILGenFunction &SGF) {
-  assert(FalseBB && "entering the false branch when it was not valid");
-  
-  // FalseBB has already been inserted somewhere unless there's a
-  // continuation block.
-  if (!ContBB) return;
-  
-  // It's possible to have no insertion point here if the end of the
-  // true case was unreachable.
-  SGF.B.emitBlock(FalseBB);
-}
-
-void Condition::exitFalse(SILGenFunction &SGF, ArrayRef<SILValue> Args) {
-  // If there's no continuation block, it's because the condition was
-  // folded to false.  In that case, we just continue emitting code as
-  // if we were still in the false case, and we're unreachable iff the
-  // end of the false case is unreachable.  In other words, there's
-  // nothing to do.
-  if (!ContBB) return;
-  
-  if (ContBB->pred_empty()) {
-    // If the true case didn't need the continuation block, then
-    // we don't either, regardless of whether the current location
-    // is reachable.  Just keep inserting / being unreachable
-    // right where we are.
-  } else if (!SGF.B.hasValidInsertionPoint()) {
-    // If the true case did need the continuation block, but the false
-    // case doesn't, just merge the continuation block back into its
-    // single predecessor and move the IP there.
-    //
-    // Note that doing this tends to strand the false code after
-    // everything else in the function, so maybe it's not a great idea.
-    auto PI = ContBB->pred_begin();
-    SILBasicBlock *ContPred = *PI;
-
-    // Verify there was only a single predecessor to ContBB.
-    ++PI;
-    assert(PI == ContBB->pred_end() && "Only expect one branch to the ContBB");
-    
-    // Insert before the uncond branch and zap it.
-    auto *Br = cast<BranchInst>(ContPred->getTerminator());
-    SGF.B.setInsertionPoint(Br->getParent());
-
-    Br->eraseFromParent();
-    assert(ContBB->pred_empty() &&
-           "Zapping the branch should make ContBB dead");
-  } else {
-    // Otherwise, branch to the continuation block and start inserting there.
-    SGF.B.createBranch(getContinuationLoc(*SGF.B.getInsertionBB(), Loc),
-                       ContBB, Args);
-  }
 }
 
 SILBasicBlock *Condition::complete(SILGenFunction &SGF) {
-  // If there is no continuation block, it's because we
-  // constant-folded the branch.  The case-exit will have left us in a
-  // normal insertion state (i.e. not a post-terminator IP) with
-  // nothing to clean up after.
-  if (!ContBB) {
-    return SGF.B.getInsertionBB();
+  assert(!TrueBB && "enterTrue is always called.");
+  if (FalseBB) {
+    assert(ContBB->getNumArguments() == 0 &&
+           "block arguments require a non-empty false path.");
+    SILGenBuilder(SGF.B, FalseBB).createBranch(Loc, ContBB);
+    FalseBB = nullptr;
   }
-  
-  // Kill the continuation block if it's not being used.  Case-exits
-  // only leave themselves post-terminator if they use the
-  // continuation block, so we're in an acceptable insertion state.
-  if (ContBB->pred_empty() && ContBB->args_empty()) {
-    SGF.eraseBasicBlock(ContBB);
-    return SGF.B.hasValidInsertionPoint() ? SGF.B.getInsertionBB() : nullptr;
-  }
-  
-  // Okay, we need to insert the continuation block.
   SGF.B.emitBlock(ContBB);
   return ContBB;
 }
diff --git a/lib/SILGen/Condition.h b/lib/SILGen/Condition.h
index b171a0c..1b21fb7 100644
--- a/lib/SILGen/Condition.h
+++ b/lib/SILGen/Condition.h
@@ -32,10 +32,12 @@
 
 /// A condition is the result of evaluating a boolean expression as
 /// control flow.
+///
+/// For each Condition instance, `enterTrue` must be called before `complete`.
+/// If `enterFalse` is skipped, then an empty fall-through block is created.
 class LLVM_LIBRARY_VISIBILITY Condition {
-  /// The blocks responsible for executing the true and false conditions.  A
-  /// block is non-null if that branch is possible, but it's only an independent
-  /// block if both branches are possible.
+  /// The blocks responsible for executing the true and false conditions. These
+  /// are initialized non-null and set to null after being emitted.
   SILBasicBlock *TrueBB;
   SILBasicBlock *FalseBB;
   
@@ -50,30 +52,39 @@
             SILBasicBlock *ContBB,
             SILLocation L)
     : TrueBB(TrueBB), FalseBB(FalseBB), ContBB(ContBB), Loc(L)
-  {}
-  
-  bool hasTrue() const { return TrueBB; }
-  bool hasFalse() const { return FalseBB; }
-  
-  /// enterTrue - Begin the emission of the true block.  This should only be
-  /// called if hasTrue() returns true.
-  void enterTrue(SILGenFunction &SGF);
-  
-  /// exitTrue - End the emission of the true block.  This must be called after
-  /// enterTrue but before anything else on this Condition.
-  void exitTrue(SILGenFunction &SGF, ArrayRef<SILValue> Args = {});
-  
-  /// enterFalse - Begin the emission of the false block.  This should only be
-  /// called if hasFalse() returns true.
-  void enterFalse(SILGenFunction &SGF);
-  
-  /// exitFalse - End the emission of the true block.  This must be called after
-  /// enterFalse but before anything else on this Condition.
-  void exitFalse(SILGenFunction &SGF, ArrayRef<SILValue> Args = {});
-  
+  {
+    assert((TrueBB != nullptr && FalseBB != nullptr) &&
+           "Requires non-null block pointers.");
+  }
+
+  /// enterTrue - Begin the emission of the true block.
+  void enterTrue(SILGenFunction &SGF) { enter(SGF, TrueBB); }
+
+  /// exitTrue - End the emission of the true block.
+  void exitTrue(SILGenFunction &SGF, ArrayRef<SILValue> Args = {}) {
+    exit(SGF, TrueBB, Args);
+    TrueBB = nullptr;
+  }
+
+  /// enterFalse - Begin the emission of the false block.
+  void enterFalse(SILGenFunction &SGF) { enter(SGF, FalseBB); }
+
+  /// exitFalse - End the emission of the true block.
+  void exitFalse(SILGenFunction &SGF, ArrayRef<SILValue> Args = {}) {
+    exit(SGF, FalseBB, Args);
+    FalseBB = nullptr;
+  }
+
   /// complete - Complete this conditional execution.  This should be called
   /// only after all other calls on this Condition have been made.
+  /// This leaves SGF's SILGenBuilder at the continuation block.
   SILBasicBlock *complete(SILGenFunction &SGF);
+
+protected:
+  void enter(SILGenFunction &SGF, SILBasicBlock *destBB);
+
+  void exit(SILGenFunction &SGF, SILBasicBlock *destBB,
+            ArrayRef<SILValue> Args = {});
 };
 
 /// A conditional value is one that depends on conditional execution.
diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h
index f6cb98c..a3920ae 100644
--- a/lib/SILGen/SILGenBuilder.h
+++ b/lib/SILGen/SILGenBuilder.h
@@ -63,6 +63,14 @@
                 SILBasicBlock::iterator insertInst)
       : SILGenBuilder(SGF, &*insertBB, insertInst) {}
 
+  // Create a new builder, inheriting the given builder's context and debug
+  // scope.
+  SILGenBuilder(SILGenBuilder &builder, SILBasicBlock *insertBB)
+    : SILBuilder(insertBB, builder.getCurrentDebugScope(),
+                 builder.getBuilderContext()),
+      SGF(builder.SGF)
+  {}
+
   SILGenModule &getSILGenModule() const;
   SILGenFunction &getSILGenFunction() const { return SGF; }
 
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 1d77860..2979c04 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -1264,7 +1264,7 @@
 /// specified JumpDest.  The insertion point is left in the block where the
 /// condition has matched and any bound variables are in scope.
 ///
-void SILGenFunction::emitStmtCondition(StmtCondition Cond, JumpDest FailDest,
+void SILGenFunction::emitStmtCondition(StmtCondition Cond, JumpDest FalseDest,
                                        SILLocation loc,
                                        ProfileCounter NumTrueTaken,
                                        ProfileCounter NumFalseTaken) {
@@ -1279,7 +1279,7 @@
     switch (elt.getKind()) {
     case StmtConditionElement::CK_PatternBinding: {
       InitializationPtr initialization =
-      InitializationForPattern(*this, FailDest).visit(elt.getPattern());
+      InitializationForPattern(*this, FalseDest).visit(elt.getPattern());
 
       // Emit the initial value into the initialization.
       FullExpr Scope(Cleanups, CleanupLocation(elt.getInitializer()));
@@ -1320,8 +1320,8 @@
     
     // Just branch on the condition.  On failure, we unwind any active cleanups,
     // on success we fall through to a new block.
+    auto FailBB = Cleanups.emitBlockForCleanups(FalseDest, loc);
     SILBasicBlock *ContBB = createBasicBlock();
-    auto FailBB = Cleanups.emitBlockForCleanups(FailDest, loc);
     B.createCondBranch(booleanTestLoc, booleanTestValue, ContBB, FailBB,
                        NumTrueTaken, NumFalseTaken);
 
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index f63848c..f53f386 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -3346,9 +3346,11 @@
         C.getBoolDecl()->getStoredProperties().front(), i1Ty);
       
       auto isTrueBB = subSGF.createBasicBlock();
-      
-      subSGF.B.createCondBranch(loc, isEqualI1, isTrueBB, isFalseBB);
-      
+      // Each false condition needs its own block to avoid critical edges.
+      auto falseEdgeBB = subSGF.createBasicBlockAndBranch(loc, isFalseBB);
+
+      subSGF.B.createCondBranch(loc, isEqualI1, isTrueBB, falseEdgeBB);
+
       subSGF.B.emitBlock(isTrueBB);
     }
     
@@ -4436,7 +4438,6 @@
     
     // FIXME: We could avoid imploding and reexploding tuples here.
     Condition cond = SGF.emitCondition(E->getCondExpr(),
-                                       /*hasFalse*/ true,
                                        /*invertCondition*/ false,
                                        SGF.getLoweredType(E->getType()),
                                        NumTrueTaken, NumFalseTaken);
@@ -4473,7 +4474,6 @@
                                                E, lowering.getLoweredType(), C);
     
     Condition cond = SGF.emitCondition(E->getCondExpr(),
-                                       /*hasFalse*/ true,
                                        /*invertCondition*/ false,
                                        /*contArgs*/ {},
                                        NumTrueTaken, NumFalseTaken);
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index b4928ca..b36f2b5 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -401,6 +401,8 @@
   emitStmt(fd->getBody());
 
   emitEpilog(fd);
+
+  mergeCleanupBlocks();
 }
 
 void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index a011c37..3f41ca6 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -679,12 +679,10 @@
   //===--------------------------------------------------------------------===//
   // Control flow
   //===--------------------------------------------------------------------===//
-  
+
   /// emitCondition - Emit a boolean expression as a control-flow condition.
   ///
   /// \param E - The expression to be evaluated as a condition.
-  /// \param hasFalseCode - true if the false branch doesn't just lead
-  ///        to the fallthrough.
   /// \param invertValue - true if this routine should invert the value before
   ///        testing true/false.
   /// \param contArgs - the types of the arguments to the continuation BB.
@@ -693,14 +691,15 @@
   /// \param NumTrueTaken - The number of times the condition evaluates to true.
   /// \param NumFalseTaken - The number of times the condition evaluates to
   /// false.
-  Condition emitCondition(Expr *E, bool hasFalseCode = true,
-                          bool invertValue = false,
+  ///
+  /// If `contArgs` is nonempty, then both Condition::exitTrue() and
+  /// Condition::exitFalse() must be called.
+  Condition emitCondition(Expr *E, bool invertValue = false,
                           ArrayRef<SILType> contArgs = {},
                           ProfileCounter NumTrueTaken = ProfileCounter(),
                           ProfileCounter NumFalseTaken = ProfileCounter());
 
-  Condition emitCondition(SILValue V, SILLocation Loc, bool hasFalseCode = true,
-                          bool invertValue = false,
+  Condition emitCondition(SILValue V, SILLocation Loc, bool invertValue = false,
                           ArrayRef<SILType> contArgs = {},
                           ProfileCounter NumTrueTaken = ProfileCounter(),
                           ProfileCounter NumFalseTaken = ProfileCounter());
@@ -727,6 +726,9 @@
   /// section.
   SILBasicBlock *createBasicBlock(FunctionSection section);
 
+  SILBasicBlock *createBasicBlockAndBranch(SILLocation loc,
+                                           SILBasicBlock *destBB);
+
   /// Erase a basic block that was speculatively created and turned
   /// out to be unneeded.
   ///
@@ -736,6 +738,8 @@
   /// The block should be empty and have no predecessors.
   void eraseBasicBlock(SILBasicBlock *block);
 
+  void mergeCleanupBlocks();
+
   //===--------------------------------------------------------------------===//
   // Memory management
   //===--------------------------------------------------------------------===//
@@ -1041,7 +1045,7 @@
   //===--------------------------------------------------------------------===//
 
   SILValue emitOSVersionRangeCheck(SILLocation loc, const VersionRange &range);
-  void emitStmtCondition(StmtCondition Cond, JumpDest FailDest, SILLocation loc,
+  void emitStmtCondition(StmtCondition Cond, JumpDest FalseDest, SILLocation loc,
                          ProfileCounter NumTrueTaken = ProfileCounter(),
                          ProfileCounter NumFalseTaken = ProfileCounter());
 
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index d2ac885..df9f587 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -20,6 +20,7 @@
 #include "SwitchEnumBuilder.h"
 #include "swift/AST/DiagnosticsSIL.h"
 #include "swift/Basic/ProfileCounter.h"
+#include "swift/SIL/BasicBlockUtils.h"
 #include "swift/SIL/SILArgument.h"
 #include "llvm/Support/SaveAndRestore.h"
 
@@ -79,6 +80,14 @@
   llvm_unreachable("bad function section");
 }
 
+SILBasicBlock *
+SILGenFunction::createBasicBlockAndBranch(SILLocation loc,
+                                          SILBasicBlock *destBB) {
+  auto *newBB = createBasicBlock();
+  SILGenBuilder(B, newBB).createBranch(loc, destBB);
+  return newBB;
+}
+
 void SILGenFunction::eraseBasicBlock(SILBasicBlock *block) {
   assert(block->pred_empty() && "erasing block with predecessors");
   assert(block->empty() && "erasing block with content");
@@ -89,6 +98,76 @@
   block->eraseFromParent();
 }
 
+// Merge blocks during a single traversal of the block list. Only unconditional
+// branch edges are visited. Consequently, this takes only as much time as a
+// linked list traversal and requires no additional storage.
+//
+// For each block, check if it can be merged with its successor. Place the
+// merged block at the successor position in the block list.
+//
+// Typically, the successor occurs later in the list. This is most efficient
+// because merging moves instructions from the successor to the
+// predecessor. This way, instructions will only be moved once. Furthermore, the
+// merged block will be visited again to determine if it can be merged with it's
+// successor, and so on, so no edges are skipped.
+//
+// In rare cases, the predessor is merged with its earlier successor, which has
+// already been visited. If the successor can also be merged, then it has
+// already happened, and there is no need to revisit the merged block.
+void SILGenFunction::mergeCleanupBlocks() {
+  for (auto bbPos = F.begin(), bbEnd = F.end(), nextPos = bbPos; bbPos != bbEnd;
+       bbPos = nextPos) {
+    // A forward iterator refering to the next unprocessed block in the block
+    // list. If blocks are merged and moved, then this will be updated.
+    nextPos = std::next(bbPos);
+
+    // Consider the current block as the predecessor.
+    auto *predBB = &*bbPos;
+    auto *BI = dyn_cast<BranchInst>(predBB->getTerminator());
+    if (!BI)
+      continue;
+
+    // predBB has an unconditional branch to succBB. If succBB has no other
+    // predecessors, then merge the blocks.
+    auto *succBB = BI->getDestBB();
+    if (!succBB->getSinglePredecessorBlock())
+      continue;
+
+    // Before merging, establish iterators that won't be invalidated by erasing
+    // succBB. Use a reverse iterator to remember the position before a block.
+    //
+    // Remember the block before the current successor as a position for placing
+    // the merged block.
+    auto beforeSucc = std::next(SILFunction::reverse_iterator(succBB));
+
+    // Remember the position before the current predecessor to avoid skipping
+    // blocks or revisiting blocks unnecessarilly.
+    auto beforePred = std::next(SILFunction::reverse_iterator(predBB));
+    // Since succBB will be erased, move before it.
+    if (beforePred == SILFunction::reverse_iterator(succBB))
+      ++beforePred;
+
+    // Merge `predBB` with `succBB`. This erases `succBB`.
+    mergeBasicBlockWithSingleSuccessor(predBB, succBB);
+
+    // If predBB is first in the list, then it must be the entry block which
+    // cannot be moved.
+    if (beforePred != F.rend()) {
+      // Move the merged block into the successor position. (If the blocks are
+      // not already adjacent, then the first is typically the trampoline.)
+      assert(beforeSucc != F.rend()
+             && "entry block cannot have a predecessor.");
+      predBB->moveAfter(&*beforeSucc);
+    }
+    // If after moving predBB there are no more blocks to process, then break.
+    if (beforePred == F.rbegin())
+      break;
+
+    // Update the loop iterator to the next unprocessed block.
+    nextPos = SILFunction::iterator(&*std::prev(beforePred));
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // SILGenFunction emitStmt implementation
 //===----------------------------------------------------------------------===//
@@ -146,8 +225,7 @@
     SGF.B.emitBlock(BB, BranchLoc);
 }
 
-Condition SILGenFunction::emitCondition(Expr *E, bool hasFalseCode,
-                                        bool invertValue,
+Condition SILGenFunction::emitCondition(Expr *E, bool invertValue,
                                         ArrayRef<SILType> contArgs,
                                         ProfileCounter NumTrueTaken,
                                         ProfileCounter NumFalseTaken) {
@@ -162,12 +240,12 @@
   }
   assert(V->getType().castTo<BuiltinIntegerType>()->isFixedWidth(1));
 
-  return emitCondition(V, E, hasFalseCode, invertValue, contArgs, NumTrueTaken,
+  return emitCondition(V, E, invertValue, contArgs, NumTrueTaken,
                        NumFalseTaken);
 }
 
 Condition SILGenFunction::emitCondition(SILValue V, SILLocation Loc,
-                                        bool hasFalseCode, bool invertValue,
+                                        bool invertValue,
                                         ArrayRef<SILType> contArgs,
                                         ProfileCounter NumTrueTaken,
                                         ProfileCounter NumFalseTaken) {
@@ -179,23 +257,14 @@
   for (SILType argTy : contArgs) {
     ContBB->createPhiArgument(argTy, ValueOwnershipKind::Owned);
   }
-  
-  SILBasicBlock *FalseBB, *FalseDestBB;
-  if (hasFalseCode) {
-    FalseBB = FalseDestBB = createBasicBlock();
-  } else {
-    FalseBB = nullptr;
-    FalseDestBB = ContBB;
-  }
 
+  SILBasicBlock *FalseBB = createBasicBlock();
   SILBasicBlock *TrueBB = createBasicBlock();
 
   if (invertValue)
-    B.createCondBranch(Loc, V, FalseDestBB, TrueBB, NumFalseTaken,
-                       NumTrueTaken);
+    B.createCondBranch(Loc, V, FalseBB, TrueBB, NumFalseTaken, NumTrueTaken);
   else
-    B.createCondBranch(Loc, V, TrueBB, FalseDestBB, NumTrueTaken,
-                       NumFalseTaken);
+    B.createCondBranch(Loc, V, TrueBB, FalseBB, NumTrueTaken, NumFalseTaken);
 
   return Condition(TrueBB, FalseBB, ContBB, Loc);
 }
@@ -507,8 +576,7 @@
 void StmtEmitter::visitIfStmt(IfStmt *S) {
   Scope condBufferScope(SGF.Cleanups, S);
   
-  // Create a continuation block.  We need it if there is a labeled break out
-  // of the if statement or if there is an if/then/else.
+  // Create a continuation block.
   JumpDest contDest = createJumpDest(S->getThenStmt());
   auto contBB = contDest.getBlock();
 
@@ -774,7 +842,7 @@
     // to the continuation block.
     auto NumTrueTaken = SGF.loadProfilerCount(S->getBody());
     auto NumFalseTaken = SGF.loadProfilerCount(S);
-    Condition Cond = SGF.emitCondition(S->getCond(), /*hasFalseCode*/ false,
+    Condition Cond = SGF.emitCondition(S->getCond(),
                                        /*invertValue*/ false, /*contArgs*/ {},
                                        NumTrueTaken, NumFalseTaken);
 
@@ -881,8 +949,7 @@
           // condition.
           // If it fails, loop around as if 'continue' happened.
           if (auto *Where = S->getWhere()) {
-            auto cond =
-                SGF.emitCondition(Where, /*hasFalse*/ false, /*invert*/ true);
+            auto cond = SGF.emitCondition(Where, /*invert*/ true);
             // If self is null, branch to the epilog.
             cond.enterTrue(SGF);
             SGF.Cleanups.emitBranchAndCleanups(loopDest, Where, {});
diff --git a/lib/SILOptimizer/Utils/CFG.cpp b/lib/SILOptimizer/Utils/CFG.cpp
index b59b1de..e72a947 100644
--- a/lib/SILOptimizer/Utils/CFG.cpp
+++ b/lib/SILOptimizer/Utils/CFG.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "swift/SIL/BasicBlockUtils.h"
 #include "swift/SIL/Dominance.h"
 #include "swift/SIL/LoopInfo.h"
 #include "swift/SIL/SILArgument.h"
@@ -740,16 +741,6 @@
   if (BB == SuccBB || !SuccBB->getSinglePredecessorBlock())
     return false;
 
-  // If there are any BB arguments in the destination, replace them with the
-  // branch operands, since they must dominate the dest block.
-  for (unsigned i = 0, e = Branch->getArgs().size(); i != e; ++i)
-    SuccBB->getArgument(i)->replaceAllUsesWith(Branch->getArg(i));
-
-  Branch->eraseFromParent();
-
-  // Move the instruction from the successor block to the current block.
-  BB->spliceAtEnd(SuccBB);
-
   if (DT)
     if (auto *SuccBBNode = DT->getNode(SuccBB)) {
       // Change the immediate dominator for children of the successor to be the
@@ -766,7 +757,7 @@
   if (LI)
     LI->removeBlock(SuccBB);
 
-  SuccBB->eraseFromParent();
+  mergeBasicBlockWithSingleSuccessor(BB, SuccBB);
 
   return true;
 }
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index d0ae002..65f1bf3 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -411,6 +411,10 @@
   BasicBlockMap.clear();
   // Assign a value ID to each SILInstruction that has value and to each basic
   // block argument.
+  //
+  // FIXME: Add reverse iteration to SILSuccessor and convert this to a "stable"
+  // RPO order. Currently, the serializer inverts the order of successors each
+  // time they are processed.
   unsigned ValueID = 0;
   llvm::ReversePostOrderTraversal<SILFunction *> RPOT(
       const_cast<SILFunction *>(&F));
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index b52c1f7..31f7697 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -221,14 +221,11 @@
 // CHECK: br label %[[END]]
 
 // CHECK: ; <label>:[[DEFAULT_CASE]]
-// CHECK: br label %[[DEFAULT_CASE_DESTROY:.*]]
-
-// CHECK: <label>:[[DEFAULT_CASE_DESTROY]]
 // CHeCK: call void %destroy
 // CHECK: br label %[[END]]
 
 // CHECK: ; <label>:[[END]]
-// CHECK: = phi [[INT]] [ 3, %[[DEFAULT_CASE_DESTROY]] ], [ {{.*}}, %[[PAMPHLET_CASE_LABEL]] ], [ 2, %[[CANVAS_CASE_LABEL]] ], [ 1, %[[PAPER_CASE_LABEL]] ]
+// CHECK: = phi [[INT]] [ 3, %[[DEFAULT_CASE]] ], [ {{.*}}, %[[PAMPHLET_CASE_LABEL]] ], [ 2, %[[CANVAS_CASE_LABEL]] ], [ 1, %[[PAPER_CASE_LABEL]] ]
 // CHECK: ret
 
 public func resilientSwitchTest(_ m: Medium) -> Int {
diff --git a/test/SILGen/auto_generated_super_init_call.swift b/test/SILGen/auto_generated_super_init_call.swift
index a3471d3..34a21a0 100644
--- a/test/SILGen/auto_generated_super_init_call.swift
+++ b/test/SILGen/auto_generated_super_init_call.swift
@@ -40,7 +40,7 @@
 // Check that we are emitting the super.init expr into the epilog block.
     
 // CHECK-LABEL: sil hidden @$s30auto_generated_super_init_call16SomeDerivedClassC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (Bool, @owned SomeDerivedClass) -> @owned SomeDerivedClass    
-// CHECK: bb4:
+// CHECK: bb5:
 // SEMANTIC ARC TODO: Another case of needing a mutable load_borrow.
 // CHECK-NEXT: [[SELFLOAD:%[0-9]+]] = load [take] [[SELF:%[0-9]+]] : $*SomeDerivedClass
 // CHECK-NEXT: [[SELFLOAD_PARENT_CAST:%.*]] = upcast [[SELFLOAD]]
diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift
index f2f67f8..548b19e 100644
--- a/test/SILGen/errors.swift
+++ b/test/SILGen/errors.swift
@@ -694,12 +694,10 @@
 // CHECK-NEXT: destroy_value [[RESULT]] : $Optional<Cat>
 // CHECK-NEXT: [[VOID:%.+]] = tuple ()
 // CHECK-NEXT: return [[VOID]] : $()
-// CHECK: [[FAILURE:.+]]([[ERROR:%.*]] : @owned $Error):
+// CHECK: [[CLEANUPS:.+]]([[ERROR:%.*]] : @owned $Error):
 // CHECK-NEXT: destroy_value [[ERROR]]
 // CHECK-NEXT: [[NONE:%.+]] = enum $Optional<Cat>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE]]([[NONE]] : $Optional<Cat>)
-// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
-// CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $Error)
 // CHECK: } // end sil function '$s6errors15testOptionalTryyyF'
 func testOptionalTry() {
   _ = try? make_a_cat()
@@ -729,12 +727,10 @@
 // CHECK-NEXT: destroy_value [[BOX]] : ${ var Optional<Cat> }
 // CHECK-NEXT: [[VOID:%.+]] = tuple ()
 // CHECK-NEXT: return [[VOID]] : $()
-// CHECK: [[FAILURE:.+]]([[ERROR:%.*]] : @owned $Error):
+// CHECK: [[CLEANUPS:.+]]([[ERROR:%.*]] : @owned $Error):
 // CHECK-NEXT: destroy_value [[ERROR]]
 // CHECK-NEXT: inject_enum_addr [[PB]] : $*Optional<Cat>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE]]
-// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
-// CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $Error)
 // CHECK: } // end sil function '$s6errors18testOptionalTryVaryyF'
 func testOptionalTryVar() {
   var cat = try? make_a_cat() // expected-warning {{initialization of variable 'cat' was never used; consider replacing with assignment to '_' or removing it}}
@@ -755,12 +751,10 @@
 // CHECK-NOT: destroy_addr %0 : $*T
 // CHECK-NEXT: [[VOID:%.+]] = tuple ()
 // CHECK-NEXT: return [[VOID]] : $()
-// CHECK: [[FAILURE:.+]]([[ERROR:%.*]] : @owned $Error):
+// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
 // CHECK-NEXT: destroy_value [[ERROR]]
 // CHECK-NEXT: inject_enum_addr [[BOX]] : $*Optional<T>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE]]
-// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
-// CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $Error)
 // CHECK: } // end sil function '$s6errors26testOptionalTryAddressOnlyyyxlF'
 func testOptionalTryAddressOnly<T>(_ obj: T) {
   _ = try? dont_return(obj)
@@ -781,12 +775,10 @@
 // CHECK-NOT: destroy_addr %0 : $*T
 // CHECK-NEXT: [[VOID:%.+]] = tuple ()
 // CHECK-NEXT: return [[VOID]] : $()
-// CHECK: [[FAILURE:.+]]([[ERROR:%.*]] : @owned $Error):
+// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
 // CHECK-NEXT: destroy_value [[ERROR]]
 // CHECK-NEXT: inject_enum_addr [[PB]] : $*Optional<T>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE]]
-// CHECK: [[CLEANUPS]]([[ERROR:%.+]] : @owned $Error):
-// CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $Error)
 // CHECK: } // end sil function '$s6errors29testOptionalTryAddressOnlyVaryyxlF'
 func testOptionalTryAddressOnlyVar<T>(_ obj: T) {
   var copy = try? dont_return(obj) // expected-warning {{initialization of variable 'copy' was never used; consider replacing with assignment to '_' or removing it}}
diff --git a/test/SILGen/force_cast_chained_optional.swift b/test/SILGen/force_cast_chained_optional.swift
index 96317ce..7487cef 100644
--- a/test/SILGen/force_cast_chained_optional.swift
+++ b/test/SILGen/force_cast_chained_optional.swift
@@ -18,9 +18,6 @@
 // CHECK:   select_enum_addr {{%.*}}
 // CHECK:   cond_br {{%.*}}, [[SOME_BAR:bb[0-9]+]], [[NO_BAR:bb[0-9]+]]
 //
-// CHECK: [[NO_BAR]]:
-// CHECK:   br [[TRAP:bb[0-9]+]]
-//
 // CHECK: [[SOME_BAR]]:
 // CHECK:   [[PAYLOAD_ADDR:%.*]] = unchecked_take_enum_data_addr {{%.*}} : $*Optional<Bar>
 // CHECK:   [[BAR:%.*]] = load [copy] [[PAYLOAD_ADDR]]
@@ -30,7 +27,7 @@
 // CHECK:   end_borrow [[BORROWED_BAR]]
 // CHECK:   unconditional_checked_cast {{%.*}} : $C to $D
 //
-// CHECK: [[TRAP]]:
+// CHECK: [[NO_BAR]]:
 // CHECK:   unreachable
 func test(_ x: Foo) -> D {
   return x.bar?.bas as! D
diff --git a/test/SILGen/foreach.swift b/test/SILGen/foreach.swift
index 716e51f..789534e 100644
--- a/test/SILGen/foreach.swift
+++ b/test/SILGen/foreach.swift
@@ -59,15 +59,12 @@
 // CHECK: [[LOOP_DEST]]:
 // CHECK:   switch_enum [[IND_VAR:%.*]] : $Optional<Int>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BLOCK:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]([[VAR:%.*]] : @trivial $Int):
 // CHECK:   [[LOOP_END_FUNC:%.*]] = function_ref @loopBodyEnd : $@convention(thin) () -> ()
 // CHECK:   apply [[LOOP_END_FUNC]]()
 // CHECK:   br [[LOOP_DEST]]
 //
-// CHECK: [[CONT_BLOCK]]:
+// CHECK: [[NONE_BB]]:
 // CHECK:   destroy_value [[ITERATOR_BOX]]
 // CHECK:   [[FUNC_END_FUNC:%.*]] = function_ref @funcEnd : $@convention(thin) () -> ()
 // CHECK:   apply [[FUNC_END_FUNC]]()
@@ -123,9 +120,6 @@
 // CHECK:   [[IND_VAR:%.*]] = load [trivial] [[GET_ELT_STACK]]
 // CHECK:   switch_enum [[IND_VAR]] : $Optional<Int>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BLOCK_JUMP:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]([[VAR:%.*]] : @trivial $Int):
 // CHECK:   cond_br {{%.*}}, [[LOOP_BREAK_END_BLOCK:bb[0-9]+]], [[CONTINUE_CHECK_BLOCK:bb[0-9]+]]
 //
@@ -147,7 +141,7 @@
 // CHECK:   apply [[LOOP_BODY_FUNC]]()
 // CHECK:   br [[LOOP_DEST]]
 //
-// CHECK: [[CONT_BLOCK_JUMP]]:
+// CHECK: [[NONE_BB]]:
 // CHECK:   br [[CONT_BLOCK]]
 //
 // CHECK: [[CONT_BLOCK]]
@@ -225,9 +219,6 @@
 // CHECK:   apply [[FUNC_REF]]<[P]>([[ELT_STACK]], [[WRITE]])
 // CHECK:   switch_enum_addr [[ELT_STACK]] : $*Optional<P>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BLOCK_JUMP:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]:
 // CHECK:   [[T0:%.*]] = alloc_stack $P, let, name "x"
 // CHECK:   [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<P>, #Optional.some!enumelt.1
@@ -258,7 +249,7 @@
 // CHECK:   dealloc_stack [[T0]]
 // CHECK:   br [[LOOP_DEST]]
 //
-// CHECK: [[CONT_BLOCK_JUMP]]:
+// CHECK: [[NONE_BB]]:
 // CHECK:   br [[CONT_BLOCK]]
 //
 // CHECK: [[CONT_BLOCK]]
@@ -388,9 +379,6 @@
 // CHECK:   apply [[FUNC_REF]]<[GenericStruct<T>]>([[ELT_STACK]], [[WRITE]])
 // CHECK:   switch_enum_addr [[ELT_STACK]] : $*Optional<GenericStruct<T>>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BLOCK_JUMP:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]:
 // CHECK:   [[T0:%.*]] = alloc_stack $GenericStruct<T>, let, name "x"
 // CHECK:   [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<GenericStruct<T>>, #Optional.some!enumelt.1
@@ -421,7 +409,7 @@
 // CHECK:   dealloc_stack [[T0]]
 // CHECK:   br [[LOOP_DEST]]
 //
-// CHECK: [[CONT_BLOCK_JUMP]]:
+// CHECK: [[NONE_BB]]:
 // CHECK:   br [[CONT_BLOCK]]
 //
 // CHECK: [[CONT_BLOCK]]
@@ -497,9 +485,6 @@
 // CHECK:   apply [[GET_NEXT_FUNC]]<T.Iterator>([[ELT_STACK]], [[WRITE]])
 // CHECK:   switch_enum_addr [[ELT_STACK]] : $*Optional<T.Element>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BLOCK_JUMP:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]:
 // CHECK:   [[T0:%.*]] = alloc_stack $T.Element, let, name "x"
 // CHECK:   [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<T.Element>, #Optional.some!enumelt.1
@@ -530,7 +515,7 @@
 // CHECK:   dealloc_stack [[T0]]
 // CHECK:   br [[LOOP_DEST]]
 //
-// CHECK: [[CONT_BLOCK_JUMP]]:
+// CHECK: [[NONE_BB]]:
 // CHECK:   br [[CONT_BLOCK]]
 //
 // CHECK: [[CONT_BLOCK]]
@@ -562,27 +547,27 @@
 
 // CHECK-LABEL: sil hidden @$s7foreach13tupleElementsyySayAA1CC_ADtGF
 func tupleElements(_ xx: [(C, C)]) {
-  // CHECK: bb3([[PAYLOAD:%.*]] : @owned $(C, C)):
+  // CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
   // CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK: destroy_value [[B]]
   // CHECK: destroy_value [[A]]
   for (a, b) in xx {}
-  // CHECK: bb7([[PAYLOAD:%.*]] : @owned $(C, C)):
+  // CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
   // CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK: destroy_value [[B]]
   // CHECK: destroy_value [[A]]
   for (a, _) in xx {}
-  // CHECK: bb11([[PAYLOAD:%.*]] : @owned $(C, C)):
+  // CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
   // CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK: destroy_value [[A]]
   // CHECK: destroy_value [[B]]
   for (_, b) in xx {}
-  // CHECK: bb15([[PAYLOAD:%.*]] : @owned $(C, C)):
+  // CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
   // CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK: destroy_value [[B]]
   // CHECK: destroy_value [[A]]
   for (_, _) in xx {}
-  // CHECK: bb19([[PAYLOAD:%.*]] : @owned $(C, C)):
+  // CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
   // CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK: destroy_value [[B]]
   // CHECK: destroy_value [[A]]
@@ -599,9 +584,6 @@
 // CHECK: [[LOOP_DEST]]:
 // CHECK:   switch_enum [[OPT_VAL:%.*]] : $Optional<Int>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 //
-// CHECK: [[NONE_BB]]:
-// CHECK:   br [[CONT_BB:bb[0-9]+]]
-//
 // CHECK: [[SOME_BB]]([[VAL:%.*]]  : @trivial $Int):
 // CHECK:   [[LOOP_END_FUNC:%.*]] = function_ref @loopBodyEnd : $@convention(thin) () -> ()
 // CHECK:   apply [[LOOP_END_FUNC]]
diff --git a/test/SILGen/if_while_binding.swift b/test/SILGen/if_while_binding.swift
index 346c544..65db13d 100644
--- a/test/SILGen/if_while_binding.swift
+++ b/test/SILGen/if_while_binding.swift
@@ -42,9 +42,6 @@
   // CHECK-NEXT:   [[OPT_RES:%.*]] = apply [[FOO]]()
   // CHECK-NEXT:   switch_enum [[OPT_RES]] : $Optional<String>, case #Optional.some!enumelt.1: [[YESX:bb[0-9]+]], case #Optional.none!enumelt: [[NOX:bb[0-9]+]]
   if let x = foo() {
-  // CHECK: [[NOX]]:
-  // CHECK:   br [[FAILURE_DESTX:bb[0-9]+]]
-  //
   // CHECK: [[YESX]]([[VAL:%[0-9]+]] : @owned $String):
   // CHECK:   debug_value [[VAL]] : $String, let, name "x"
   // CHECK:   [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
@@ -55,26 +52,22 @@
   // CHECK:   br [[CONT_X:bb[0-9]+]]
     a(x)
   //
-  // CHECK: [[FAILURE_DESTX]]:
+  // CHECK: [[NOX]]:
   // CHECK:   alloc_box ${ var String }, var, name "y"
-  // CHECK:   switch_enum {{.*}} : $Optional<String>, case #Optional.some!enumelt.1: [[YESY:bb[0-9]+]], case #Optional.none!enumelt: [[ELSE1:bb[0-9]+]]
-    // CHECK: [[ELSE1]]:
-    // CHECK:   dealloc_box {{.*}} ${ var String }
-    // CHECK:   br [[ELSE:bb[0-9]+]]
+  // CHECK:   switch_enum {{.*}} : $Optional<String>, case #Optional.some!enumelt.1: [[YESY:bb[0-9]+]], case #Optional.none!enumelt: [[ELSE:bb[0-9]+]]
   } else if var y = bar() {
   // CHECK: [[YESY]]([[VAL:%[0-9]+]] : @owned $String):
   // CHECK:   br [[CONT_Y:bb[0-9]+]]
-  // CHECK: [[CONT_Y]]:
-  // CHECK:   br [[CONT_Y2:bb[0-9]+]]
     b(y)
   } else {
     // CHECK: [[ELSE]]:
-    // CHECK: function_ref if_while_binding.c
+    // CHECK:   dealloc_box {{.*}} ${ var String }
+    // CHECK:   function_ref if_while_binding.c
     c("")
-    // CHECK:   br [[CONT_Y2]]
+    // CHECK:   br [[CONT_Y]]
   }
 
-  // CHECK: [[CONT_Y2]]:
+  // CHECK: [[CONT_Y]]:
   //   br [[CONT_X]]
   // CHECK: [[CONT_X]]:
 }
@@ -90,10 +83,7 @@
   // CHECK:   br [[LOOP_EXIT:bb[0-9]+]]
   while let x = foo() {
   // CHECK: [[LOOP_BODY]]([[X:%[0-9]+]] : @owned $String):
-  // CHECK:   switch_enum {{.*}} : $Optional<String>, case #Optional.some!enumelt.1: [[YES:bb[0-9]+]], case #Optional.none!enumelt: [[NO_TRAMPOLINE_2:bb[0-9]+]]
-  //
-  // CHECK: [[NO_TRAMPOLINE_2]]:
-  // CHECK:   br [[FAILURE_DEST_2:bb[0-9]+]]
+  // CHECK:   switch_enum {{.*}} : $Optional<String>, case #Optional.some!enumelt.1: [[YES:bb[0-9]+]], case #Optional.none!enumelt: [[FAILURE_DEST_2:bb[0-9]+]]
     if let y = bar() {
   // CHECK: [[YES]]([[Y:%[0-9]+]] : @owned $String):
       a(y)
@@ -119,17 +109,15 @@
 // CHECK:         [[X:%.*]] = alloc_stack $T, let, name "x"
 // CHECK:         [[OPTBUF:%[0-9]+]] = alloc_stack $Optional<T>
 // CHECK:         switch_enum_addr {{.*}}, case #Optional.some!enumelt.1: [[LOOPBODY:bb.*]], case #Optional.none!enumelt: [[OUT:bb[0-9]+]]
-// CHECK:       [[OUT]]:
-// CHECK:         dealloc_stack [[OPTBUF]]
-// CHECK:         dealloc_stack [[X]]
-// CHECK:         br [[DONE:bb[0-9]+]]
 // CHECK:       [[LOOPBODY]]:
 // CHECK:         [[ENUMVAL:%.*]] = unchecked_take_enum_data_addr
 // CHECK:         copy_addr [take] [[ENUMVAL]] to [initialization] [[X]]
 // CHECK:         destroy_addr [[X]]
 // CHECK:         dealloc_stack [[X]]
 // CHECK:         br [[COND]]
-// CHECK:       [[DONE]]:
+// CHECK:       [[OUT]]:
+// CHECK:         dealloc_stack [[OPTBUF]]
+// CHECK:         dealloc_stack [[X]]
 // CHECK:         return
 // CHECK: } // end sil function '$s16if_while_binding0B13_loop_generic{{[_0-9a-zA-Z]*}}F'
 func while_loop_generic<T>(_ source: () -> T?) {
@@ -247,7 +235,7 @@
   // CHECK:   switch_enum {{.*}}, case #Optional.some!enumelt.1: [[CHECKBUF2:bb.*]], case #Optional.none!enumelt: [[NONE_TRAMPOLINE:bb[0-9]+]]
   //
   // CHECK: [[NONE_TRAMPOLINE]]:
-  // CHECK:   br [[ELSE:bb[0-9]+]]
+  // CHECK:   br [[DONE:bb[0-9]+]]
   // CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : @owned $String):
   // CHECK:   debug_value [[A]] : $String, let, name "a"
   // CHECK:   [[BBOX:%[0-9]+]] = alloc_box ${ var String }, var, name "b"
@@ -256,23 +244,23 @@
   // CHECK: [[IF_EXIT1a]]:
   // CHECK:   dealloc_box {{.*}} ${ var String }
   // CHECK:   destroy_value [[A]]
-  // CHECK:   br [[ELSE]]
+  // CHECK:   br [[DONE]]
 
   // CHECK: [[CHECK_WHERE]]([[B:%[0-9]+]] : @owned $String):
   // CHECK:   function_ref Swift.Bool._getBuiltinLogicValue() -> Builtin.Int1
   // CHECK:   cond_br {{.*}}, [[IF_BODY:bb[0-9]+]], [[IF_EXIT3:bb[0-9]+]]
-  // CHECK: [[IF_EXIT3]]:
-  // CHECK:   destroy_value [[BBOX]]
-  // CHECK:   destroy_value [[A]]
-  // CHECK:   br [[IF_DONE:bb[0-9]+]]
   if let a = foo(), var b = bar(), a == b {
     // CHECK: [[IF_BODY]]:
     // CHECK:   destroy_value [[BBOX]]
     // CHECK:   destroy_value [[A]]
-    // CHECK:   br [[IF_DONE]]
+    // CHECK:   br [[DONE]]
     let c = a
   }
-  // CHECK: [[IF_DONE]]:
+  // CHECK: [[IF_EXIT3]]:
+  // CHECK:   destroy_value [[BBOX]]
+  // CHECK:   destroy_value [[A]]
+  // CHECK:   br [[DONE]]
+  // CHECK: [[DONE]]:
   // CHECK-NEXT:   tuple ()
   // CHECK-NEXT:   return
 }
@@ -288,13 +276,13 @@
 
   // CHECK:      [[FN:%.*]] = function_ref {{.*}}
   // CHECK-NEXT: [[EQRESULTI1:%[0-9]+]] = apply [[FN:%.*]]([[EQRESULT]]) : $@convention(method) (Bool) -> Builtin.Int1
-  // CHECK-NEXT: cond_br [[EQRESULTI1]], [[CHECKFOO:bb[0-9]+]], [[IFDONE:bb[0-9]+]]
+  // CHECK-NEXT: cond_br [[EQRESULTI1]], [[CHECKFOO:bb[0-9]+]], [[ELSE:bb[0-9]+]]
 
   // Call Foo and test for the optional being present.
 // CHECK: [[CHECKFOO]]:
   // CHECK: [[OPTRESULT:%[0-9]+]] = apply {{.*}}() : $@convention(thin) () -> @owned Optional<String>
   
-  // CHECK:   switch_enum [[OPTRESULT]] : $Optional<String>, case #Optional.some!enumelt.1: [[SUCCESS:bb.*]], case #Optional.none!enumelt: [[IF_DONE:bb[0-9]+]]
+  // CHECK:   switch_enum [[OPTRESULT]] : $Optional<String>, case #Optional.some!enumelt.1: [[SUCCESS:bb.*]], case #Optional.none!enumelt: [[IFDONE:bb[0-9]+]]
 
 // CHECK: [[SUCCESS]]([[B:%[0-9]+]] : @owned $String):
   // CHECK:   debug_value [[B]] : $String, let, name "b"
@@ -304,10 +292,12 @@
   // CHECK:   end_borrow [[BORROWED_B]]
   // CHECK:   destroy_value [[B_COPY]]
   // CHECK:   destroy_value [[B]]
-  // CHECK:   br [[IFDONE]]
+  // CHECK:   br [[IFDONE:bb[0-9]+]]
   if a == a, let b = foo() {
     let c = b
   }
+  // CHECK: [[ELSE]]:
+  // CHECK:   br [[IFDONE]]
   // CHECK: [[IFDONE]]:
   // CHECK-NEXT: tuple ()
 
@@ -368,11 +358,11 @@
   //
   // CHECK: [[SOME_BB]]([[PAYLOAD:%.*]] : @trivial $Bool):
   // CHECK:   [[ISTRUE:%[0-9]+]] = struct_extract [[PAYLOAD]] : $Bool, #Bool._value
-  // CHECK:   cond_br [[ISTRUE]], [[TRUE_TRAMPOLINE_BB:bb[0-9]+]], [[CONT_BB]]
-  //
-  // CHECK: [[TRUE_TRAMPOLINE_BB:bb[0-9]+]]
-  // CHECK:   br [[TRUE_BB:bb[0-9]+]]
-  //
+  // CHECK:   cond_br [[ISTRUE]], [[TRUE_BB:bb[0-9]+]], [[FALSE_TRAMPOLINE:bb[0-9]+]]
+
+  // CHECK: [[FALSE_TRAMPOLINE]]:
+  // CHECK:   br [[CONT_BB]]
+
   // CHECK: [[TRUE_BB]]:
   // CHECK:   function_ref @$s16if_while_binding8marker_1yyF
   // CHECK:   br [[CONT_BB]]
@@ -388,10 +378,10 @@
 
   // CHECK: [[SUCC_BB_2]]([[PAYLOAD2:%.*]] : @trivial $Bool):
   // CHECK:   [[ISTRUE:%[0-9]+]] = struct_extract [[PAYLOAD2]] : $Bool, #Bool._value
-  // CHECK:   cond_br [[ISTRUE]], [[EPILOG_BB]], [[FALSE2_TRAMPOLINE_BB:bb[0-9]+]]
+  // CHECK:   cond_br [[ISTRUE]], [[TRUE3_BB:bb[0-9]+]], [[FALSE2_BB:bb[0-9]+]]
 
-  // CHECK: [[FALSE2_TRAMPOLINE_BB]]:
-  // CHECK:   br [[FALSE2_BB:bb[0-9]+]]
+  // CHECK: [[TRUE3_BB]]:
+  // CHECK:   br [[EPILOG_BB:bb[0-9]+]]
   //
   // CHECK: [[FALSE2_BB]]:
   // CHECK:   function_ref @$s16if_while_binding8marker_2yyF
diff --git a/test/SILGen/implicitly_unwrapped_optional.swift b/test/SILGen/implicitly_unwrapped_optional.swift
index da73905..2a86827 100644
--- a/test/SILGen/implicitly_unwrapped_optional.swift
+++ b/test/SILGen/implicitly_unwrapped_optional.swift
@@ -13,24 +13,24 @@
 // CHECK:   store [[T0_COPY]] to [init] [[PF]]
 // CHECK:   [[READ:%.*]] = begin_access [read] [unknown] [[PF]] : $*Optional<@callee_guaranteed () -> ()>
 // CHECK:   [[HASVALUE:%.*]] = select_enum_addr [[READ]]
-// CHECK:   cond_br [[HASVALUE]], bb2, bb1
+// CHECK:   cond_br [[HASVALUE]], bb1, bb3
 //
 //   If it does, project and load the value out of the implicitly unwrapped
 //   optional...
-// CHECK:    bb2:
+// CHECK:    bb1:
 // CHECK-NEXT: [[FN0_ADDR:%.*]] = unchecked_take_enum_data_addr [[READ]]
 // CHECK-NEXT: [[FN0:%.*]] = load [copy] [[FN0_ADDR]]
 //   .... then call it
 // CHECK:   [[B:%.*]] = begin_borrow [[FN0]]
 // CHECK:   apply [[B]]() : $@callee_guaranteed () -> ()
 // CHECK:   end_borrow [[B]]
-// CHECK:   br bb3
-// CHECK: bb3(
+// CHECK:   br bb2
+// CHECK: bb2(
 // CHECK:   destroy_value [[F]]
 // CHECK:   return
-// CHECK: bb4:
+// CHECK: bb3:
 // CHECK:   enum $Optional<()>, #Optional.none!enumelt
-// CHECK:   br bb3
+// CHECK:   br bb2
 //   The rest of this is tested in optional.swift
 // } // end sil function '{{.*}}foo{{.*}}'
 
diff --git a/test/SILGen/indirect_enum.swift b/test/SILGen/indirect_enum.swift
index 4f2556c..e7615f1 100644
--- a/test/SILGen/indirect_enum.swift
+++ b/test/SILGen/indirect_enum.swift
@@ -335,17 +335,13 @@
   // CHECK: bb0([[ARG:%.*]] : @guaranteed $TreeA<T>):
   do {
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
-    // CHECK:   destroy_value [[ORIGINAL_VALUE]]
+    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO1:bb[0-9]+]]
     // CHECK: [[YES]]:
     guard case .Nil = tree else { return }
 
     // CHECK:   [[X:%.*]] = alloc_stack $T
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
-    // CHECK:   destroy_value [[ORIGINAL_VALUE]]
+    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO2:bb[0-9]+]]
     // CHECK: [[YES]]([[BOX:%.*]] : @owned $<τ_0_0> { var τ_0_0 } <T>):
     // CHECK:   [[VALUE_ADDR:%.*]] = project_box [[BOX]]
     // CHECK:   [[TMP:%.*]] = alloc_stack
@@ -355,9 +351,7 @@
     guard case .Leaf(let x) = tree else { return }
 
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
-    // CHECK:   destroy_value [[ORIGINAL_VALUE]]
+    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO3:bb[0-9]+]]
     // CHECK: [[YES]]([[BOX:%.*]] : @owned $<τ_0_0> { var (left: TreeA<τ_0_0>, right: TreeA<τ_0_0>) } <T>):
     // CHECK:   [[VALUE_ADDR:%.*]] = project_box [[BOX]]
     // CHECK:   [[TUPLE:%.*]] = load_borrow [[VALUE_ADDR]]
@@ -374,8 +368,8 @@
 
   do {
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
+    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO4:bb[0-9]+]]
+    // CHECK: [[NO4]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
     // CHECK:   destroy_value [[ORIGINAL_VALUE]]
     // CHECK: [[YES]]:
     // CHECK:   br
@@ -383,8 +377,8 @@
 
     // CHECK:   [[X:%.*]] = alloc_stack $T
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
+    // CHECK:   switch_enum [[ARG_COPY]] : $TreeA<T>, case #TreeA.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO5:bb[0-9]+]]
+    // CHECK: [[NO5]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
     // CHECK:   destroy_value [[ORIGINAL_VALUE]]
     // CHECK: [[YES]]([[BOX:%.*]] : @owned $<τ_0_0> { var τ_0_0 } <T>):
     // CHECK:   [[VALUE_ADDR:%.*]] = project_box [[BOX]]
@@ -411,37 +405,37 @@
     // CHECK:   destroy_value [[L]]
     if case .Branch(left: let l, right: let r) = tree { }
   }
+  // CHECK: [[NO3]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
+  // CHECK:   destroy_value [[ORIGINAL_VALUE]]
+  // CHECK: [[NO2]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
+  // CHECK:   destroy_value [[ORIGINAL_VALUE]]
+  // CHECK: [[NO1]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):
+  // CHECK:   destroy_value [[ORIGINAL_VALUE]]
 }
 // CHECK-LABEL: sil hidden @$s13indirect_enum10guardTreeB{{[_0-9a-zA-Z]*}}F
 func guardTreeB<T>(_ tree: TreeB<T>) {
   do {
-    // CHECK:   copy_addr %0 to [initialization] [[TMP:%.*]] :
-    // CHECK:   switch_enum_addr [[TMP]] : $*TreeB<T>, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]:
-    // CHECK:   destroy_addr [[TMP]]
+    // CHECK:   copy_addr %0 to [initialization] [[TMP1:%.*]] :
+    // CHECK:   switch_enum_addr [[TMP1]] : $*TreeB<T>, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO2:bb[0-9]+]]
     // CHECK: [[YES]]:
-    // CHECK:   destroy_addr [[TMP]]
+    // CHECK:   destroy_addr [[TMP1]]
     guard case .Nil = tree else { return }
 
     // CHECK:   [[X:%.*]] = alloc_stack $T
-    // CHECK:   copy_addr %0 to [initialization] [[TMP:%.*]] :
-    // CHECK:   switch_enum_addr [[TMP]] : $*TreeB<T>, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]:
-    // CHECK:   destroy_addr [[TMP]]
+    // CHECK:   copy_addr %0 to [initialization] [[TMP2:%.*]] :
+    // CHECK:   switch_enum_addr [[TMP2]] : $*TreeB<T>, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO2:bb[0-9]+]]
     // CHECK: [[YES]]:
-    // CHECK:   [[VALUE:%.*]] = unchecked_take_enum_data_addr [[TMP]]
+    // CHECK:   [[VALUE:%.*]] = unchecked_take_enum_data_addr [[TMP2]]
     // CHECK:   copy_addr [take] [[VALUE]] to [initialization] [[X]]
-    // CHECK:   dealloc_stack [[TMP]]
+    // CHECK:   dealloc_stack [[TMP2]]
     guard case .Leaf(let x) = tree else { return }
 
     // CHECK:   [[L:%.*]] = alloc_stack $TreeB
     // CHECK:   [[R:%.*]] = alloc_stack $TreeB
-    // CHECK:   copy_addr %0 to [initialization] [[TMP:%.*]] :
-    // CHECK:   switch_enum_addr [[TMP]] : $*TreeB<T>, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]]
-    // CHECK: [[NO]]:
-    // CHECK:   destroy_addr [[TMP]]
+    // CHECK:   copy_addr %0 to [initialization] [[TMP3:%.*]] :
+    // CHECK:   switch_enum_addr [[TMP3]] : $*TreeB<T>, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO3:bb[0-9]+]]
     // CHECK: [[YES]]:
-    // CHECK:   [[BOX_ADDR:%.*]] = unchecked_take_enum_data_addr [[TMP]]
+    // CHECK:   [[BOX_ADDR:%.*]] = unchecked_take_enum_data_addr [[TMP3]]
     // CHECK:   [[BOX:%.*]] = load [take] [[BOX_ADDR]]
     // CHECK:   [[TUPLE_ADDR:%.*]] = project_box [[BOX]]
     // CHECK:   copy_addr [[TUPLE_ADDR]] to [initialization] [[TUPLE_COPY:%.*]] :
@@ -498,6 +492,12 @@
     // CHECK:   destroy_addr [[L]]
     if case .Branch(left: let l, right: let r) = tree { }
   }
+  // CHECK: [[NO3]]:
+  // CHECK:   destroy_addr [[TMP3]]
+  // CHECK: [[NO2]]:
+  // CHECK:   destroy_addr [[TMP2]]
+  // CHECK: [[NO1]]:
+  // CHECK:   destroy_addr [[TMP1]]
 }
 
 // Just run guardTreeInt through the ownership verifier
@@ -526,20 +526,21 @@
   // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
   // CHECK:   switch_enum [[ARG_COPY]] : $TrivialButIndirect, case #TrivialButIndirect.Direct!enumelt.1:  [[YES:bb[0-9]+]], case #TrivialButIndirect.Indirect!enumelt.1: [[NO:bb[0-9]+]]
   //
-  // CHECK: [[NO]]([[PAYLOAD:%.*]] : @owned ${ var Int }):
-  // CHECK:   destroy_value [[PAYLOAD]]
   guard case .Direct(let foo) = x else { return }
 
   // CHECK: [[YES]]({{%.*}} : @trivial $Int):
   // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-  // CHECK:   switch_enum [[ARG_COPY]] : $TrivialButIndirect, case #TrivialButIndirect.Indirect!enumelt.1:  [[YES:bb[0-9]+]], case #TrivialButIndirect.Direct!enumelt.1: [[NO:bb[0-9]+]]
-
-  // CHECK: [[NO]]({{%.*}} : @trivial $Int):
-  // CHECK-NOT: destroy_value
+  // CHECK:   switch_enum [[ARG_COPY]] : $TrivialButIndirect, case #TrivialButIndirect.Indirect!enumelt.1:  [[YES:bb[0-9]+]], case #TrivialButIndirect.Direct!enumelt.1: [[NO2:bb[0-9]+]]
 
   // CHECK: [[YES]]([[BOX:%.*]] : @owned ${ var Int }):
   // CHECK:   destroy_value [[BOX]]
 
+  // CHECK: [[NO2]]({{%.*}} : @trivial $Int):
+  // CHECK-NOT: destroy_value
+
+  // CHECK: [[NO]]([[PAYLOAD:%.*]] : @owned ${ var Int }):
+  // CHECK:   destroy_value [[PAYLOAD]]
+
   guard case .Indirect(let bar) = x else { return }
 }
 // CHECK: } // end sil function '$s13indirect_enum35dontDisableCleanupOfIndirectPayloadyyAA010TrivialButG0OF'
diff --git a/test/SILGen/objc_blocks_bridging.swift b/test/SILGen/objc_blocks_bridging.swift
index 8cbf438..1a7fe02 100644
--- a/test/SILGen/objc_blocks_bridging.swift
+++ b/test/SILGen/objc_blocks_bridging.swift
@@ -96,7 +96,7 @@
   // CHECK-LABEL: sil hidden @$s20objc_blocks_bridging3FooC19optCFunctionPointer{{[_0-9a-zA-Z]*}}F
   // CHECK:         switch_enum %0
   //
-  // CHECK: bb2([[FP_BUF:%.*]] : @trivial $@convention(c) (NSString) -> @autoreleased NSString):
+  // CHECK: bb1([[FP_BUF:%.*]] : @trivial $@convention(c) (NSString) -> @autoreleased NSString):
   @objc dynamic func optCFunctionPointer(_ fp: (@convention(c) (String) -> String)?, x: String) -> String? {
     return fp?(x)
   }
diff --git a/test/SILGen/objc_error.swift b/test/SILGen/objc_error.swift
index 1a67fc0..acbfce4 100644
--- a/test/SILGen/objc_error.swift
+++ b/test/SILGen/objc_error.swift
@@ -64,7 +64,7 @@
   // CHECK: unconditional_checked_cast_addr AnyObject in {{%.*}} : $*AnyObject to NSError in {{%.*}} : $*NSError
   let nsForcedCast = (e as AnyObject) as! NSError
 
-  // CHECK: checked_cast_addr_br {{.*}} Error in {{%.*}} : $*Error to NSError in {{%.*}} : $*NSError, bb3, bb4
+  // CHECK: checked_cast_addr_br {{.*}} Error in {{%.*}} : $*Error to NSError in {{%.*}} : $*NSError, bb1, bb2
   do {
     throw e
   } catch _ as NSError {
diff --git a/test/SILGen/optional-cast.swift b/test/SILGen/optional-cast.swift
index d3ba748..1519692 100644
--- a/test/SILGen/optional-cast.swift
+++ b/test/SILGen/optional-cast.swift
@@ -12,9 +12,6 @@
 // CHECK:      [[ARG_COPY:%.*]] = copy_value [[ARG]]
 // CHECK:      switch_enum [[ARG_COPY]] : $Optional<A>, case #Optional.some!enumelt.1: [[IS_PRESENT:bb[0-9]+]], case #Optional.none!enumelt: [[NOT_PRESENT:bb[0-9]+]]
 //
-// CHECK:    [[NOT_PRESENT]]:
-// CHECK:      br [[NOT_PRESENT_FINISH:bb[0-9]+]]
-//
 //   If so, pull the value out and check whether it's a B.
 // CHECK:    [[IS_PRESENT]]([[VAL:%.*]] :
 // CHECK-NEXT: [[X_VALUE:%.*]] = init_enum_data_addr [[PB]] : $*Optional<B>, #Optional.some
@@ -44,7 +41,7 @@
 // CHECK-NEXT: return
 //
 //   Finish the not-present path.
-// CHECK:    [[NOT_PRESENT_FINISH]]:
+// CHECK:    [[NOT_PRESENT]]:
 // CHECK-NEXT: inject_enum_addr [[PB]] {{.*}}none
 // CHECK-NEXT: br [[RETURN_BB]]
 func foo(_ y : A?) {
@@ -73,16 +70,10 @@
 // CHECK:    [[PP]]([[VALUE_OOA:%.*]] :
 // CHECK-NEXT: switch_enum [[VALUE_OOA]] : ${{.*}}, case #Optional.some!enumelt.1: [[PPP:bb[0-9]+]], case #Optional.none!enumelt: [[NIL_DEPTH_3:bb[0-9]+]]
 //
-// CHECK: [[NIL_DEPTH_3]]:
-// CHECK:   br [[FINISH_NIL_1:bb[0-9]+]]
-//
 //   If so, drill down another level and check for some(some(some(some(...)))).
 // CHECK:    [[PPP]]([[VALUE_OA:%.*]] :
 // CHECK-NEXT: switch_enum [[VALUE_OA]] : ${{.*}}, case #Optional.some!enumelt.1: [[PPPP:bb[0-9]+]], case #Optional.none!enumelt: [[NIL_DEPTH_4:bb[0-9]+]]
 //
-// CHECK: [[NIL_DEPTH_4]]:
-// CHECK:   br [[FINISH_NIL_2:bb[0-9]+]]
-//
 //   If so, pull out the A and check whether it's a B.
 // CHECK:    [[PPPP]]([[VAL:%.*]] :
 // CHECK-NEXT: checked_cast_br [[VAL]] : $A to $B, [[IS_B:bb.*]], [[NOT_B:bb[0-9]+]]
@@ -117,18 +108,18 @@
 //   Set X := some(OOB).
 // CHECK:    [[DONE_DEPTH1]]
 // CHECK-NEXT: enum $Optional<Optional<Optional<B>>>, #Optional.some!enumelt.1,
-// CHECK: br [[DONE_DEPTH2:bb[0-9]+]]
+// CHECK:      br [[DONE_DEPTH2:bb[0-9]+]]
 // CHECK:    [[DONE_DEPTH2]]
 // CHECK-NEXT: destroy_value [[X]]
 // CHECK-NOT: destroy_value %0
 // CHECK:      return
 //
 //   On various failure paths, set OOB := nil.
-// CHECK:    [[FINISH_NIL_2]]:
+// CHECK: [[NIL_DEPTH_4]]:
 // CHECK-NEXT: enum $Optional<B>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE_DEPTH0]]
 //
-// CHECK:    [[FINISH_NIL_1]]:
+// CHECK: [[NIL_DEPTH_3]]:
 // CHECK-NEXT: enum $Optional<Optional<B>>, #Optional.none!enumelt
 // CHECK-NEXT: br [[DONE_DEPTH1]]
 //
@@ -148,7 +139,7 @@
 // CHECK-NEXT:    [[PB:%.*]] = project_box [[X]]
 // CHECK-NEXT:    [[ARG_COPY:%.*]] = copy_value [[ARG]]
 // CHECK:         switch_enum [[ARG_COPY]]
-// CHECK:       bb2([[VAL:%.*]] : @owned $AnyObject):
+// CHECK:       bb1([[VAL:%.*]] : @owned $AnyObject):
 // CHECK-NEXT:    [[X_VALUE:%.*]] = init_enum_data_addr [[PB]] : $*Optional<B>, #Optional.some
 // CHECK-NEXT:    checked_cast_br [[VAL]] : $AnyObject to $B, [[IS_B:bb.*]], [[NOT_B:bb[0-9]+]]
 // CHECK:       [[IS_B]]([[CASTED_VALUE:%.*]] : @owned $B):
diff --git a/test/SILGen/optional.swift b/test/SILGen/optional.swift
index a49f763..e66669e 100644
--- a/test/SILGen/optional.swift
+++ b/test/SILGen/optional.swift
@@ -9,9 +9,6 @@
 // CHECK:      [[T0_COPY:%.*]] = copy_value [[T0]]
 // CHECK-NEXT: switch_enum [[T0_COPY]] : $Optional<@callee_guaranteed () -> ()>, case #Optional.some!enumelt.1: [[SOME:bb[0-9]+]], case #Optional.none!enumelt: [[NONE:bb[0-9]+]]
 //
-// CHECK: [[NONE]]:
-// CHECK:   br [[NOTHING_BLOCK_EXIT:bb[0-9]+]]
-
 //   If it does, project and load the value out of the implicitly unwrapped
 //   optional...
 
@@ -23,7 +20,7 @@
 // CHECK:      br [[EXIT:bb[0-9]+]](
 
 //   (first nothing block)
-// CHECK:    [[NOTHING_BLOCK_EXIT]]:
+// CHECK:    [[NONE]]:
 // CHECK-NEXT: enum $Optional<()>, #Optional.none!enumelt
 // CHECK-NEXT: br [[EXIT]]
 // CHECK: } // end sil function '$s8optional8testCallyyyycSgF'
@@ -44,9 +41,9 @@
 // CHECK-NEXT: [[READ:%.*]] = begin_access [read] [unknown] [[PBF]]
 //   Check whether 'f' holds a value.
 // CHECK: [[HASVALUE:%.*]] = select_enum_addr [[READ]]
-// CHECK-NEXT: cond_br [[HASVALUE]], bb2, bb1
+// CHECK-NEXT: cond_br [[HASVALUE]], bb1, bb3
 //   If so, pull out the value...
-// CHECK:    bb2:
+// CHECK:    bb1:
 // CHECK-NEXT: [[T1:%.*]] = unchecked_take_enum_data_addr [[READ]]
 // CHECK-NEXT: [[T0:%.*]] = load [copy] [[T1]]
 // CHECK-NEXT: end_access [[READ]]
@@ -56,9 +53,9 @@
 //   ...and coerce to T?
 // CHECK: inject_enum_addr [[PBX]] {{.*}}some
 // CHECK:     destroy_value [[T0]]
-// CHECK-NEXT: br bb3
+// CHECK-NEXT: br bb2
 //   Continuation block.
-// CHECK:    bb3
+// CHECK:    bb2
 // CHECK-NEXT: destroy_value [[X]]
 // CHECK-NEXT: destroy_value [[F]]
 // CHECK-NOT: destroy_value %0
@@ -66,9 +63,10 @@
 // CHECK-NEXT: return [[T0]] : $()
 
 //   Nothing block.
-// CHECK:    bb4:
+// CHECK:    bb3:
+// CHECK-NEXT: end_access [[READ]]
 // CHECK-NEXT: inject_enum_addr [[PBX]] {{.*}}none
-// CHECK-NEXT: br bb3
+// CHECK-NEXT: br bb2
 
 
 // <rdar://problem/15180622>
diff --git a/test/SILGen/pointer_conversion.swift b/test/SILGen/pointer_conversion.swift
index bfb5127..6c6c79f 100644
--- a/test/SILGen/pointer_conversion.swift
+++ b/test/SILGen/pointer_conversion.swift
@@ -310,9 +310,6 @@
   // CHECK:   [[RESULT1:%.*]] = apply [[SIDE1]]()
   // CHECK:   switch_enum [[COPY]] : $Optional<Array<Int>>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
   //
-  // CHECK: [[NONE_BB]]:
-  // CHECK:   br [[NONE_BB_TARGET:bb[0-9]+]]
-  //
   // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] :
   // CHECK:   [[CONVERT:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgumentyyXlSg_q_tSayxGs01_E0R_r0_lF
   // CHECK:   [[BORROW_SOME_VALUE:%.*]] = begin_borrow [[SOME_VALUE]]
@@ -329,7 +326,7 @@
   // CHECK:   apply [[TAKES]]([[OPTDEP]], [[RESULT1]])
   // CHECK:   destroy_value [[OWNER]]
   // CHECK-NOT:   destroy_value %0
-  // CHECK: [[NONE_BB_TARGET]]:
+  // CHECK: [[NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<UnsafePointer<Int>>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[CONT_BB]]([[NO_VALUE]] : $Optional<UnsafePointer<Int>>, [[NO_OWNER]] : $Optional<AnyObject>)
@@ -343,14 +340,9 @@
   // CHECK:   [[RESULT1:%.*]] = apply [[SIDE1]]()
   // CHECK:   switch_enum [[COPY]] : $Optional<Optional<Array<Int>>>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
   //
-  // CHECK: [[NONE_BB]]:
-  // CHECK:   br [[NONE_BB_TARGET:bb[0-9]+]]
-  //
   // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] :
   // CHECK:   switch_enum [[SOME_VALUE]] : $Optional<Array<Int>>, case #Optional.some!enumelt.1: [[SOME_SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[SOME_NONE_BB:bb[0-9]+]]
   //
-  // CHECK: [[SOME_NONE_BB]]:
-  // CHECK:   br [[SOME_NONE_BB2:bb[0-9]+]]
   // CHECK: [[SOME_SOME_BB]]([[SOME_SOME_VALUE:%.*]] :
   // CHECK:   [[CONVERT:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgumentyyXlSg_q_tSayxGs01_E0R_r0_lF
   // CHECK:   [[SOME_SOME_VALUE_BORROW:%.*]] = begin_borrow [[SOME_SOME_VALUE]]
@@ -371,11 +363,11 @@
   // CHECK:   apply [[TAKES]]([[OPTOPTDEP]], [[RESULT1]])
   // CHECK:   destroy_value [[OWNER]]
   // CHECK-NOT:   destroy_value %0
-  // CHECK: [[SOME_NONE_BB2]]:
+  // CHECK: [[SOME_NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<UnsafePointer<Int>>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[SOME_SOME_CONT_BB]]([[NO_VALUE]] : $Optional<UnsafePointer<Int>>, [[NO_OWNER]] : $Optional<AnyObject>)
-  // CHECK: [[NONE_BB_TARGET]]:
+  // CHECK: [[NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<Optional<UnsafePointer<Int>>>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[SOME_CONT_BB]]([[NO_VALUE]] : $Optional<Optional<UnsafePointer<Int>>>, [[NO_OWNER]] : $Optional<AnyObject>)
@@ -389,9 +381,6 @@
   // CHECK:   [[RESULT1:%.*]] = apply [[SIDE1]]()
   // CHECK:   switch_enum [[COPY]] : $Optional<String>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
   //
-  // CHECK: [[NONE_BB]]:
-  // CHECK:   br [[NONE_BB_TARGET:bb[0-9]+]]
-  //
   // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] :
   // CHECK:   [[CONVERT:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgumentyyXlSg_xtSSs01_F0RzlF
   // CHECK:   [[BORROWED_SOME_VALUE:%.*]] = begin_borrow [[SOME_VALUE]]
@@ -408,7 +397,7 @@
   // CHECK:   apply [[TAKES]]([[OPTDEP]], [[RESULT1]])
   // CHECK:   destroy_value [[OWNER]]
   // CHECK-NOT:   destroy_value %0
-  // CHECK: [[NONE_BB_TARGET]]:
+  // CHECK: [[NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<UnsafeRawPointer>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[CONT_BB]]([[NO_VALUE]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
@@ -423,13 +412,8 @@
   //   FIXME: this should really go somewhere that will make nil, not some(nil)
   // CHECK:   switch_enum [[COPY]] : $Optional<Optional<String>>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
   //
-  // CHECK: [[NONE_BB]]:
-  // CHECK:   br [[NONE_BB_TARGET:bb[0-9]+]]
-  //
   // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] :
   // CHECK:   switch_enum [[SOME_VALUE]] : $Optional<String>, case #Optional.some!enumelt.1: [[SOME_SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[SOME_NONE_BB:bb[0-9]+]]
-  // CHECK: [[SOME_NONE_BB]]:
-  // CHECK:   br [[SOME_NONE_BB2:bb[0-9]+]]
   // CHECK: [[SOME_SOME_BB]]([[SOME_SOME_VALUE:%.*]] :
   // CHECK:   [[CONVERT:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgumentyyXlSg_xtSSs01_F0RzlF
   // CHECK:   [[BORROWED_SOME_SOME_VALUE:%.*]] = begin_borrow [[SOME_SOME_VALUE]]
@@ -450,11 +434,11 @@
   // CHECK:   apply [[TAKES]]([[OPTOPTDEP]], [[RESULT1]])
   // CHECK:   destroy_value [[OWNER]]
   // CHECK-NOT:   destroy_value %0
-  // CHECK: [[SOME_NONE_BB2]]:
+  // CHECK: [[SOME_NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<UnsafeRawPointer>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[SOME_SOME_CONT_BB]]([[NO_VALUE]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
-  // CHECK: [[NONE_BB_TARGET]]:
+  // CHECK: [[NONE_BB]]:
   // CHECK:   [[NO_VALUE:%.*]] = enum $Optional<Optional<UnsafeRawPointer>>, #Optional.none
   // CHECK:   [[NO_OWNER:%.*]] = enum $Optional<AnyObject>, #Optional.none
   // CHECK:   br [[SOME_CONT_BB]]([[NO_VALUE]] : $Optional<Optional<UnsafeRawPointer>>, [[NO_OWNER]] : $Optional<AnyObject>)
diff --git a/test/SILGen/sil_locations.swift b/test/SILGen/sil_locations.swift
index 410c06c..cad8643 100644
--- a/test/SILGen/sil_locations.swift
+++ b/test/SILGen/sil_locations.swift
@@ -12,8 +12,10 @@
   // CHECK-LABEL: sil hidden @$s13sil_locations6ifexprSiyF
   // CHECK: apply {{.*}}, loc "{{.*}}":[[@LINE-5]]:6
   // CHECK: cond_br {{%.*}}, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]], loc "{{.*}}":[[@LINE-6]]:6
-  // CHECK: br [[FALSE_BB]], loc "{{.*}}":[[@LINE-5]]:3
-  // CHECK: return {{.*}}, loc "{{.*}}":[[@LINE-5]]:3, {{.*}}:return
+  // CHECK: [[TRUE_BB]]:
+  // CHECK: br [[CONT_BB:bb[0-9]+]], loc "{{.*}}":[[@LINE-6]]:3
+  // CHECK: [[CONT_BB]]:
+  // CHECK: return {{.*}}, loc "{{.*}}":[[@LINE-7]]:3, {{.*}}:return
 }
 
 func ifelseexpr() -> Int {
@@ -77,7 +79,7 @@
 func useTemplateTest() -> Int {
   return templateTest(5);
   // CHECK-LABEL: sil hidden @$s13sil_locations15useTemplateTestSiyF
-  // CHECK: function_ref @$sSi2{{[_0-9a-zA-Z]*}}fC :{{.*}}, loc "{{.*}}":78
+  // CHECK: function_ref @$sSi2{{[_0-9a-zA-Z]*}}fC :{{.*}}, loc "{{.*}}":[[@LINE-2]]
 }
 
 func foo(_ x: Int) -> Int {
diff --git a/test/SILGen/statements.swift b/test/SILGen/statements.swift
index 8a19193..5395056 100644
--- a/test/SILGen/statements.swift
+++ b/test/SILGen/statements.swift
@@ -270,18 +270,15 @@
   // CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
   // CHECK: switch_enum [[ARG_COPY]] : $Optional<C>, case #Optional.some!enumelt.1: [[TRUE:bb[0-9]+]], case #Optional.none!enumelt: [[FALSE:bb[0-9]+]]
 
-  // CHECK: [[FALSE]]:
-  // CHECK:   br [[AFTER_FALSE:bb[0-9]+]]
   if let x = c {
     // CHECK: [[TRUE]]({{.*}} : @owned $C):
     use(x)
-    // CHECK:   br [[CONT:bb[0-9]+]]
-    // CHECK: [[CONT]]:
+    // CHECK: apply
     // CHECK:   br [[EPILOG:bb[0-9]+]]
   } else {
-    // CHECK: [[AFTER_FALSE]]:
+    // CHECK: [[FALSE]]:
     // CHECK: apply
-    // CHECK: br [[EPILOG]]
+    // CHECK:   br [[EPILOG:bb[0-9]+]]
     foo()
     break label2
     foo() // expected-warning {{will never be executed}}
@@ -297,17 +294,12 @@
   // CHECK: [[ARG2_COPY:%.*]] = copy_value [[ARG2]]
   // CHECK: switch_enum [[ARG2_COPY]] : $Optional<C>, case #Optional.some!enumelt.1: [[TRUE:bb[0-9]+]], case #Optional.none!enumelt: [[FALSE:bb[0-9]+]]
 
-  // CHECK: [[FALSE]]:
-  // CHECK:   br [[COND2:bb[0-9]+]]
   if let x = c {
     // CHECK: [[TRUE]]({{.*}} : @owned $C):
     use(x)
-    // CHECK:   br [[TRUE_TRAMPOLINE:bb[0-9]+]]
-    //
-    // CHECK: [[TRUE_TRAMPOLINE]]:
     // CHECK:   br [[EPILOG_BB:bb[0-9]+]]
   } else if a {
-    // CHECK: [[COND2]]:
+    // CHECK: [[FALSE]]:
     // CHECK:   cond_br {{.*}}, [[TRUE2:bb[0-9]+]], [[FALSE2:bb[0-9]+]]
     //
     // CHECK: [[TRUE2]]:
@@ -333,7 +325,7 @@
   // CHECK: [[LOOP]]:
   // CHECK: function_ref @$sSb21_getBuiltinLogicValue{{[_0-9a-zA-Z]*}}F
   // CHECK-NEXT: apply
-  // CHECK-NEXT: cond_br {{.*}}, [[LOOPTRUE:bb[0-9]+]], [[OUT:bb[0-9]+]]
+  // CHECK-NEXT: cond_br {{.*}}, [[LOOPTRUE:bb[0-9]+]], [[EXIT:bb[0-9]+]]
   while a {
     if a {
       foo()
@@ -349,12 +341,15 @@
 
   // [[IFTRUE]]:
   // CHECK: function_ref statements.foo
-  // CHECK: br [[OUT]]
+  // CHECK: br [[OUT:bb[0-9]+]]
 
   // CHECK: [[IFFALSE]]:
   // CHECK: function_ref statements.foo
   // CHECK: br [[LOOP]]
 
+  // CHECK: [[EXIT]]:
+  // CHECK: br [[OUT]]
+
   // CHECK: [[OUT]]:
   // CHECK:   return
 }
@@ -475,10 +470,8 @@
 func defer_test2(_ cond : Bool) {
   // CHECK: [[C3:%.*]] = function_ref @{{.*}}callee3yyF
   // CHECK: apply [[C3]]
-  // CHECK: br [[LOOP:bb[0-9]+]]
   callee3()
   
-// CHECK: [[LOOP]]:
 // test the condition.
 // CHECK:  [[CONDTRUE:%.*]] = apply {{.*}}(%0)
 // CHECK: cond_br [[CONDTRUE]], [[BODY:bb[0-9]+]], [[EXIT:bb[0-9]+]]
@@ -489,13 +482,16 @@
 
   // CHECK: [[C1:%.*]] = function_ref @$s10statements11defer_test2yySbF6
   // CHECK: apply [[C1]]
-  // CHECK: br [[EXIT]]
+  // CHECK: br [[RETURN:bb[0-9]+]]
     defer { callee1() }
     callee2()
     break
   }
   
 // CHECK: [[EXIT]]:
+// CHECK: br [[RETURN]]
+
+// CHECK: [[RETURN]]:
 // CHECK: [[C3:%.*]] = function_ref @{{.*}}callee3yyF
 // CHECK: apply [[C3]]
 
@@ -587,18 +583,12 @@
 // CHECK-NEXT:   switch_enum [[ARG]] : $Optional<Int>, case #Optional.some!enumelt.1: [[SOME:bb[0-9]+]], case #Optional.none!enumelt: [[NONE:bb[0-9]+]]
 func testRequireOptional1(_ a : Int?) -> Int {
 
-  // CHECK: [[NONE]]:
-  // CHECK:   br [[ABORT:bb[0-9]+]]
-
   // CHECK: [[SOME]]([[PAYLOAD:%.*]] : @trivial $Int):
   // CHECK-NEXT:   debug_value [[PAYLOAD]] : $Int, let, name "t"
-  // CHECK-NEXT:   br [[EPILOG:bb[0-9]+]]
-  //
-  // CHECK: [[EPILOG]]:
   // CHECK-NEXT:   return [[PAYLOAD]] : $Int
   guard let t = a else { abort() }
 
-  // CHECK:  [[ABORT]]:
+  // CHECK: [[NONE]]:
   // CHECK-NEXT:    // function_ref statements.abort() -> Swift.Never
   // CHECK-NEXT:    [[FUNC_REF:%.*]] = function_ref @$s10statements5aborts5NeverOyF
   // CHECK-NEXT:    apply [[FUNC_REF]]() : $@convention(thin) () -> Never
@@ -614,20 +604,15 @@
 func testRequireOptional2(_ a : String?) -> String {
   guard let t = a else { abort() }
 
-  // CHECK: [[NONE_BB]]:
-  // CHECK-NEXT: br [[ABORT_BB:bb[0-9]+]]
-  
   // CHECK:  [[SOME_BB]]([[STR:%.*]] : @owned $String):
   // CHECK-NEXT:   debug_value [[STR]] : $String, let, name "t"
-  // CHECK-NEXT:   br [[CONT_BB:bb[0-9]+]]
-  // CHECK:  [[CONT_BB]]:
   // CHECK-NEXT:   [[BORROWED_STR:%.*]] = begin_borrow [[STR]]
   // CHECK-NEXT:   [[RETURN:%.*]] = copy_value [[BORROWED_STR]]
   // CHECK-NEXT:   end_borrow [[BORROWED_STR]]
   // CHECK-NEXT:   destroy_value [[STR]] : $String
   // CHECK-NEXT:   return [[RETURN]] : $String
 
-  // CHECK:        [[ABORT_BB]]:
+  // CHECK: [[NONE_BB]]:
   // CHECK-NEXT:   // function_ref statements.abort() -> Swift.Never
   // CHECK-NEXT:   [[ABORT_FUNC:%.*]] = function_ref @$s10statements5aborts5NeverOyF
   // CHECK-NEXT:   [[NEVER:%.*]] = apply [[ABORT_FUNC]]()
@@ -665,8 +650,6 @@
 
   // CHECK: bb{{.*}}([[PTR:%[0-9]+]] : @owned $DerivedClass):
   // CHECK-NEXT: debug_value [[PTR]] : $DerivedClass, let, name "result"
-  // CHECK-NEXT: br [[CONT_BB:bb[0-9]+]]
-  // CHECK: [[CONT_BB]]:
   // CHECK-NEXT: [[BORROWED_PTR:%.*]] = begin_borrow [[PTR]]
   // CHECK-NEXT: [[RESULT:%.*]] = copy_value [[BORROWED_PTR]]
   // CHECK-NEXT: end_borrow [[BORROWED_PTR]]
@@ -689,8 +672,6 @@
   // CHECK-NEXT:   ([[PAYLOAD_1:%.*]], [[PAYLOAD_2:%.*]]) = destructure_tuple [[PAYLOAD]]
   // CHECK-NEXT:   debug_value [[PAYLOAD_1]] : $Int, let, name "x"
   // CHECK-NEXT:   debug_value [[PAYLOAD_2]] : $Int, let, name "y"
-  // CHECK-NEXT:   br [[CONT_BB:bb[0-9]+]]
-  // CHECK: [[CONT_BB]]:
   // CHECK-NEXT:   return [[PAYLOAD_1]] : $Int
 }
 
diff --git a/test/SILGen/switch.swift b/test/SILGen/switch.swift
index b25814f..a6f8a93 100644
--- a/test/SILGen/switch.swift
+++ b/test/SILGen/switch.swift
@@ -31,10 +31,8 @@
   // CHECK:   function_ref @$s6switch3fooSiyF
   case _:
   // CHECK:   function_ref @$s6switch1ayyF
-  // CHECK:   br [[CONT:bb[0-9]+]]
     a()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s6switch1byyF
   b()
 }
@@ -60,7 +58,7 @@
   switch foo() {
   // CHECK:   function_ref @$s6switch3fooSiyF
   // CHECK:   function_ref @$s6switch6runcedSbyF
-  // CHECK:   cond_br {{%.*}}, [[CASE1:bb[0-9]+]], [[NO_CASE2:bb[0-9]+]]
+  // CHECK:   cond_br {{%.*}}, [[CASE1:bb[0-9]+]], [[CASE2:bb[0-9]+]]
 
   case _ where runced():
   // CHECK: [[CASE1]]:
@@ -68,8 +66,6 @@
   // CHECK:   br [[CONT:bb[0-9]+]]
     a()
 
-  // CHECK: [[NO_CASE2]]:
-  // CHECK:   br [[CASE2:bb[0-9]+]]
   case _:
   // CHECK: [[CASE2]]:
   // CHECK:   function_ref @$s6switch1byyF
@@ -88,10 +84,8 @@
   // CHECK:   function_ref @$s6switch3barSiyF
   case _:
   // CHECK:   function_ref @$s6switch1ayyF
-  // CHECK:   br [[CONT:bb[0-9]+]]
     a()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s6switch1byyF
   b()
 }
@@ -118,15 +112,11 @@
   // CHECK:   br [[CONT]]
     b()
 
-  // CHECK: [[NOT_CASE2]]:
-  // CHECK:   br [[CASE3:bb[0-9]+]]
   case _:
-  // CHECK: [[CASE3]]:
+  // CHECK: [[NOT_CASE2]]:
   // CHECK:   function_ref @$s6switch1cyyF
-  // CHECK:   br [[CONT]]
     c()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s6switch1dyyF
   d()
 }
@@ -161,16 +151,12 @@
   // CHECK:   br [[CONT:bb[0-9]+]]
     a()
 
-  // CHECK: [[NOT_CASE1]]:
-  // CHECK:   br [[CASE2:bb[0-9]+]]
   case (_, _):
-  // CHECK: [[CASE2]]:
+  // CHECK: [[NOT_CASE1]]:
   // CHECK:   function_ref @$s6switch1byyF
-  // CHECK:   br [[CONT]]
     b()
   }
   c()
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s6switch1cyyF
 }
 
@@ -269,15 +255,11 @@
   // CHECK:   br [[CONT]]
     b()
 
-  // CHECK: [[NOT_CASE2]]:
-  // CHECK:   br [[CASE3:bb[0-9]+]]
   case _:
-  // CHECK: [[CASE3]]:
+  // CHECK: [[NOT_CASE2]]:
   // CHECK:   function_ref @$s6switch1cyyF
-  // CHECK:   br [[CONT]]
     c()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s6switch1dyyF
   d()
 }
@@ -294,10 +276,8 @@
   // CHECK:   br [[CONT:bb[0-9]+]]
     a()
 
-  // CHECK: [[NOT_CASE1]]:
-  // CHECK:   br [[CASE2:bb[0-9]+]]
   case _:
-  // CHECK: [[CASE2]]:
+  // CHECK: [[NOT_CASE1]]:
   // CHECK:   function_ref @$s6switch1byyF
   // CHECK:   br [[CONT]]
     b()
@@ -457,7 +437,7 @@
   // CHECK-NEXT:   destroy_value [[CAST_D1_COPY]]
   // CHECK-NEXT:   end_borrow [[CAST_D1]]
   // CHECK-NEXT:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK-NEXT:   br [[NEXT_CASE:bb5]]
+  // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
   // CHECK: [[IS_NOT_D1]]([[CASTFAIL_D1:%.*]] : @guaranteed $B):
   // CHECK-NEXT:   end_borrow [[CASTFAIL_D1]]
@@ -479,9 +459,6 @@
 
   // CHECK: [[IS_NOT_D2]]([[CASTFAIL_D2:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[CASTFAIL_D2]]
-  // CHECK:   br [[NEXT_CASE:bb8]]
-
-  // CHECK: [[NEXT_CASE]]:
   // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
   // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
   case is E where funged():
@@ -502,7 +479,7 @@
   // CHECK-NEXT:   destroy_value [[CAST_E_COPY]]
   // CHECK-NEXT:   end_borrow
   // CHECK-NEXT:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK-NEXT:   br [[NEXT_CASE:bb13]]
+  // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
   // CHECK: [[IS_NOT_E]]([[NOTCAST_E:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOTCAST_E]]
@@ -524,9 +501,6 @@
 
   // CHECK: [[IS_NOT_C]]([[NOCAST_C:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_C]]
-  // CHECK:   br [[NEXT_CASE:bb16]]
-
-  // CHECK: [[NEXT_CASE]]:
   default:
   // CHECK:    destroy_value [[X_COPY]]
   // CHECK:    function_ref @$s6switch1eyyF
@@ -595,9 +569,6 @@
 
   // CHECK: [[IS_NOT_D2]]([[NOCAST_D2:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_D2]]
-  // CHECK:   br [[NEXT_CASE:bb8]]
-
-  // CHECK: [[NEXT_CASE]]:
   // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
   // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
   case let y as E where funged():
@@ -621,7 +592,7 @@
 
   // CHECK: [[NO_CASE3]]:
   // CHECK    destroy_value [[CAST_E_COPY]]
-  // CHECK:   br [[NEXT_CASE:bb13]]
+  // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
   // CHECK: [[IS_NOT_E]]([[NOCAST_E:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_E]]
@@ -647,9 +618,6 @@
 
   // CHECK: [[IS_NOT_C]]([[NOCAST_C:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_C]]
-  // CHECK:   br [[NEXT_CASE:bb16]]
-
-  // CHECK: [[NEXT_CASE]]:
   default:
   // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1eyyF
diff --git a/test/SILGen/switch_fallthrough.swift b/test/SILGen/switch_fallthrough.swift
index 73d1d7f..ed4e782 100644
--- a/test/SILGen/switch_fallthrough.swift
+++ b/test/SILGen/switch_fallthrough.swift
@@ -37,10 +37,8 @@
   case _:
   // CHECK: [[CASE3]]:
   // CHECK:   function_ref @$s18switch_fallthrough1cyyF
-  // CHECK:   br [[CONT:bb[0-9]+]]
     c()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s18switch_fallthrough1dyyF
   d()
 }
@@ -65,10 +63,8 @@
   case _:
   // CHECK: [[CASE3]]:
   // CHECK:   function_ref @$s18switch_fallthrough1cyyF
-  // CHECK:   br [[CONT:bb[0-9]+]]
     c()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s18switch_fallthrough1dyyF
   d()
 }
@@ -98,10 +94,8 @@
   case (_, _):
   // CHECK: [[CASE4]]:
   // CHECK:   function_ref @$s18switch_fallthrough1dyyF
-  // CHECK:   br [[CONT:bb[0-9]+]]
     d()
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s18switch_fallthrough1eyyF
   e()
 }
diff --git a/test/SILGen/switch_multiple_entry_address_only.swift b/test/SILGen/switch_multiple_entry_address_only.swift
index cca9c21..b9673c4 100644
--- a/test/SILGen/switch_multiple_entry_address_only.swift
+++ b/test/SILGen/switch_multiple_entry_address_only.swift
@@ -42,17 +42,14 @@
   // CHECK:      [[FN:%.*]] = function_ref @$s34switch_multiple_entry_address_only8takesAnyyyypF
   // CHECK-NEXT: apply [[FN]]([[X_PHI]]
   // CHECK-NEXT: destroy_addr [[X_PHI]]
-  // CHECK-NEXT: br bb6
+  // CHECK-NEXT: br bb5
 
   // CHECK:      bb4:
+  // CHECK-NEXT: destroy_addr [[E_COPY]]
+  // CHECK-NEXT: dealloc_stack [[E_COPY]]
   // CHECK-NEXT: br bb5
 
   // CHECK:      bb5:
-  // CHECK-NEXT: destroy_addr [[E_COPY]]
-  // CHECK-NEXT: dealloc_stack [[E_COPY]]
-  // CHECK-NEXT: br bb6
-
-  // CHECK:      bb6:
   // CHECK-NEXT: dealloc_stack [[X_PHI]]
   // CHECK-NEXT: tuple ()
   // CHECK-NEXT: return
@@ -106,17 +103,14 @@
   // CHECK-NEXT: destroy_addr [[ANY_STACK]]
   // CHECK-NEXT: dealloc_stack [[ANY_STACK]]
   // CHECK-NEXT: destroy_value [[ANY_BOX]]
-  // CHECK-NEXT: br bb6
+  // CHECK-NEXT: br bb5
 
   // CHECK:      bb4:
+  // CHECK-NEXT: destroy_addr [[E_COPY]]
+  // CHECK-NEXT: dealloc_stack [[E_COPY]]
   // CHECK-NEXT: br bb5
 
   // CHECK:      bb5:
-  // CHECK-NEXT: destroy_addr [[E_COPY]]
-  // CHECK-NEXT: dealloc_stack [[E_COPY]]
-  // CHECK-NEXT: br bb6
-
-  // CHECK:      bb6:
   // CHECK-NEXT: dealloc_stack [[X_PHI]]
   // CHECK-NEXT: tuple ()
   // CHECK-NEXT: return
@@ -163,17 +157,14 @@
   // CHECK:      [[FN2:%.*]] = function_ref @$s34switch_multiple_entry_address_only8takesAnyyyypF
   // CHECK-NEXT: apply [[FN2]]([[X_PHI]]
   // CHECK-NEXT: destroy_addr [[X_PHI]]
-  // CHECK-NEXT: br bb6
+  // CHECK-NEXT: br bb5
   
   // CHECK:      bb4:
+  // CHECK-NEXT: destroy_addr [[E_COPY]]
+  // CHECK-NEXT: dealloc_stack [[E_COPY]]
   // CHECK-NEXT: br bb5
   
   // CHECK:      bb5:
-  // CHECK-NEXT: destroy_addr [[E_COPY]]
-  // CHECK-NEXT: dealloc_stack [[E_COPY]]
-  // CHECK-NEXT: br bb6
-  
-  // CHECK:      bb6:
   // CHECK-NEXT: dealloc_stack [[X_PHI]]
   // CHECK-NEXT: tuple ()
   // CHECK-NEXT: return
diff --git a/test/SILGen/switch_objc.swift b/test/SILGen/switch_objc.swift
index 77e323c..f78f0e4 100644
--- a/test/SILGen/switch_objc.swift
+++ b/test/SILGen/switch_objc.swift
@@ -20,9 +20,7 @@
     return true
 
   // CHECK: [[NOT_CASE2]]:
-  // CHECK:   br [[RET_FALSE:bb[0-9]+]]
   default:
-  // CHECK: [[RET_FALSE]]:
   // CHECK:   function_ref @$sSb2{{[_0-9a-zA-Z]*}}fC
     return false
   }
diff --git a/test/SILGen/switch_var.swift b/test/SILGen/switch_var.swift
index c2d9477..76531ff 100644
--- a/test/SILGen/switch_var.swift
+++ b/test/SILGen/switch_var.swift
@@ -54,10 +54,8 @@
   // CHECK:   load [trivial] [[READ]]
   // CHECK:   function_ref @$s10switch_var1a1xySi_tF
   // CHECK:   destroy_value [[XADDR]]
-  // CHECK:   br [[CONT:bb[0-9]+]]
     a(x: x)
   }
-  // CHECK: [[CONT]]:
   // CHECK:   function_ref @$s10switch_var1byyF
   b()
 }
@@ -96,10 +94,8 @@
   // CHECK:   destroy_value [[YADDR]]
   // CHECK:   br [[CONT]]
     b(x: y)
-  // CHECK: [[NO_CASE2]]:
-  // CHECK:   br [[CASE3:bb[0-9]+]]
   case var z:
-  // CHECK: [[CASE3]]:
+  // CHECK: [[NO_CASE2]]:
   // CHECK:   [[ZADDR:%.*]] = alloc_box ${ var Int }
   // CHECK:   [[Z:%.*]] = project_box [[ZADDR]]
   // CHECK:   [[READ:%.*]] = begin_access [read] [unknown] [[Z]]
@@ -133,10 +129,8 @@
   // CHECK:   destroy_value [[XADDR]]
   // CHECK:   br [[CONT:bb[0-9]+]]
     aa(x: x)
-  // CHECK: [[NO_CASE1]]:
-  // CHECK:   br [[NO_CASE1_TARGET:bb[0-9]+]]
 
-  // CHECK: [[NO_CASE1_TARGET]]:
+  // CHECK: [[NO_CASE1]]:
   // CHECK:   [[YADDR:%.*]] = alloc_box ${ var Int }
   // CHECK:   [[Y:%.*]] = project_box [[YADDR]]
   // CHECK:   [[ZADDR:%.*]] = alloc_box ${ var Int }
@@ -174,9 +168,7 @@
     bb(x: w)
   // CHECK: [[NO_CASE3]]:
   // CHECK:   destroy_value [[WADDR]]
-  // CHECK:   br [[CASE4:bb[0-9]+]]
   case var v:
-  // CHECK: [[CASE4]]:
   // CHECK:   [[VADDR:%.*]] = alloc_box ${ var (Int, Int) } 
   // CHECK:   [[V:%.*]] = project_box [[VADDR]]
   // CHECK:   [[READ:%.*]] = begin_access [read] [unknown] [[V]]
@@ -289,9 +281,7 @@
 
   // CHECK: [[DFLT_NO_CASE3]]:
   // CHECK:   destroy_value [[ZADDR]]
-  // CHECK:   br [[CASE4:bb[0-9]+]]
   case (_, var w):
-  // CHECK: [[CASE4]]:
   // CHECK:   [[PAIR_0:%.*]] = tuple_element_addr [[PAIR]] : $*(P, Int), 0
   // CHECK:   [[WADDR:%.*]] = alloc_box ${ var Int }
   // CHECK:   [[W:%.*]] = project_box [[WADDR]]
@@ -343,10 +333,8 @@
   // CHECK:   br [[CASE4:bb[0-9]+]]
   case _:
   // CHECK: [[CASE4]]:
-  // CHECK:   br [[CONT]]
     d()
   }
-  // CHECK: [[CONT]]:
   e()
 }
 
@@ -417,8 +405,6 @@
     a(x: x)
   // CHECK: [[NO_CASE1]]:
   // CHECK:   destroy_value [[VAL_COPY]]
-  // CHECK:   br [[TRY_CASE2:bb[0-9]+]]
-  // CHECK: [[TRY_CASE2]]:
   // CHECK:   [[BORROWED_VAL_2:%.*]] = begin_borrow [[VAL]]
   // CHECK:   [[VAL_COPY_2:%.*]] = copy_value [[BORROWED_VAL_2]]
   // CHECK:   function_ref @$s10switch_var6fungedSbyF
@@ -434,9 +420,6 @@
     b(x: y)
   // CHECK: [[NO_CASE2]]:
   // CHECK:   destroy_value [[VAL_COPY_2]]
-  // CHECK:   br [[NEXT_CASE:bb6]]
-
-  // CHECK: [[NEXT_CASE]]:
   // CHECK:   [[BORROWED_VAL_3:%.*]] = begin_borrow [[VAL]]
   // CHECK:   [[VAL_COPY_3:%.*]] = copy_value [[BORROWED_VAL_3]]
   // CHECK:   function_ref @$s10switch_var4barsSSyF
@@ -454,9 +437,7 @@
     c()
   // CHECK: [[NO_CASE3]]:
   // CHECK:   destroy_value [[VAL_COPY_3]]
-  // CHECK:   br [[NEXT_CASE:bb9+]]
 
-  // CHECK: [[NEXT_CASE]]:
   case _:
     // CHECK:   destroy_value [[VAL]]
     // CHECK:   function_ref @$s10switch_var1dyyF
@@ -496,9 +477,7 @@
 
   // CHECK: [[NOCASE1]]:
   // CHECK:   destroy_value [[BOX]]
-  // CHECK:   br [[NEXT_PATTERN:bb[0-9]+]]
 
-  // CHECK: [[NEXT_PATTERN]]:
   // CHECK:   [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
   // CHECK:   [[VAL_COPY:%.*]] = copy_value [[BORROWED_VAL]]
   // CHECK:   cond_br {{.*}}, [[CASE2:bb[0-9]+]], [[NOCASE2:bb[0-9]+]]
@@ -516,9 +495,7 @@
 
   // CHECK: [[NOCASE2]]:
   // CHECK:   destroy_value [[VAL_COPY]]
-  // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
-  // CHECK: [[NEXT_CASE]]
   // CHECK:   [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
   // CHECK:   [[VAL_COPY:%.*]] = copy_value [[BORROWED_VAL]]
   // CHECK:   [[BORROWED_VAL_COPY:%.*]] = begin_borrow [[VAL_COPY]]
@@ -536,9 +513,7 @@
 
   // CHECK: [[NOCASE3]]:
   // CHECK:   destroy_value [[VAL_COPY]]
-  // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
-  // CHECK: [[NEXT_CASE]]:
   // CHECK:   destroy_value [[VAL]]
   // CHECK:   [[D_FUNC:%.*]] = function_ref @$s10switch_var1dyyF : $@convention(thin) () -> ()
   // CHECK:   apply [[D_FUNC]]()
diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift
index 302d0fa..eeb8218 100644
--- a/test/SILOptimizer/access_marker_verify.swift
+++ b/test/SILOptimizer/access_marker_verify.swift
@@ -480,23 +480,9 @@
 // ----- access the temporary array result of the getter
 // CHECK:   [[TEMPACCESS:%.*]] = begin_access [modify] [unsafe] [[TEMP]]
 // CHECK:   [[HAS_VALUE:%.*]] = select_enum_addr [[TEMPACCESS]]
-// CHECK:   cond_br [[HAS_VALUE]], bb2, bb1
+// CHECK:   cond_br [[HAS_VALUE]], [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
 //
-// CHECK: bb1:
-// CHECK:   [[TEMPARRAY:%.*]] = load [copy] [[TEMPACCESS]]
-// CHECK:   [[WRITEBACK:%.*]] = alloc_stack $Optional<Array<Int>>
-// CHECK-NOT: begin_access
-// CHECK:   store [[TEMPARRAY]] to [init] [[WRITEBACK]]
-// CHECK:   [[TEMP3:%.*]] = alloc_stack $Int
-// CHECK-NOT: begin_access
-// CHECK:   store %{{.*}} to [trivial] [[TEMP3]] : $*Int
-// Call MyDict.subscript.setter
-// CHECK:   apply %{{.*}}<Int, [Int]>([[WRITEBACK]], [[TEMP3]], [[BOXACCESS]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in Optional<τ_0_1>, @in τ_0_0, @inout MyDict<τ_0_0, τ_0_1>) -> ()
-// CHECK:   end_access [[TEMPACCESS]] : $*Optional<Array<Int>>
-// CHECK:   end_access [[BOXACCESS]] : $*MyDict<Int, Array<Int>>
-// CHECK:   br
-//
-// CHECK: bb2:
+// CHECK: [[TRUEBB]]:
 // CHECK-NOT: begin_access
 // CHECK:   [[TEMPARRAYADR:%.*]] = unchecked_take_enum_data_addr [[TEMPACCESS]] : $*Optional<Array<Int>>, #Optional.some!enumelt.1
 // ----- call Array.append
@@ -511,6 +497,22 @@
 // CHECK:   store %{{.*}} to [trivial]
 // ----- call MyDict.subscript.setter
 // CHECK: apply %{{.*}}<Int, [Int]>([[ARRAYCOPY]], %{{.*}}, [[BOXACCESS]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in Optional<τ_0_1>, @in τ_0_0, @inout MyDict<τ_0_0, τ_0_1>) -> ()
+// CHECK:   br [[RETBB:bb[0-9]+]]
+//
+// CHECK: [[FALSEBB]]:
+// CHECK:   [[TEMPARRAY:%.*]] = load [copy] [[TEMPACCESS]]
+// CHECK:   [[WRITEBACK:%.*]] = alloc_stack $Optional<Array<Int>>
+// CHECK-NOT: begin_access
+// CHECK:   store [[TEMPARRAY]] to [init] [[WRITEBACK]]
+// CHECK:   [[TEMP3:%.*]] = alloc_stack $Int
+// CHECK-NOT: begin_access
+// CHECK:   store %{{.*}} to [trivial] [[TEMP3]] : $*Int
+// Call MyDict.subscript.setter
+// CHECK:   apply %{{.*}}<Int, [Int]>([[WRITEBACK]], [[TEMP3]], [[BOXACCESS]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in Optional<τ_0_1>, @in τ_0_0, @inout MyDict<τ_0_0, τ_0_1>) -> ()
+// CHECK:   end_access [[TEMPACCESS]] : $*Optional<Array<Int>>
+// CHECK:   end_access [[BOXACCESS]] : $*MyDict<Int, Array<Int>>
+// CHECK:   br [[RETBB]]
+//
 // CHECK-LABEL: } // end sil function '$s20access_marker_verify0A13OptionalArrayyyAA6MyDictVySiSaySiGGF'
 
 // --- Optional map.
diff --git a/test/SILOptimizer/definite-init-convert-to-escape.swift b/test/SILOptimizer/definite-init-convert-to-escape.swift
index 8ae073e..9953a1c 100644
--- a/test/SILOptimizer/definite-init-convert-to-escape.swift
+++ b/test/SILOptimizer/definite-init-convert-to-escape.swift
@@ -10,16 +10,16 @@
 // CHECK: bb0
 // CHECK:  retain_value %0
 // CHECK:  retain_value %0
-// CHECK: bb2
+// CHECK: bb1
 // CHECK:  convert_escape_to_noescape %
 // CHECK:  strong_release
+// CHECK: bb5
+// CHECK:  retain_value %1
+// CHECK:  retain_value %1
 // CHECK: bb6
-// CHECK:  retain_value %1
-// CHECK:  retain_value %1
-// CHECK: bb8
 // CHECK:  convert_escape_to_noescape %
 // CHECK:  strong_release
-// CHECK: bb12
+// CHECK: bb10
 // CHECK:  [[F:%.*]] = function_ref @noescapeBlock3
 // CHECK:  apply [[F]]
 // CHECK:  release_value {{.*}} : $Optional<NSString>
@@ -42,11 +42,11 @@
 // CHECK:  [[V0:%.*]] = function_ref @_returnOptionalEscape
 // CHECK:  [[V1:%.*]] = apply [[V0]]
 // CHECK:  retain_value [[V1]]
-// CHECK:  switch_enum {{.*}}bb2
-// CHECK: bb2([[V2:%.*]]: $@callee_guaranteed () -> ()):
+// CHECK:  switch_enum {{.*}}bb1
+// CHECK: bb1([[V2:%.*]]: $@callee_guaranteed () -> ()):
 // CHECK:  convert_escape_to_noescape %
 // CHECK:  strong_release [[V2]]
-// CHECK: bb6({{.*}} : $Optional<@convention(block) @noescape () -> ()>)
+// CHECK: bb5({{.*}} : $Optional<@convention(block) @noescape () -> ()>)
 // CHECK:  [[F:%.*]] = function_ref @noescapeBlock
 // CHECK:  apply [[F]]({{.*}})
 // CHECK:  release_value [[V1]] : $Optional<@callee_guaranteed () -> ()>
@@ -59,15 +59,15 @@
 // NOPEEPHOLE:  store [[NONE]] to [[SLOT]]
 // NOPEEPHOLE:  [[V0:%.*]] = function_ref @_returnOptionalEscape
 // NOPEEPHOLE:  [[V1:%.*]] = apply [[V0]]
-// NOPEEPHOLE:  switch_enum {{.*}}bb2
-// NOPEEPHOLE: bb2([[V2:%.*]]: $@callee_guaranteed () -> ()):
+// NOPEEPHOLE:  switch_enum {{.*}}bb1
+// NOPEEPHOLE: bb1([[V2:%.*]]: $@callee_guaranteed () -> ()):
 // NOPEEPHOLE:  destroy_addr [[SLOT]]
 // NOPEEPHOLE:  [[SOME:%.*]] = enum $Optional<@callee_guaranteed () -> ()>, #Optional.some!enumelt.1, [[V2]]
 // NOPEEPHOLE:  store [[SOME]] to [[SLOT]]
 // NOPEEPHOLE:  convert_escape_to_noescape %
 // NOPEEPHOLE-NOT:  strong_release
 // NOPEEPHOLE:  br
-// NOPEEPHOLE: bb6({{.*}} : $Optional<@convention(block) @noescape () -> ()>)
+// NOPEEPHOLE: bb5({{.*}} : $Optional<@convention(block) @noescape () -> ()>)
 // NOPEEPHOLE:  [[F:%.*]] = function_ref @noescapeBlock
 // NOPEEPHOLE:  apply [[F]]({{.*}})
 // NOPEEPHOLE:  destroy_addr [[SLOT]]
diff --git a/test/SILOptimizer/definite_init_diagnostics.swift b/test/SILOptimizer/definite_init_diagnostics.swift
index 1c1e287..2eed511 100644
--- a/test/SILOptimizer/definite_init_diagnostics.swift
+++ b/test/SILOptimizer/definite_init_diagnostics.swift
@@ -561,10 +561,10 @@
 
   switch b {
   default:
-    PerpetualMotion().start()
+    PerpetualMotion().start() // expected-note {{a call to a never-returning function}}
   }
 
-  return a
+  return a // expected-warning {{will never be executed}}
 }
 
 func testNoReturn4(_ b : Bool) -> Any {
@@ -572,10 +572,10 @@
 
   switch b {
   default:
-    PerpetualMotion.stop()
+    PerpetualMotion.stop() // expected-note {{a call to a never-returning function}}
   }
 
-  return a
+  return a // expected-warning {{will never be executed}}
 }
 
 
diff --git a/test/SILOptimizer/definite_init_failable_initializers_objc.swift b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
index f926c98..04abe6b 100644
--- a/test/SILOptimizer/definite_init_failable_initializers_objc.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
@@ -39,9 +39,12 @@
     // CHECK-NEXT: cond_br [[COND]], bb1, bb2
 
   // CHECK: bb1:
-    // CHECK-NEXT: br bb3
+    // CHECK-NEXT: br bb4
 
   // CHECK: bb2:
+    // ChECK-NEXT br bb3
+
+  // CHECK: bb3:
     // CHECK-NEXT: [[SUPER:%.*]] = upcast %2 : $Cat to $FakeNSObject
     // CHECK-NEXT: [[SUB:%.*]] = unchecked_ref_cast [[SUPER]] : $FakeNSObject to $Cat
     // CHECK-NEXT: [[SUPER_FN:%.*]] = objc_super_method [[SUB]] : $Cat, #FakeNSObject.init!initializer.1.foreign : (FakeNSObject.Type) -> () -> FakeNSObject, $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
@@ -53,18 +56,18 @@
     // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.some!enumelt.1, [[NEW_SELF]] : $Cat
     // CHECK-NEXT: destroy_addr [[SELF_BOX]]
     // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
-    // CHECK-NEXT: br bb4([[RESULT]] : $Optional<Cat>)
+    // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
 
-  // CHECK: bb3:
+  // CHECK: bb4:
     // CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
     // CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
     // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
     // CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[METATYPE]] : $@thick Cat.Type
     // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
     // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.none!enumelt
-    // CHECK-NEXT: br bb4([[RESULT]] : $Optional<Cat>)
+    // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
 
-  // CHECK: bb4([[RESULT:%.*]] : $Optional<Cat>):
+  // CHECK: bb5([[RESULT:%.*]] : $Optional<Cat>):
     // CHECK-NEXT: return [[RESULT]] : $Optional<Cat>
 
   init?(n: Int, after: Bool) {
diff --git a/test/SILOptimizer/definite_init_value_types.swift b/test/SILOptimizer/definite_init_value_types.swift
index ac8d8af..71bd780 100644
--- a/test/SILOptimizer/definite_init_value_types.swift
+++ b/test/SILOptimizer/definite_init_value_types.swift
@@ -33,10 +33,8 @@
   // CHECK-NEXT:   [[INIT_STATE:%.*]] = integer_literal $Builtin.Int1, 0
   // CHECK-NEXT:   store [[INIT_STATE]] to [[STATE]]
   // CHECK:        [[BOOL:%.*]] = struct_extract %0 : $Bool, #Bool._value
-  // CHECK-NEXT:   cond_br [[BOOL]], bb2, bb1
+  // CHECK-NEXT:   cond_br [[BOOL]], bb1, bb2
   // CHECK:      bb1:
-  // CHECK-NEXT:   br bb3
-  // CHECK:      bb2:
   // CHECK-NEXT:   [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type
   // CHECK-NEXT:   [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.b!enumelt
   // CHECK-NEXT:   [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]]
@@ -45,6 +43,8 @@
   // CHECK-NEXT:   store [[NEW_SELF]] to [[SELF_ACCESS]]
   // CHECK-NEXT:   end_access [[SELF_ACCESS]]
   // CHECK-NEXT:   br bb3
+  // CHECK:      bb2:
+  // CHECK-NEXT:   br bb3
   // CHECK:      bb3:
   // CHECK-NEXT:   [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type
   // CHECK-NEXT:   [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.c!enumelt
diff --git a/test/SILOptimizer/pointer_conversion_linux.swift b/test/SILOptimizer/pointer_conversion_linux.swift
index b307d44..94a1080 100644
--- a/test/SILOptimizer/pointer_conversion_linux.swift
+++ b/test/SILOptimizer/pointer_conversion_linux.swift
@@ -26,17 +26,12 @@
   // CHECK: bb0:
   // CHECK:   switch_enum {{.*}}, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 
-  // CHECK: [[NONE_BB]]:
-  // CHECK-NEXT: [[NO_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.none!enumelt
-  // CHECK-NEXT: [[NO_OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.none!enumelt
-  // CHECK-NEXT: br [[CALL_BRANCH:bb[0-9]+]]([[NO_POINTER]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
-
   // CHECK: [[SOME_BB]](
   // CHECK: [[OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.some!enumelt.1,
   // CHECK-NEXT: [[POINTER:%.+]] = struct $UnsafeRawPointer (
   // CHECK-NEXT: [[DEP_POINTER:%.+]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] : $Optional<AnyObject>
   // CHECK-NEXT: [[OPT_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.some!enumelt.1, [[DEP_POINTER]]
-  // CHECK-NEXT: br [[CALL_BRANCH]]([[OPT_POINTER]] : $Optional<UnsafeRawPointer>, [[OWNER]] : $Optional<AnyObject>)
+  // CHECK-NEXT: br [[CALL_BRANCH:bb[0-9]+]]([[OPT_POINTER]] : $Optional<UnsafeRawPointer>, [[OWNER]] : $Optional<AnyObject>)
 
   // CHECK: [[CALL_BRANCH]]([[OPT_POINTER:%.+]] : $Optional<UnsafeRawPointer>, [[OWNER:%.+]] : $Optional<AnyObject>):
   // CHECK-NOT: release
@@ -49,4 +44,9 @@
   // CHECK-NEXT: [[EMPTY:%.+]] = tuple ()
   // CHECK-NEXT: return [[EMPTY]]
 
+  // CHECK: [[NONE_BB]]:
+  // CHECK-NEXT: [[NO_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.none!enumelt
+  // CHECK-NEXT: [[NO_OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.none!enumelt
+  // CHECK-NEXT: br [[CALL_BRANCH]]([[NO_POINTER]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
+
 } // CHECK: end sil function '$s18pointer_conversion17testOptionalArrayyyF'
diff --git a/test/SILOptimizer/pointer_conversion_objc.swift b/test/SILOptimizer/pointer_conversion_objc.swift
index 8c36d9c..9787788 100644
--- a/test/SILOptimizer/pointer_conversion_objc.swift
+++ b/test/SILOptimizer/pointer_conversion_objc.swift
@@ -28,11 +28,6 @@
   // CHECK: bb0:
   // CHECK:   switch_enum {{.*}}, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
 
-  // CHECK: [[NONE_BB]]:
-  // CHECK-NEXT: [[NO_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.none!enumelt
-  // CHECK-NEXT: [[NO_OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.none!enumelt
-  // CHECK-NEXT: br [[CALL_BRANCH:bb[0-9]+]]([[NO_POINTER]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
-
   // CHECK: [[SOME_BB]](
   // CHECK:   cond_br {{%.*}}, {{bb[0-9]+}}, [[CHECK_BB:bb[0-9]+]]
 
@@ -44,7 +39,7 @@
   // CHECK-NEXT: [[POINTER:%.+]] = struct $UnsafeRawPointer (
   // CHECK-NEXT: [[DEP_POINTER:%.+]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] : $Optional<AnyObject>
   // CHECK-NEXT: [[OPT_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.some!enumelt.1, [[DEP_POINTER]]
-  // CHECK-NEXT: br [[CALL_BRANCH]]([[OPT_POINTER]] : $Optional<UnsafeRawPointer>, [[OWNER]] : $Optional<AnyObject>)
+  // CHECK-NEXT: br [[CALL_BRANCH:bb[0-9]+]]([[OPT_POINTER]] : $Optional<UnsafeRawPointer>, [[OWNER]] : $Optional<AnyObject>)
 
   // CHECK: [[CALL_BRANCH]]([[OPT_POINTER:%.+]] : $Optional<UnsafeRawPointer>, [[OWNER:%.+]] : $Optional<AnyObject>):
   // CHECK-NOT: release
@@ -57,4 +52,9 @@
   // CHECK-NEXT: [[EMPTY:%.+]] = tuple ()
   // CHECK-NEXT: return [[EMPTY]]
 
+  // CHECK: [[NONE_BB]]:
+  // CHECK-NEXT: [[NO_POINTER:%.+]] = enum $Optional<UnsafeRawPointer>, #Optional.none!enumelt
+  // CHECK-NEXT: [[NO_OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.none!enumelt
+  // CHECK-NEXT: br [[CALL_BRANCH]]([[NO_POINTER]] : $Optional<UnsafeRawPointer>, [[NO_OWNER]] : $Optional<AnyObject>)
+
 } // CHECK-LABEL: end sil function '$s18pointer_conversion17testOptionalArrayyyF'
diff --git a/test/SILOptimizer/switch_enum_objc.swift b/test/SILOptimizer/switch_enum_objc.swift
index 2582a1c..9829e9a 100644
--- a/test/SILOptimizer/switch_enum_objc.swift
+++ b/test/SILOptimizer/switch_enum_objc.swift
@@ -184,11 +184,11 @@
 
 // CHECK-LABEL: sil hidden @$s16switch_enum_objc19testImperativeHeadsyySo4CoinVF
 func testImperativeHeads(_ coin: Coin) {
-  // CHECK: switch_enum %0 : $Coin, case #Coin.heads!enumelt: bb2, default bb1
+  // CHECK: switch_enum %0 : $Coin, case #Coin.heads!enumelt: bb1, default bb2
   // CHECK: bb1:
-  // CHECK: function_ref @$s16switch_enum_objc7action1
-  // CHECK: bb2:
   // CHECK: function_ref @$s16switch_enum_objc7action0
+  // CHECK: bb2:
+  // CHECK: function_ref @$s16switch_enum_objc7action1
   if case .heads = coin {
     action0()
   } else {
@@ -198,11 +198,11 @@
 
 // CHECK-LABEL: sil hidden @$s16switch_enum_objc19testImperativeTailsyySo4CoinVF
 func testImperativeTails(_ coin: Coin) {
-  // CHECK: switch_enum %0 : $Coin, case #Coin.tails!enumelt: bb2, default bb1
+  // CHECK: switch_enum %0 : $Coin, case #Coin.tails!enumelt: bb1, default bb2
   // CHECK: bb1:
-  // CHECK: function_ref @$s16switch_enum_objc7action1
-  // CHECK: bb2:
   // CHECK: function_ref @$s16switch_enum_objc7action0
+  // CHECK: bb2:
+  // CHECK: function_ref @$s16switch_enum_objc7action1
   if case .tails = coin {
     action0()
   } else {
diff --git a/test/SILOptimizer/switch_enum_resilient.swift b/test/SILOptimizer/switch_enum_resilient.swift
index 5311165..55a3edf 100644
--- a/test/SILOptimizer/switch_enum_resilient.swift
+++ b/test/SILOptimizer/switch_enum_resilient.swift
@@ -210,7 +210,7 @@
 
 // CHECK-NOINLINE-LABEL: sil{{.*}} @$s21switch_enum_resilient19testImperativeHeadsyyAA4CoinOF
 public func testImperativeHeads(_ coin: Coin) {
-  // CHECK-NOINLINE: switch_enum{{_addr %.+ : [$][*]Coin| %0 : [$]Coin}}, case #Coin.heads!enumelt: bb2, case #Coin.tails!enumelt: bb1 //
+  // CHECK-NOINLINE: switch_enum{{_addr %.+ : [$][*]Coin| %0 : [$]Coin}}, case #Coin.heads!enumelt: bb1, case #Coin.tails!enumelt: bb2 //
   if case .heads = coin {
     action0()
   } else {
@@ -220,7 +220,7 @@
 
 // CHECK-NOINLINE-LABEL: sil{{.*}} @$s21switch_enum_resilient19testImperativeTailsyyAA4CoinOF
 public func testImperativeTails(_ coin: Coin) {
-  // CHECK-NOINLINE: switch_enum{{_addr %.+ : [$][*]Coin| %0 : [$]Coin}}, case #Coin.tails!enumelt: bb2, case #Coin.heads!enumelt: bb1 //
+  // CHECK-NOINLINE: switch_enum{{_addr %.+ : [$][*]Coin| %0 : [$]Coin}}, case #Coin.tails!enumelt: bb1, case #Coin.heads!enumelt: bb2 //
   if case .tails = coin {
     action0()
   } else {
@@ -233,7 +233,7 @@
   // CHECK-FRAGILE-NOINLINE: [[FIVE:%.+]] = integer_literal ${{.+}}, 5000
   // CHECK-FRAGILE-NOINLINE: [[NINE:%.+]] = integer_literal ${{.+}}, 9001
   // CHECK-FRAGILE-NOINLINE: = select_enum %0 : $Coin, case #Coin.heads!enumelt: [[FIVE]], case #Coin.tails!enumelt: [[NINE]] :
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb2, case #Coin.tails!enumelt: bb1
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb1, case #Coin.tails!enumelt: bb2
   if case .heads = coin {
     return 5000
   } else {
@@ -246,7 +246,7 @@
   // CHECK-FRAGILE-NOINLINE: [[FIVE:%.+]] = integer_literal ${{.+}}, 5000
   // CHECK-FRAGILE-NOINLINE: [[NINE:%.+]] = integer_literal ${{.+}}, 9001
   // CHECK-FRAGILE-NOINLINE: = select_enum %0 : $Coin, case #Coin.tails!enumelt: [[FIVE]], case #Coin.heads!enumelt: [[NINE]] :
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb2, case #Coin.heads!enumelt: bb1
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb1, case #Coin.heads!enumelt: bb2
   if case .tails = coin {
     return 5000
   } else {
@@ -306,7 +306,7 @@
   // CHECK-FRAGILE: [[FIVE:%.+]] = integer_literal ${{.+}}, 5000
   // CHECK-FRAGILE: [[NINE:%.+]] = integer_literal ${{.+}}, 9001
   // CHECK-FRAGILE: = select_enum %0 : $Coin, case #Coin.heads!enumelt: [[FIVE]], case #Coin.tails!enumelt: [[NINE]] :
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb2, case #Coin.tails!enumelt: bb1 //
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb{{[0-9]+}}, case #Coin.tails!enumelt: bb{{[0-9]+}} //
   // CHECK-RESILIENT-INLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb2, default bb1
   if case .heads = coin {
     return 5000
@@ -320,7 +320,7 @@
   // CHECK-FRAGILE: [[FIVE:%.+]] = integer_literal ${{.+}}, 5000
   // CHECK-FRAGILE: [[NINE:%.+]] = integer_literal ${{.+}}, 9001
   // CHECK-FRAGILE: = select_enum %0 : $Coin, case #Coin.tails!enumelt: [[FIVE]], case #Coin.heads!enumelt: [[NINE]] :
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb2, case #Coin.heads!enumelt: bb1 //
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb{{[0-9]+}}, case #Coin.heads!enumelt: bb{{[0-9]+}} //
   // CHECK-RESILIENT-INLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb2, default bb1
   if case .tails = coin {
     return 5000
@@ -332,8 +332,8 @@
 
 // CHECK-ALL-LABEL: sil{{.*}} @$s21switch_enum_resilient21inlineImperativeHeadsyyAA4CoinOF
 @inlinable public func inlineImperativeHeads(_ coin: Coin) {
-  // CHECK-FRAGILE: switch_enum %0 : $Coin, case #Coin.heads!enumelt: bb2, case #Coin.tails!enumelt: bb1 //
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb2, case #Coin.tails!enumelt: bb1 //
+  // CHECK-FRAGILE: switch_enum %0 : $Coin, case #Coin.heads!enumelt: bb{{[0-9]+}}, case #Coin.tails!enumelt: bb{{[0-9]+}} //
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb{{[0-9]+}}, case #Coin.tails!enumelt: bb{{[0-9]+}} //
   // CHECK-RESILIENT-INLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.heads!enumelt: bb2, default bb1
   if case .heads = coin {
     action0()
@@ -344,8 +344,8 @@
 
 // CHECK-ALL-LABEL: sil{{.*}} @$s21switch_enum_resilient21inlineImperativeTailsyyAA4CoinOF
 @inlinable public func inlineImperativeTails(_ coin: Coin) {
-  // CHECK-FRAGILE: switch_enum %0 : $Coin, case #Coin.tails!enumelt: bb2, case #Coin.heads!enumelt: bb1 //
-  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb2, case #Coin.heads!enumelt: bb1 //
+  // CHECK-FRAGILE: switch_enum %0 : $Coin, case #Coin.tails!enumelt: bb{{[0-9]+}}, case #Coin.heads!enumelt: bb{{[0-9]+}} //
+  // CHECK-RESILIENT-NOINLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb{{[0-9]+}}, case #Coin.heads!enumelt: bb{{[0-9]+}} //
   // CHECK-RESILIENT-INLINE: switch_enum_addr {{%.+}} : $*Coin, case #Coin.tails!enumelt: bb2, default bb1
   if case .tails = coin {
     action0()