OSDN Git Service

[WebAssembly] Make CFG stackification independent of basic-block labels.
authorDan Gohman <dan433584@gmail.com>
Tue, 12 Jan 2016 19:14:46 +0000 (19:14 +0000)
committerDan Gohman <dan433584@gmail.com>
Tue, 12 Jan 2016 19:14:46 +0000 (19:14 +0000)
This patch changes the way labels are referenced. Instead of referencing the
basic-block label name (eg. .LBB0_0), instructions now just have an immediate
which indicates the depth in the control-flow stack to find a label to jump to.
This makes them much closer to what we expect to have in the binary encoding,
and avoids the problem of basic-block label names not being explicit in the
binary encoding.

Also, it terminates blocks and loops with end_block and end_loop instructions,
rather than basic-block label names, for similar reasons.

This will also fix problems where two constructs appear to have the same label,
because we no longer explicitly use labels, so consumers that need labels will
presumably create their own labels, and presumably they won't reuse labels
when they do.

This patch does make the code a little more awkward to read; as a partial
mitigation, this patch also introduces comments showing where the labels are,
and comments on each branch showing where it's branching to.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257505 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
lib/Target/WebAssembly/WebAssemblyInstrControl.td
lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
test/CodeGen/WebAssembly/cfg-stackify.ll
test/CodeGen/WebAssembly/reg-stackify.ll
test/CodeGen/WebAssembly/switch.ll

index f92a9d0..60e5201 100644 (file)
@@ -16,6 +16,8 @@
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
 #include "WebAssembly.h"
 #include "WebAssemblyMachineFunctionInfo.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstrInfo.h"
@@ -33,7 +35,7 @@ using namespace llvm;
 WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI,
                                                const MCInstrInfo &MII,
                                                const MCRegisterInfo &MRI)
-    : MCInstPrinter(MAI, MII, MRI) {}
+    : MCInstPrinter(MAI, MII, MRI), ControlFlowCounter(0) {}
 
 void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
                                           unsigned RegNo) const {
@@ -59,6 +61,52 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
 
   // Print any added annotation.
   printAnnotation(OS, Annot);
+
+  if (CommentStream) {
+    // Observe any effects on the control flow stack, for use in annotating
+    // control flow label references.
+    switch (MI->getOpcode()) {
+    default:
+      break;
+    case WebAssembly::LOOP: {
+      // Grab the TopLabel value first so that labels print in numeric order.
+      uint64_t TopLabel = ControlFlowCounter++;
+      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
+      printAnnotation(OS, "label" + utostr(TopLabel) + ':');
+      ControlFlowStack.push_back(std::make_pair(TopLabel, true));
+      break;
+    }
+    case WebAssembly::BLOCK:
+      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
+      break;
+    case WebAssembly::END_LOOP:
+      ControlFlowStack.pop_back();
+      printAnnotation(
+          OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
+      break;
+    case WebAssembly::END_BLOCK:
+      printAnnotation(
+          OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
+      break;
+    }
+
+    // Annotate any control flow label references.
+    unsigned NumFixedOperands = Desc.NumOperands;
+    SmallSet<uint64_t, 8> Printed;
+    for (unsigned i = 0, e = MI->getNumOperands(); i < e; ++i) {
+      const MCOperandInfo &Info = Desc.OpInfo[i];
+      if (!(i < NumFixedOperands
+                ? (Info.OperandType == WebAssembly::OPERAND_BASIC_BLOCK)
+                : (Desc.TSFlags & WebAssemblyII::VariableOpImmediateIsLabel)))
+        continue;
+      uint64_t Depth = MI->getOperand(i).getImm();
+      if (!Printed.insert(Depth).second)
+        continue;
+      const auto &Pair = ControlFlowStack.rbegin()[Depth];
+      printAnnotation(OS, utostr(Depth) + ": " + (Pair.second ? "up" : "down") +
+                              " to label" + utostr(Pair.first));
+    }
+  }
 }
 
 static std::string toString(const APFloat &FP) {
@@ -100,7 +148,7 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
   } else if (Op.isImm()) {
     assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
             (MII.get(MI->getOpcode()).TSFlags &
-                     WebAssemblyII::VariableOpIsImmediate)) &&
+             WebAssemblyII::VariableOpIsImmediate)) &&
            "WebAssemblyII::VariableOpIsImmediate should be set for "
            "variable_ops immediate ops");
     if (MII.get(MI->getOpcode()).TSFlags &
@@ -117,7 +165,7 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
   } else {
     assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
             (MII.get(MI->getOpcode()).TSFlags &
-                     WebAssemblyII::VariableOpIsImmediate)) &&
+             WebAssemblyII::VariableOpIsImmediate)) &&
            "WebAssemblyII::VariableOpIsImmediate should be set for "
            "variable_ops expr ops");
     assert(Op.isExpr() && "unknown operand kind in printOperand");
index 39a16f5..cd6c59a 100644 (file)
@@ -23,6 +23,9 @@ namespace llvm {
 class MCSubtargetInfo;
 
 class WebAssemblyInstPrinter final : public MCInstPrinter {
+  uint64_t ControlFlowCounter;
+  SmallVector<std::pair<uint64_t, bool>, 0> ControlFlowStack;
+
 public:
   WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
                          const MCRegisterInfo &MRI);
index 753b78f..7c4fb6c 100644 (file)
@@ -58,6 +58,9 @@ enum {
   // For immediate values in the variable_ops range, this flag indicates
   // whether the value represents a type.
   VariableOpImmediateIsType   = (1 << 1),
+  // For immediate values in the variable_ops range, this flag indicates
+  // whether the value represents a control-flow label.
+  VariableOpImmediateIsLabel  = (1 << 2),
 };
 } // end namespace WebAssemblyII
 
index 8d84901..6a25c04 100644 (file)
@@ -208,10 +208,6 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
     // These represent values which are live into the function entry, so there's
     // no instruction to emit.
     break;
-  case WebAssembly::LOOP_END:
-    // This is a no-op which just exists to tell AsmPrinter.cpp that there's a
-    // fallthrough which nevertheless requires a label for the destination here.
-    break;
   default: {
     WebAssemblyMCInstLower MCInstLowering(OutContext, *this);
     MCInst TmpInst;
index 0080dc0..7876a1e 100644 (file)
@@ -326,13 +326,21 @@ static void PlaceBlockMarker(MachineBasicBlock &MBB, MachineFunction &MF,
     InsertPos = Header->getFirstTerminator();
     while (InsertPos != Header->begin() &&
            prev(InsertPos)->definesRegister(WebAssembly::EXPR_STACK) &&
-           prev(InsertPos)->getOpcode() != WebAssembly::LOOP)
+           prev(InsertPos)->getOpcode() != WebAssembly::LOOP &&
+           prev(InsertPos)->getOpcode() != WebAssembly::END_BLOCK &&
+           prev(InsertPos)->getOpcode() != WebAssembly::END_LOOP)
       --InsertPos;
   }
 
   // Add the BLOCK.
-  BuildMI(*Header, InsertPos, DebugLoc(), TII.get(WebAssembly::BLOCK))
-      .addMBB(&MBB);
+  BuildMI(*Header, InsertPos, DebugLoc(), TII.get(WebAssembly::BLOCK));
+
+  // Mark the end of the block.
+  InsertPos = MBB.begin();
+  while (InsertPos != MBB.end() &&
+         InsertPos->getOpcode() == WebAssembly::END_LOOP)
+    ++InsertPos;
+  BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::END_BLOCK));
 
   // Track the farthest-spanning scope that ends at this point.
   int Number = MBB.getNumber();
@@ -342,10 +350,11 @@ static void PlaceBlockMarker(MachineBasicBlock &MBB, MachineFunction &MF,
 }
 
 /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
-static void PlaceLoopMarker(MachineBasicBlock &MBB, MachineFunction &MF,
-                            SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
-                            const WebAssemblyInstrInfo &TII,
-                            const MachineLoopInfo &MLI) {
+static void PlaceLoopMarker(
+    MachineBasicBlock &MBB, MachineFunction &MF,
+    SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
+    DenseMap<const MachineInstr *, const MachineBasicBlock *> &LoopTops,
+    const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) {
   MachineLoop *Loop = MLI.getLoopFor(&MBB);
   if (!Loop || Loop->getHeader() != &MBB)
     return;
@@ -362,14 +371,19 @@ static void PlaceLoopMarker(MachineBasicBlock &MBB, MachineFunction &MF,
     Iter = next(MachineFunction::iterator(Bottom));
   }
   MachineBasicBlock *AfterLoop = &*Iter;
-  BuildMI(MBB, MBB.begin(), DebugLoc(), TII.get(WebAssembly::LOOP))
-      .addMBB(AfterLoop);
 
-  // Emit a special no-op telling the asm printer that we need a label to close
-  // the loop scope, even though the destination is only reachable by
-  // fallthrough.
-  if (!Bottom->back().isBarrier())
-    BuildMI(*Bottom, Bottom->end(), DebugLoc(), TII.get(WebAssembly::LOOP_END));
+  // Mark the beginning of the loop (after the end of any existing loop that
+  // ends here).
+  auto InsertPos = MBB.begin();
+  while (InsertPos != MBB.end() &&
+         InsertPos->getOpcode() == WebAssembly::END_LOOP)
+    ++InsertPos;
+  BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::LOOP));
+
+  // Mark the end of the loop.
+  MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), DebugLoc(),
+                              TII.get(WebAssembly::END_LOOP));
+  LoopTops[End] = &MBB;
 
   assert((!ScopeTops[AfterLoop->getNumber()] ||
           ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
@@ -378,6 +392,19 @@ static void PlaceLoopMarker(MachineBasicBlock &MBB, MachineFunction &MF,
     ScopeTops[AfterLoop->getNumber()] = &MBB;
 }
 
+static unsigned
+GetDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack,
+         const MachineBasicBlock *MBB) {
+  unsigned Depth = 0;
+  for (auto X : reverse(Stack)) {
+    if (X == MBB)
+      break;
+    ++Depth;
+  }
+  assert(Depth < Stack.size() && "Branch destination should be in scope");
+  return Depth;
+}
+
 /// Insert LOOP and BLOCK markers at appropriate places.
 static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
                          const WebAssemblyInstrInfo &TII,
@@ -389,25 +416,57 @@ static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
   // we may insert at the end.
   SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1);
 
+  // For eacn LOOP_END, the corresponding LOOP.
+  DenseMap<const MachineInstr *, const MachineBasicBlock *> LoopTops;
+
   for (auto &MBB : MF) {
     // Place the LOOP for MBB if MBB is the header of a loop.
-    PlaceLoopMarker(MBB, MF, ScopeTops, TII, MLI);
+    PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI);
 
     // Place the BLOCK for MBB if MBB is branched to from above.
     PlaceBlockMarker(MBB, MF, ScopeTops, TII, MLI, MDT);
   }
-}
 
-#ifndef NDEBUG
-static bool
-IsOnStack(const SmallVectorImpl<std::pair<MachineBasicBlock *, bool>> &Stack,
-          const MachineBasicBlock *MBB) {
-  for (const auto &Pair : Stack)
-    if (Pair.first == MBB)
-      return true;
-  return false;
+  // Now rewrite references to basic blocks to be depth immediates.
+  SmallVector<const MachineBasicBlock *, 8> Stack;
+  for (auto &MBB : reverse(MF)) {
+    for (auto &MI : reverse(MBB)) {
+      switch (MI.getOpcode()) {
+      case WebAssembly::BLOCK:
+        assert(ScopeTops[Stack.back()->getNumber()] == &MBB &&
+               "Block should be balanced");
+        Stack.pop_back();
+        break;
+      case WebAssembly::LOOP:
+        assert(Stack.back() == &MBB && "Loop top should be balanced");
+        Stack.pop_back();
+        Stack.pop_back();
+        break;
+      case WebAssembly::END_BLOCK:
+        Stack.push_back(&MBB);
+        break;
+      case WebAssembly::END_LOOP:
+        Stack.push_back(&MBB);
+        Stack.push_back(LoopTops[&MI]);
+        break;
+      default:
+        if (MI.isTerminator()) {
+          // Rewrite MBB operands to be depth immediates.
+          SmallVector<MachineOperand, 4> Ops(MI.operands());
+          while (MI.getNumOperands() > 0)
+            MI.RemoveOperand(MI.getNumOperands() - 1);
+          for (auto MO : Ops) {
+            if (MO.isMBB())
+              MO = MachineOperand::CreateImm(GetDepth(Stack, MO.getMBB()));
+            MI.addOperand(MF, MO);
+          }
+        }
+        break;
+      }
+    }
+  }
+  assert(Stack.empty() && "Control flow should be balanced");
 }
-#endif
 
 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
   DEBUG(dbgs() << "********** CFG Stackifying **********\n"
@@ -427,43 +486,5 @@ bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
   // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
   PlaceMarkers(MF, MLI, TII, MDT);
 
-#ifndef NDEBUG
-  // Verify that block and loop beginnings and endings are in LIFO order, and
-  // that all references to blocks are to blocks on the stack at the point of
-  // the reference.
-  SmallVector<std::pair<MachineBasicBlock *, bool>, 0> Stack;
-  for (auto &MBB : MF) {
-    while (!Stack.empty() && Stack.back().first == &MBB)
-      if (Stack.back().second) {
-        assert(Stack.size() >= 2);
-        Stack.pop_back();
-        Stack.pop_back();
-      } else {
-        assert(Stack.size() >= 1);
-        Stack.pop_back();
-      }
-    for (auto &MI : MBB)
-      switch (MI.getOpcode()) {
-      case WebAssembly::LOOP:
-        Stack.push_back(std::make_pair(&MBB, false));
-        Stack.push_back(std::make_pair(MI.getOperand(0).getMBB(), true));
-        break;
-      case WebAssembly::BLOCK:
-        Stack.push_back(std::make_pair(MI.getOperand(0).getMBB(), false));
-        break;
-      default:
-        // Verify that all referenced blocks are in scope. A reference to a
-        // block with a negative number is invalid, but can happen with inline
-        // asm, so we shouldn't assert on it, but instead let CodeGen properly
-        // fail on it.
-        for (const MachineOperand &MO : MI.explicit_operands())
-          if (MO.isMBB() && MO.getMBB()->getNumber() >= 0)
-            assert(IsOnStack(Stack, MO.getMBB()));
-        break;
-      }
-  }
-  assert(Stack.empty());
-#endif
-
   return true;
 }
index 1c06b08..d285201 100644 (file)
@@ -42,32 +42,32 @@ let Defs = [ARGUMENTS] in {
 // jump tables, so in practice we don't ever use TABLESWITCH_I64 in wasm32 mode
 // currently.
 // Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
+// Set TSFlags{2} to 1 to indicate that the immediates represent labels.
 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
 def TABLESWITCH_I32 : I<(outs), (ins I32:$index, bb_op:$default, variable_ops),
                         [(WebAssemblytableswitch I32:$index, bb:$default)],
                         "tableswitch\t$index, $default"> {
   let TSFlags{0} = 1;
+  let TSFlags{2} = 1;
 }
 def TABLESWITCH_I64 : I<(outs), (ins I64:$index, bb_op:$default, variable_ops),
                         [(WebAssemblytableswitch I64:$index, bb:$default)],
                         "tableswitch\t$index, $default"> {
   let TSFlags{0} = 1;
+  let TSFlags{2} = 1;
 }
 } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
 
-// Placemarkers to indicate the start of a block or loop scope. These
+// Placemarkers to indicate the start or end of a block or loop scope. These
 // use/clobber EXPR_STACK to prevent them from being moved into the middle of
 // an expression tree.
 let Uses = [EXPR_STACK], Defs = [EXPR_STACK] in {
-def BLOCK     : I<(outs), (ins bb_op:$dst), [], "block   \t$dst">;
-def LOOP      : I<(outs), (ins bb_op:$dst), [], "loop    \t$dst">;
+def BLOCK     : I<(outs), (ins), [], "block">;
+def LOOP      : I<(outs), (ins), [], "loop">;
+def END_BLOCK : I<(outs), (ins), [], "end_block">;
+def END_LOOP  : I<(outs), (ins), [], "end_loop">;
 } // Uses = [EXPR_STACK], Defs = [EXPR_STACK]
 
-// No-op to indicate to the AsmPrinter that a loop ends here, so a
-// basic block label is needed even if it wouldn't otherwise appear so.
-let isTerminator = 1, hasCtrlDep = 1 in
-def LOOP_END : I<(outs), (ins), []>;
-
 multiclass RETURN<WebAssemblyRegClass vt> {
   def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
                      "return  \t$val">;
index 5e7663c..028e9af 100644 (file)
@@ -74,6 +74,9 @@ bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
     case WebAssembly::BR_IF:
       if (HaveCond)
         return true;
+      // If we're running after CFGStackify, we can't optimize further.
+      if (!MI.getOperand(1).isMBB())
+        return true;
       Cond.push_back(MachineOperand::CreateImm(true));
       Cond.push_back(MI.getOperand(0));
       TBB = MI.getOperand(1).getMBB();
@@ -82,12 +85,18 @@ bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
     case WebAssembly::BR_UNLESS:
       if (HaveCond)
         return true;
+      // If we're running after CFGStackify, we can't optimize further.
+      if (!MI.getOperand(1).isMBB())
+        return true;
       Cond.push_back(MachineOperand::CreateImm(false));
       Cond.push_back(MI.getOperand(0));
       TBB = MI.getOperand(1).getMBB();
       HaveCond = true;
       break;
     case WebAssembly::BR:
+      // If we're running after CFGStackify, we can't optimize further.
+      if (!MI.getOperand(0).isMBB())
+        return true;
       if (!HaveCond)
         TBB = MI.getOperand(0).getMBB();
       else
index eaba53e..022a448 100644 (file)
@@ -66,6 +66,9 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
     default:
       MI->dump();
       llvm_unreachable("unknown operand type");
+    case MachineOperand::MO_MachineBasicBlock:
+      MI->dump();
+      llvm_unreachable("MachineBasicBlock operand should have been rewritten");
     case MachineOperand::MO_Register: {
       // Ignore all implicit register operands.
       if (MO.isImplicit())
@@ -91,10 +94,6 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
         llvm_unreachable("unknown floating point immediate type");
       break;
     }
-    case MachineOperand::MO_MachineBasicBlock:
-      MCOp = MCOperand::createExpr(
-          MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
-      break;
     case MachineOperand::MO_GlobalAddress:
       assert(MO.getTargetFlags() == 0 &&
              "WebAssembly does not use target flags on GlobalAddresses");
index 77984fa..f0e5f44 100644 (file)
@@ -18,7 +18,7 @@ declare void @something()
 ; CHECK-NEXT: br_if
 ; CHECK-NOT: br
 ; CHECK: call
-; CHECK: br .LBB0_1{{$}}
+; CHECK: br 0{{$}}
 ; CHECK: return{{$}}
 ; OPT-LABEL: test0:
 ; OPT: loop
@@ -28,7 +28,7 @@ declare void @something()
 ; OPT-NEXT: br_if
 ; OPT-NOT: br
 ; OPT: call
-; OPT: br .LBB0_1{{$}}
+; OPT: br 0{{$}}
 ; OPT: return{{$}}
 define void @test0(i32 %n) {
 entry:
@@ -59,7 +59,7 @@ back:
 ; CHECK-NEXT: br_if
 ; CHECK-NOT: br
 ; CHECK: call
-; CHECK: br .LBB1_1{{$}}
+; CHECK: br 0{{$}}
 ; CHECK: return{{$}}
 ; OPT-LABEL: test1:
 ; OPT: loop
@@ -69,7 +69,7 @@ back:
 ; OPT-NEXT: br_if
 ; OPT-NOT: br
 ; OPT: call
-; OPT: br .LBB1_1{{$}}
+; OPT: br 0{{$}}
 ; OPT: return{{$}}
 define void @test1(i32 %n) {
 entry:
@@ -94,17 +94,18 @@ back:
 
 ; CHECK-LABEL: test2:
 ; CHECK-NOT: local
-; CHECK: block .LBB2_2{{$}}
-; CHECK: br_if {{[^,]*}}, .LBB2_2{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if {{[^,]*}}, 0{{$}}
 ; CHECK: .LBB2_1:
-; CHECK: br_if ${{[0-9]+}}, .LBB2_1{{$}}
+; CHECK: br_if ${{[0-9]+}}, 0{{$}}
 ; CHECK: .LBB2_2:
 ; CHECK: return{{$}}
 ; OPT-LABEL: test2:
-; OPT: block .LBB2_2{{$}}
-; OPT: br_if {{[^,]*}}, .LBB2_2{{$}}
+; OPT-NOT: local
+; OPT: block{{$}}
+; OPT: br_if {{[^,]*}}, 0{{$}}
 ; OPT: .LBB2_1:
-; OPT: br_if ${{[0-9]+}}, .LBB2_1{{$}}
+; OPT: br_if ${{[0-9]+}}, 0{{$}}
 ; OPT: .LBB2_2:
 ; OPT: return{{$}}
 define void @test2(double* nocapture %p, i32 %n) {
@@ -133,22 +134,27 @@ for.end:
 }
 
 ; CHECK-LABEL: doublediamond:
-; CHECK: block .LBB3_5{{$}}
-; CHECK: block .LBB3_2{{$}}
-; CHECK: br_if $0, .LBB3_2{{$}}
-; CHECK: block .LBB3_4{{$}}
-; CHECK: br_if $1, .LBB3_4{{$}}
-; CHECK: br .LBB3_5{{$}}
+; CHECK: block{{$}}
+; CHECK-NEXT: block{{$}}
+; CHECK: br_if ${{[^,]*}}, 0{{$}}
+; CHECK: br 1{{$}}
+; CHECK: .LBB3_2:
+; CHECK-NEXT: end_block{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if ${{[^,]*}}, 0{{$}}
+; CHECK: br 1{{$}}
 ; CHECK: .LBB3_4:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK: .LBB3_5:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: doublediamond:
-; OPT: block .LBB3_5{{$}}
-; OPT: block .LBB3_4{{$}}
-; OPT: br_if {{[^,]*}}, .LBB3_4{{$}}
-; OPT: block .LBB3_3{{$}}
-; OPT: br_if {{[^,]*}}, .LBB3_3{{$}}
-; OPT: br .LBB3_5{{$}}
+; OPT: block{{$}}
+; OPT-NEXT: block{{$}}
+; OPT: br_if ${{[^,]*}}, 0{{$}}
+; OPT: block{{$}}
+; OPT: br_if ${{[^,]*}}, 0{{$}}
+; OPT: br 1{{$}}
 ; OPT: .LBB3_4:
 ; OPT: .LBB3_5:
 ; OPT: return ${{[0-9]+}}{{$}}
@@ -176,13 +182,13 @@ exit:
 }
 
 ; CHECK-LABEL: triangle:
-; CHECK: block .LBB4_2{{$}}
-; CHECK: br_if $1, .LBB4_2{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if $1, 0{{$}}
 ; CHECK: .LBB4_2:
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: triangle:
-; OPT: block .LBB4_2{{$}}
-; OPT: br_if $1, .LBB4_2{{$}}
+; OPT: block{{$}}
+; OPT: br_if $1, 0{{$}}
 ; OPT: .LBB4_2:
 ; OPT: return ${{[0-9]+}}{{$}}
 define i32 @triangle(i32* %p, i32 %a) {
@@ -199,18 +205,18 @@ exit:
 }
 
 ; CHECK-LABEL: diamond:
-; CHECK: block .LBB5_3{{$}}
-; CHECK: block .LBB5_2{{$}}
-; CHECK: br_if $1, .LBB5_2{{$}}
-; CHECK: br .LBB5_3{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if $1, 0{{$}}
+; CHECK: br 1{{$}}
 ; CHECK: .LBB5_2:
 ; CHECK: .LBB5_3:
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: diamond:
-; OPT: block .LBB5_3{{$}}
-; OPT: block .LBB5_2{{$}}
-; OPT: br_if {{[^,]*}}, .LBB5_2{{$}}
-; OPT: br .LBB5_3{{$}}
+; OPT: block{{$}}
+; OPT: block{{$}}
+; OPT: br_if {{[^,]*}}, 0{{$}}
+; OPT: br 1{{$}}
 ; OPT: .LBB5_2:
 ; OPT: .LBB5_3:
 ; OPT: return ${{[0-9]+}}{{$}}
@@ -246,13 +252,13 @@ entry:
 ; CHECK-NOT: br
 ; CHECK: .LBB7_1:
 ; CHECK: i32.store $discard=, 0($0), $pop{{[0-9]+}}{{$}}
-; CHECK: br .LBB7_1{{$}}
+; CHECK: br 0{{$}}
 ; CHECK: .LBB7_2:
 ; OPT-LABEL: minimal_loop:
 ; OPT-NOT: br
 ; OPT: .LBB7_1:
 ; OPT: i32.store $discard=, 0($0), $pop{{[0-9]+}}{{$}}
-; OPT: br .LBB7_1{{$}}
+; OPT: br 0{{$}}
 ; OPT: .LBB7_2:
 define i32 @minimal_loop(i32* %p) {
 entry:
@@ -266,16 +272,16 @@ loop:
 ; CHECK-LABEL: simple_loop:
 ; CHECK-NOT: br
 ; CHECK: .LBB8_1:
-; CHECK: loop .LBB8_2{{$}}
-; CHECK: br_if $pop{{[0-9]+}}, .LBB8_1{{$}}
-; CHECK: .LBB8_2:
+; CHECK: loop{{$}}
+; CHECK: br_if $pop{{[0-9]+}}, 0{{$}}
+; CHECK-NEXT: end_loop{{$}}
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: simple_loop:
 ; OPT-NOT: br
 ; OPT: .LBB8_1:
-; OPT: loop .LBB8_2{{$}}
-; OPT: br_if {{[^,]*}}, .LBB8_1{{$}}
-; OPT: .LBB8_2:
+; OPT: loop{{$}}
+; OPT: br_if {{[^,]*}}, 0{{$}}
+; OPT-NEXT: end_loop{{$}}
 ; OPT: return ${{[0-9]+}}{{$}}
 define i32 @simple_loop(i32* %p, i32 %a) {
 entry:
@@ -291,18 +297,18 @@ exit:
 }
 
 ; CHECK-LABEL: doubletriangle:
-; CHECK: block .LBB9_4{{$}}
-; CHECK: br_if $0, .LBB9_4{{$}}
-; CHECK: block .LBB9_3{{$}}
-; CHECK: br_if $1, .LBB9_3{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if $0, 0{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if $1, 0{{$}}
 ; CHECK: .LBB9_3:
 ; CHECK: .LBB9_4:
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: doubletriangle:
-; OPT: block .LBB9_4{{$}}
-; OPT: br_if $0, .LBB9_4{{$}}
-; OPT: block .LBB9_3{{$}}
-; OPT: br_if $1, .LBB9_3{{$}}
+; OPT: block{{$}}
+; OPT: br_if $0, 0{{$}}
+; OPT: block{{$}}
+; OPT: br_if $1, 0{{$}}
 ; OPT: .LBB9_3:
 ; OPT: .LBB9_4:
 ; OPT: return ${{[0-9]+}}{{$}}
@@ -327,20 +333,20 @@ exit:
 }
 
 ; CHECK-LABEL: ifelse_earlyexits:
-; CHECK: block .LBB10_4{{$}}
-; CHECK: block .LBB10_2{{$}}
-; CHECK: br_if $0, .LBB10_2{{$}}
-; CHECK: br .LBB10_4{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if $0, 0{{$}}
+; CHECK: br 1{{$}}
 ; CHECK: .LBB10_2:
-; CHECK: br_if $1, .LBB10_4{{$}}
+; CHECK: br_if $1, 0{{$}}
 ; CHECK: .LBB10_4:
 ; CHECK: return ${{[0-9]+}}{{$}}
 ; OPT-LABEL: ifelse_earlyexits:
-; OPT: block .LBB10_4{{$}}
-; OPT: block .LBB10_3{{$}}
-; OPT: br_if {{[^,]*}}, .LBB10_3{{$}}
-; OPT: br_if $1, .LBB10_4{{$}}
-; OPT: br .LBB10_4{{$}}
+; OPT: block{{$}}
+; OPT: block{{$}}
+; OPT: br_if {{[^,]*}}, 0{{$}}
+; OPT: br_if $1, 1{{$}}
+; OPT: br 1{{$}}
 ; OPT: .LBB10_3:
 ; OPT: .LBB10_4:
 ; OPT: return ${{[0-9]+}}{{$}}
@@ -366,34 +372,39 @@ exit:
 
 ; CHECK-LABEL: doublediamond_in_a_loop:
 ; CHECK: .LBB11_1:
-; CHECK: loop            .LBB11_7{{$}}
-; CHECK: block           .LBB11_6{{$}}
-; CHECK: block           .LBB11_3{{$}}
-; CHECK: br_if           $0, .LBB11_3{{$}}
-; CHECK: br              .LBB11_6{{$}}
+; CHECK: loop{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if           $0, 0{{$}}
+; CHECK: br              1{{$}}
 ; CHECK: .LBB11_3:
-; CHECK: block           .LBB11_5{{$}}
-; CHECK: br_if           $1, .LBB11_5{{$}}
-; CHECK: br              .LBB11_6{{$}}
+; CHECK: block{{$}}
+; CHECK: br_if           $1, 0{{$}}
+; CHECK: br              1{{$}}
 ; CHECK: .LBB11_5:
 ; CHECK: .LBB11_6:
-; CHECK: br              .LBB11_1{{$}}
+; CHECK: br              0{{$}}
 ; CHECK: .LBB11_7:
+; CHECK-NEXT: end_loop{{$}}
 ; OPT-LABEL: doublediamond_in_a_loop:
 ; OPT: .LBB11_1:
-; OPT: loop            .LBB11_7{{$}}
-; OPT: block           .LBB11_6{{$}}
-; OPT: block           .LBB11_5{{$}}
-; OPT: br_if           {{[^,]*}}, .LBB11_5{{$}}
-; OPT: block           .LBB11_4{{$}}
-; OPT: br_if           {{[^,]*}}, .LBB11_4{{$}}
-; OPT: br              .LBB11_6{{$}}
+; OPT: loop{{$}}
+; OPT: block{{$}}
+; OPT: block{{$}}
+; OPT: br_if           {{[^,]*}}, 0{{$}}
+; OPT: block{{$}}
+; OPT: br_if           {{[^,]*}}, 0{{$}}
+; OPT: br              2{{$}}
 ; OPT: .LBB11_4:
-; OPT: br              .LBB11_6{{$}}
+; OPT-NEXT: end_block{{$}}
+; OPT: br              1{{$}}
 ; OPT: .LBB11_5:
+; OPT-NEXT: end_block{{$}}
 ; OPT: .LBB11_6:
-; OPT: br              .LBB11_1{{$}}
+; OPT-NEXT: end_block{{$}}
+; OPT: br              0{{$}}
 ; OPT: .LBB11_7:
+; OPT-NEXT: end_loop{{$}}
 define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) {
 entry:
   br label %header
@@ -461,42 +472,48 @@ if.end:
 ; Test switch lowering and block placement.
 
 ; CHECK-LABEL: test4:
-; CHECK-NEXT: .param      i32{{$}}
-; CHECK:      block       .LBB13_8{{$}}
-; CHECK-NEXT: block       .LBB13_7{{$}}
-; CHECK-NEXT: block       .LBB13_4{{$}}
-; CHECK:      br_if       $pop{{[0-9]*}}, .LBB13_4{{$}}
-; CHECK-NEXT: block       .LBB13_3{{$}}
-; CHECK:      br_if       $pop{{[0-9]*}}, .LBB13_3{{$}}
-; CHECK:      br_if       $pop{{[0-9]*}}, .LBB13_7{{$}}
+; CHECK-NEXT: .param       i32{{$}}
+; CHECK:      block{{$}}
+; CHECK-NEXT: block{{$}}
+; CHECK-NEXT: block{{$}}
+; CHECK:      br_if       $pop{{[0-9]*}}, 0{{$}}
+; CHECK-NEXT: block{{$}}
+; CHECK:      br_if       $pop{{[0-9]*}}, 0{{$}}
+; CHECK:      br_if       $pop{{[0-9]*}}, 2{{$}}
 ; CHECK-NEXT: .LBB13_3:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return{{$}}
 ; CHECK-NEXT: .LBB13_4:
-; CHECK:      br_if       $pop{{[0-9]*}}, .LBB13_8{{$}}
-; CHECK:      br_if       $pop{{[0-9]*}}, .LBB13_7{{$}}
+; CHECK:      br_if       $pop{{[0-9]*}}, 1{{$}}
+; CHECK:      br_if       $pop{{[0-9]*}}, 0{{$}}
 ; CHECK-NEXT: return{{$}}
 ; CHECK-NEXT: .LBB13_7:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return{{$}}
 ; CHECK-NEXT: .LBB13_8:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return{{$}}
 ; OPT-LABEL: test4:
-; OPT-NEXT: .param      i32{{$}}
-; OPT:      block       .LBB13_8{{$}}
-; OPT-NEXT: block       .LBB13_7{{$}}
-; OPT-NEXT: block       .LBB13_4{{$}}
-; OPT:      br_if       $pop{{[0-9]*}}, .LBB13_4{{$}}
-; OPT-NEXT: block       .LBB13_3{{$}}
-; OPT:      br_if       $pop{{[0-9]*}}, .LBB13_3{{$}}
-; OPT:      br_if       $pop{{[0-9]*}}, .LBB13_7{{$}}
+; OPT-NEXT: .param       i32{{$}}
+; OPT:      block{{$}}
+; OPT-NEXT: block{{$}}
+; OPT-NEXT: block{{$}}
+; OPT:      br_if       $pop{{[0-9]*}}, 0{{$}}
+; OPT-NEXT: block{{$}}
+; OPT:      br_if       $pop{{[0-9]*}}, 0{{$}}
+; OPT:      br_if       $pop{{[0-9]*}}, 2{{$}}
 ; OPT-NEXT: .LBB13_3:
+; OPT-NEXT: end_block{{$}}
 ; OPT-NEXT: return{{$}}
 ; OPT-NEXT: .LBB13_4:
-; OPT:      br_if       $pop{{[0-9]*}}, .LBB13_8{{$}}
-; OPT:      br_if       $pop{{[0-9]*}}, .LBB13_7{{$}}
+; OPT:      br_if       $pop{{[0-9]*}}, 1{{$}}
+; OPT:      br_if       $pop{{[0-9]*}}, 0{{$}}
 ; OPT-NEXT: return{{$}}
 ; OPT-NEXT: .LBB13_7:
+; OPT-NEXT: end_block{{$}}
 ; OPT-NEXT: return{{$}}
 ; OPT-NEXT: .LBB13_8:
+; OPT-NEXT: end_block{{$}}
 ; OPT-NEXT: return{{$}}
 define void @test4(i32 %t) {
 entry:
@@ -525,21 +542,21 @@ default:
 
 ; CHECK-LABEL: test5:
 ; CHECK:       .LBB14_1:
-; CHECK-NEXT:  block .LBB14_4{{$}}
-; CHECK-NEXT:  loop .LBB14_3{{$}}
-; CHECK:       br_if {{[^,]*}}, .LBB14_4{{$}}
-; CHECK:       br_if {{[^,]*}}, .LBB14_1{{$}}
-; CHECK-NEXT:  .LBB14_3:
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  loop{{$}}
+; CHECK:       br_if {{[^,]*}}, 2{{$}}
+; CHECK:       br_if {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  end_loop{{$}}
 ; CHECK:       return{{$}}
 ; CHECK-NEXT:  .LBB14_4:
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test5:
 ; OPT:       .LBB14_1:
-; OPT-NEXT:  block .LBB14_4{{$}}
-; OPT-NEXT:  loop .LBB14_3{{$}}
-; OPT:       br_if {{[^,]*}}, .LBB14_4{{$}}
-; OPT:       br_if {{[^,]*}}, .LBB14_1{{$}}
-; OPT-NEXT:  .LBB14_3:
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  loop{{$}}
+; OPT:       br_if {{[^,]*}}, 2{{$}}
+; OPT:       br_if {{[^,]*}}, 0{{$}}
+; OPT-NEXT:  end_loop{{$}}
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB14_4:
 ; OPT:       return{{$}}
@@ -570,40 +587,44 @@ return:
 
 ; CHECK-LABEL: test6:
 ; CHECK:       .LBB15_1:
-; CHECK-NEXT:  block .LBB15_6{{$}}
-; CHECK-NEXT:  block .LBB15_5{{$}}
-; CHECK-NEXT:  loop  .LBB15_4{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if {{[^,]*}}, .LBB15_6{{$}}
+; CHECK:       br_if {{[^,]*}}, 3{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if {{[^,]*}}, .LBB15_5{{$}}
+; CHECK:       br_if {{[^,]*}}, 2{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if {{[^,]*}}, .LBB15_1{{$}}
-; CHECK-NEXT:  .LBB15_4:
+; CHECK:       br_if {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  end_loop{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; CHECK-NEXT:  .LBB15_5:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       .LBB15_6:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test6:
 ; OPT:       .LBB15_1:
-; OPT-NEXT:  block .LBB15_6{{$}}
-; OPT-NEXT:  block .LBB15_5{{$}}
-; OPT-NEXT:  loop  .LBB15_4{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB15_6{{$}}
+; OPT:       br_if {{[^,]*}}, 3{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB15_5{{$}}
+; OPT:       br_if {{[^,]*}}, 2{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB15_1{{$}}
-; OPT-NEXT:  .LBB15_4:
+; OPT:       br_if {{[^,]*}}, 0{{$}}
+; OPT-NEXT:  end_loop{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB15_5:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
 ; OPT:       .LBB15_6:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 define void @test6(i1 %p, i1 %q) {
@@ -640,35 +661,37 @@ second:
 
 ; CHECK-LABEL: test7:
 ; CHECK:       .LBB16_1:
-; CHECK-NEXT:  loop .LBB16_5{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       block .LBB16_4{{$}}
-; CHECK:       br_if {{[^,]*}}, .LBB16_4{{$}}
+; CHECK:       block{{$}}
+; CHECK:       br_if {{[^,]*}}, 0{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if {{[^,]*}}, .LBB16_1{{$}}
+; CHECK:       br_if {{[^,]*}}, 1{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       unreachable
-; CHECK_NEXT:  .LBB16_4:
+; CHECK-NEXT:  .LBB16_4:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if {{[^,]*}}, .LBB16_1{{$}}
-; CHECK-NEXT:  .LBB16_5:
+; CHECK:       br_if {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  end_loop{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       unreachable
 ; OPT-LABEL: test7:
 ; OPT:       .LBB16_1:
-; OPT-NEXT:  loop .LBB16_5{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       block .LBB16_4{{$}}
+; OPT:       block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB16_4{{$}}
+; OPT:       br_if {{[^,]*}}, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB16_1{{$}}
+; OPT:       br_if {{[^,]*}}, 1{{$}}
 ; OPT-NOT:   block
 ; OPT:       unreachable
-; OPT_NEXT:  .LBB16_4:
+; OPT-NEXT:  .LBB16_4:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if {{[^,]*}}, .LBB16_1{{$}}
-; OPT-NEXT:  .LBB16_5:
+; OPT:       br_if {{[^,]*}}, 0{{$}}
+; OPT-NEXT:  end_loop{{$}}
 ; OPT-NOT:   block
 ; OPT:       unreachable
 define void @test7(i1 %tobool2, i1 %tobool9) {
@@ -701,29 +724,31 @@ u1:
 
 ; CHECK-LABEL: test8:
 ; CHECK:       .LBB17_1:
-; CHECK-NEXT:  loop     .LBB17_4{{$}}
-; CHECK-NEXT:  block    .LBB17_3{{$}}
+; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if    {{[^,]*}}, .LBB17_3{{$}}
+; CHECK:       br_if    {{[^,]*}}, 0{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if    {{[^,]*}}, .LBB17_1{{$}}
+; CHECK:       br_if    {{[^,]*}}, 1{{$}}
 ; CHECK-NEXT:  .LBB17_3:
-; CHECK-NEXT:  loop     .LBB17_4{{$}}
-; CHECK-NEXT:  br_if    {{[^,]*}}, .LBB17_3{{$}}
-; CHECK-NEXT:  br       .LBB17_1{{$}}
+; CHECK-NEXT:  end_block{{$}}
+; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  br_if    {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  br       2{{$}}
 ; CHECK-NEXT:  .LBB17_4:
 ; OPT-LABEL: test8:
 ; OPT:       .LBB17_1:
-; OPT-NEXT:  loop     .LBB17_4{{$}}
-; OPT-NEXT:  block    .LBB17_3{{$}}
+; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if    {{[^,]*}}, .LBB17_3{{$}}
+; OPT:       br_if    {{[^,]*}}, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if    {{[^,]*}}, .LBB17_1{{$}}
+; OPT:       br_if    {{[^,]*}}, 1{{$}}
 ; OPT-NEXT:  .LBB17_3:
-; OPT-NEXT:  loop     .LBB17_4{{$}}
-; OPT-NEXT:  br_if    {{[^,]*}}, .LBB17_3{{$}}
-; OPT-NEXT:  br       .LBB17_1{{$}}
+; OPT-NEXT:  end_block{{$}}
+; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  br_if    {{[^,]*}}, 0{{$}}
+; OPT-NEXT:  br       2{{$}}
 ; OPT-NEXT:  .LBB17_4:
 define i32 @test8() {
 bb:
@@ -747,43 +772,45 @@ bb3:
 
 ; CHECK-LABEL: test9:
 ; CHECK:       .LBB18_1:
-; CHECK-NEXT:  loop      .LBB18_5{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if     {{[^,]*}}, .LBB18_5{{$}}
+; CHECK:       br_if     {{[^,]*}}, 1{{$}}
 ; CHECK-NEXT:  .LBB18_2:
-; CHECK-NEXT:  loop      .LBB18_5{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       block     .LBB18_4{{$}}
+; CHECK:       block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if     {{[^,]*}}, .LBB18_4{{$}}
+; CHECK:       br_if     {{[^,]*}}, 0{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if     {{[^,]*}}, .LBB18_2{{$}}
-; CHECK-NEXT:  br        .LBB18_1{{$}}
+; CHECK:       br_if     {{[^,]*}}, 1{{$}}
+; CHECK-NEXT:  br        3{{$}}
 ; CHECK-NEXT:  .LBB18_4:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if     {{[^,]*}}, .LBB18_2{{$}}
-; CHECK-NEXT:  br        .LBB18_1{{$}}
+; CHECK:       br_if     {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  br        2{{$}}
 ; CHECK-NEXT:  .LBB18_5:
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test9:
 ; OPT:       .LBB18_1:
-; OPT-NEXT:  loop      .LBB18_5{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if     {{[^,]*}}, .LBB18_5{{$}}
+; OPT:       br_if     {{[^,]*}}, 1{{$}}
 ; OPT-NEXT:  .LBB18_2:
-; OPT-NEXT:  loop      .LBB18_5{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       block     .LBB18_4{{$}}
+; OPT:       block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if     {{[^,]*}}, .LBB18_4{{$}}
+; OPT:       br_if     {{[^,]*}}, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if     {{[^,]*}}, .LBB18_2{{$}}
-; OPT-NEXT:  br        .LBB18_1{{$}}
+; OPT:       br_if     {{[^,]*}}, 1{{$}}
+; OPT-NEXT:  br        3{{$}}
 ; OPT-NEXT:  .LBB18_4:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if     {{[^,]*}}, .LBB18_2{{$}}
-; OPT-NEXT:  br        .LBB18_1{{$}}
+; OPT:       br_if     {{[^,]*}}, 0{{$}}
+; OPT-NEXT:  br        2{{$}}
 ; OPT-NEXT:  .LBB18_5:
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
@@ -823,45 +850,51 @@ end:
 
 ; CHECK-LABEL: test10:
 ; CHECK:       .LBB19_1:
-; CHECK-NEXT:  loop     .LBB19_7{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if    {{[^,]*}}, .LBB19_1{{$}}
+; CHECK:       br_if    {{[^,]*}}, 0{{$}}
 ; CHECK-NEXT:  .LBB19_2:
-; CHECK-NEXT:  block    .LBB19_6{{$}}
-; CHECK-NEXT:  loop     .LBB19_5{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       .LBB19_3:
-; CHECK-NEXT:  loop     .LBB19_5{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if    {{[^,]*}}, .LBB19_1{{$}}
+; CHECK:       br_if    {{[^,]*}}, 5{{$}}
 ; CHECK-NOT:   block
-; CHECK:       tableswitch  {{[^,]*}}, .LBB19_3, .LBB19_3, .LBB19_5, .LBB19_1, .LBB19_2, .LBB19_6{{$}}
+; CHECK:       tableswitch  {{[^,]*}}, 0, 0, 1, 5, 2, 4{{$}}
 ; CHECK-NEXT:  .LBB19_5:
+; CHECK-NEXT:  end_loop{{$}}
+; CHECK-NEXT:  end_loop{{$}}
 ; CHECK-NEXT:  return{{$}}
 ; CHECK-NEXT:  .LBB19_6:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br       .LBB19_1{{$}}
+; CHECK:       br       0{{$}}
 ; CHECK-NEXT:  .LBB19_7:
 ; OPT-LABEL: test10:
 ; OPT:       .LBB19_1:
-; OPT-NEXT:  loop     .LBB19_7{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if    {{[^,]*}}, .LBB19_1{{$}}
+; OPT:       br_if    {{[^,]*}}, 0{{$}}
 ; OPT-NEXT:  .LBB19_2:
-; OPT-NEXT:  block    .LBB19_6{{$}}
-; OPT-NEXT:  loop     .LBB19_5{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
 ; OPT:       .LBB19_3:
-; OPT-NEXT:  loop     .LBB19_5{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if    {{[^,]*}}, .LBB19_1{{$}}
+; OPT:       br_if    {{[^,]*}}, 5{{$}}
 ; OPT-NOT:   block
-; OPT:       tableswitch  {{[^,]*}}, .LBB19_3, .LBB19_3, .LBB19_5, .LBB19_1, .LBB19_2, .LBB19_6{{$}}
+; OPT:       tableswitch  {{[^,]*}}, 0, 0, 1, 5, 2, 4{{$}}
 ; OPT-NEXT:  .LBB19_5:
+; OPT-NEXT:  end_loop{{$}}
+; OPT-NEXT:  end_loop{{$}}
 ; OPT-NEXT:  return{{$}}
 ; OPT-NEXT:  .LBB19_6:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br       .LBB19_1{{$}}
+; OPT:       br       0{{$}}
 ; OPT-NEXT:  .LBB19_7:
 define void @test10() {
 bb0:
@@ -901,58 +934,67 @@ bb6:
 ; Test a CFG DAG with interesting merging.
 
 ; CHECK-LABEL: test11:
-; CHECK:       block        .LBB20_8{{$}}
-; CHECK-NEXT:  block        .LBB20_7{{$}}
-; CHECK-NEXT:  block        .LBB20_6{{$}}
-; CHECK-NEXT:  block        .LBB20_4{{$}}
-; CHECK-NEXT:  br_if        {{[^,]*}}, .LBB20_4{{$}}
+; CHECK:       block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  br_if        {{[^,]*}}, 0{{$}}
+; CHECK-NEXT:  block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       block        .LBB20_3{{$}}
-; CHECK:       br_if        {{[^,]*}}, .LBB20_3{{$}}
+; CHECK:       br_if        {{[^,]*}}, 0{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if        {{[^,]*}}, .LBB20_6{{$}}
+; CHECK:       br_if        {{[^,]*}}, 2{{$}}
 ; CHECK-NEXT:  .LBB20_3:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; CHECK-NEXT:  .LBB20_4:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if        {{[^,]*}}, .LBB20_8{{$}}
+; CHECK:       br_if        {{[^,]*}}, 2{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if        {{[^,]*}}, .LBB20_7{{$}}
+; CHECK:       br_if        {{[^,]*}}, 1{{$}}
 ; CHECK-NEXT:  .LBB20_6:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; CHECK-NEXT:  .LBB20_7:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; CHECK-NEXT:  .LBB20_8:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test11:
-; OPT:       block        .LBB20_8{{$}}
-; OPT-NEXT:  block        .LBB20_4{{$}}
-; OPT-NEXT:  br_if        $0, .LBB20_4{{$}}
+; OPT:       block{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  br_if        $0, 0{{$}}
+; OPT-NEXT:  block{{$}}
 ; OPT-NOT:   block
-; OPT:       block        .LBB20_3{{$}}
-; OPT:       br_if        $0, .LBB20_3{{$}}
+; OPT:       br_if        $0, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $0, .LBB20_8{{$}}
+; OPT:       br_if        $0, 2{{$}}
 ; OPT-NEXT:  .LBB20_3:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB20_4:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       block        .LBB20_6{{$}}
+; OPT:       block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $pop9, .LBB20_6{{$}}
+; OPT:       br_if        $pop9, 0{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB20_6:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $0, .LBB20_8{{$}}
+; OPT:       br_if        $0, 0{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB20_8:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 define void @test11() {
@@ -987,51 +1029,57 @@ bb8:
 
 ; CHECK-LABEL: test12:
 ; CHECK:       .LBB21_1:
-; CHECK-NEXT:  loop        .LBB21_8{{$}}
+; CHECK-NEXT:  loop{{$}}
 ; CHECK-NOT:   block
-; CHECK:       block       .LBB21_7{{$}}
-; CHECK-NEXT:  block       .LBB21_6{{$}}
-; CHECK-NEXT:  block       .LBB21_4{{$}}
-; CHECK:       br_if       {{[^,]*}}, .LBB21_4{{$}}
+; CHECK:       block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  block{{$}}
+; CHECK:       br_if       {{[^,]*}}, 0{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; CHECK:       br_if       {{[^,]*}}, 2{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if       {{[^,]*}}, .LBB21_7{{$}}
-; CHECK-NEXT:  br          .LBB21_6{{$}}
+; CHECK:       br_if       {{[^,]*}}, 2{{$}}
+; CHECK-NEXT:  br          1{{$}}
 ; CHECK-NEXT:  .LBB21_4:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; CHECK:       br_if       {{[^,]*}}, 1{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; CHECK:       br_if       {{[^,]*}}, 1{{$}}
 ; CHECK-NEXT:  .LBB21_6:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NEXT:  return{{$}}
 ; CHECK-NEXT:  .LBB21_7:
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NOT:   block
-; CHECK:       br          .LBB21_1{{$}}
+; CHECK:       br          0{{$}}
 ; CHECK-NEXT:  .LBB21_8:
 ; OPT-LABEL: test12:
 ; OPT:       .LBB21_1:
-; OPT-NEXT:  loop        .LBB21_8{{$}}
+; OPT-NEXT:  loop{{$}}
 ; OPT-NOT:   block
-; OPT:       block       .LBB21_7{{$}}
-; OPT-NEXT:  block       .LBB21_6{{$}}
-; OPT-NEXT:  block       .LBB21_4{{$}}
-; OPT:       br_if       {{[^,]*}}, .LBB21_4{{$}}
+; OPT:       block{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  block{{$}}
+; OPT:       br_if       {{[^,]*}}, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; OPT:       br_if       {{[^,]*}}, 2{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if       {{[^,]*}}, .LBB21_7{{$}}
-; OPT-NEXT:  br          .LBB21_6{{$}}
+; OPT:       br_if       {{[^,]*}}, 2{{$}}
+; OPT-NEXT:  br          1{{$}}
 ; OPT-NEXT:  .LBB21_4:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; OPT:       br_if       {{[^,]*}}, 1{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if       {{[^,]*}}, .LBB21_7{{$}}
+; OPT:       br_if       {{[^,]*}}, 1{{$}}
 ; OPT-NEXT:  .LBB21_6:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NEXT:  return{{$}}
 ; OPT-NEXT:  .LBB21_7:
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br          .LBB21_1{{$}}
+; OPT:       br          0{{$}}
 ; OPT-NEXT:  .LBB21_8:
 define void @test12(i8* %arg) {
 bb:
@@ -1061,30 +1109,34 @@ bb7:
 ; optnone to disable optimizations to test this case.
 
 ; CHECK-LABEL: test13:
-; CHECK-NEXT:  .local i32{{$}}
-; CHECK:       block .LBB22_2{{$}}
-; CHECK:       br_if $pop4, .LBB22_2{{$}}
+; CHECK-NEXT:  local i32{{$}}
+; CHECK:       block{{$}}
+; CHECK:       br_if $pop4, 0{{$}}
 ; CHECK-NEXT:  return{{$}}
 ; CHECK-NEXT:  .LBB22_2:
-; CHECK:       block .LBB22_4{{$}}
-; CHECK-NEXT:  br_if $0, .LBB22_4{{$}}
+; CHECK-NEXT:  end_block{{$}}
+; CHECK:       block{{$}}
+; CHECK-NEXT:  br_if $0, 0{{$}}
 ; CHECK:       .LBB22_4:
-; CHECK:       block .LBB22_5{{$}}
-; CHECK:       br_if $pop6, .LBB22_5{{$}}
-; CHECK-NEXT:  .LBB22_5:
+; CHECK-NEXT:  end_block{{$}}
+; CHECK:       block{{$}}
+; CHECK:       br_if $pop6, 0{{$}}
+; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NEXT:  unreachable{{$}}
 ; OPT-LABEL: test13:
-; OPT-NEXT:  .local i32{{$}}
-; OPT:       block .LBB22_2{{$}}
-; OPT:       br_if $pop4, .LBB22_2{{$}}
+; OPT-NEXT:  local i32{{$}}
+; OPT:       block{{$}}
+; OPT:       br_if $pop4, 0{{$}}
 ; OPT-NEXT:  return{{$}}
 ; OPT-NEXT:  .LBB22_2:
-; OPT:       block .LBB22_4{{$}}
-; OPT-NEXT:  br_if $0, .LBB22_4{{$}}
+; OPT-NEXT:  end_block{{$}}
+; OPT:       block{{$}}
+; OPT-NEXT:  br_if $0, 0{{$}}
 ; OPT:       .LBB22_4:
-; OPT:       block .LBB22_5{{$}}
-; OPT:       br_if $pop6, .LBB22_5{{$}}
-; OPT-NEXT:  .LBB22_5:
+; OPT-NEXT:  end_block{{$}}
+; OPT:       block{{$}}
+; OPT:       br_if $pop6, 0{{$}}
+; OPT-NEXT:  end_block{{$}}
 ; OPT-NEXT:  unreachable{{$}}
 define void @test13() noinline optnone {
 bb:
@@ -1101,3 +1153,65 @@ bb4:
 bb5:
   ret void
 }
+
+; Test a case with a single-block loop that has another loop
+; as a successor. The end_loop for the first loop should go
+; before the loop for the second.
+
+; CHECK-LABEL: test14:
+; CHECK-NEXT:     local       i32{{$}}
+; CHECK-NEXT:     i32.const   $0=, 0{{$}}
+; CHECK-NEXT: .LBB23_1:{{$}}
+; CHECK-NEXT:     loop{{$}}
+; CHECK-NEXT:     br_if       $0, 0{{$}}
+; CHECK-NEXT: .LBB23_2:{{$}}
+; CHECK-NEXT:     end_loop{{$}}
+; CHECK-NEXT:     loop{{$}}
+; CHECK-NEXT:     br_if       $0, 0{{$}}
+; CHECK-NEXT:     end_loop{{$}}
+; CHECK-NEXT:     return{{$}}
+define void @test14() {
+bb:
+  br label %bb1
+
+bb1:
+  %tmp = bitcast i1 undef to i1
+  br i1 %tmp, label %bb3, label %bb1
+
+bb3:
+  br label %bb4
+
+bb4:
+  br i1 undef, label %bb7, label %bb48
+
+bb7:
+  br i1 undef, label %bb12, label %bb12
+
+bb12:
+  br i1 undef, label %bb17, label %bb17
+
+bb17:
+  br i1 undef, label %bb22, label %bb22
+
+bb22:
+  br i1 undef, label %bb27, label %bb27
+
+bb27:
+  br i1 undef, label %bb30, label %bb30
+
+bb30:
+  br i1 undef, label %bb35, label %bb35
+
+bb35:
+  br i1 undef, label %bb38, label %bb38
+
+bb38:
+  br i1 undef, label %bb48, label %bb48
+
+bb48:
+  %tmp49 = bitcast i1 undef to i1
+  br i1 %tmp49, label %bb3, label %bb50
+
+bb50:
+  ret void
+}
index 768d574..f8cae7f 100644 (file)
@@ -55,7 +55,7 @@ define i32 @yes1(i32* %q) {
 ; CHECK-NEXT: .local i32, i32{{$}}
 ; CHECK-NEXT: i32.const   $5=, 2{{$}}
 ; CHECK-NEXT: i32.const   $4=, 1{{$}}
-; CHECK-NEXT: block       .LBB4_2{{$}}
+; CHECK-NEXT: block{{$}}
 ; CHECK-NEXT: i32.lt_s    $push0=, $0, $4{{$}}
 ; CHECK-NEXT: i32.lt_s    $push1=, $1, $5{{$}}
 ; CHECK-NEXT: i32.xor     $push4=, $pop0, $pop1{{$}}
@@ -64,10 +64,11 @@ define i32 @yes1(i32* %q) {
 ; CHECK-NEXT: i32.xor     $push5=, $pop2, $pop3{{$}}
 ; CHECK-NEXT: i32.xor     $push6=, $pop4, $pop5{{$}}
 ; CHECK-NEXT: i32.ne      $push7=, $pop6, $4{{$}}
-; CHECK-NEXT: br_if       $pop7, .LBB4_2{{$}}
+; CHECK-NEXT: br_if       $pop7, 0{{$}}
 ; CHECK-NEXT: i32.const   $push8=, 0{{$}}
 ; CHECK-NEXT: return      $pop8{{$}}
 ; CHECK-NEXT: .LBB4_2:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return      $4{{$}}
 define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
 entry:
@@ -89,16 +90,17 @@ false:
 ; be trivially stackified.
 
 ; CHECK-LABEL: multiple_uses:
-; CHECK-NEXT: .param      i32, i32, i32{{$}}
-; CHECK-NEXT: .local      i32{{$}}
+; CHECK-NEXT: .param       i32, i32, i32{{$}}
+; CHECK-NEXT: .local       i32{{$}}
 ; CHECK-NEXT: i32.load    $3=, 0($2){{$}}
-; CHECK-NEXT: block       .LBB5_3{{$}}
+; CHECK-NEXT: block{{$}}
 ; CHECK-NEXT: i32.ge_u    $push0=, $3, $1{{$}}
-; CHECK-NEXT: br_if       $pop0, .LBB5_3{{$}}
+; CHECK-NEXT: br_if       $pop0, 0{{$}}
 ; CHECK-NEXT: i32.lt_u    $push1=, $3, $0{{$}}
-; CHECK-NEXT: br_if       $pop1, .LBB5_3{{$}}
+; CHECK-NEXT: br_if       $pop1, 0{{$}}
 ; CHECK-NEXT: i32.store   $discard=, 0($2), $3{{$}}
 ; CHECK-NEXT: .LBB5_3:
+; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return{{$}}
 define void @multiple_uses(i32* %arg0, i32* %arg1, i32* %arg2) nounwind {
 bb:
index ef35ba1..3df5e7f 100644 (file)
@@ -14,14 +14,14 @@ declare void @foo4()
 declare void @foo5()
 
 ; CHECK-LABEL: bar32:
-; CHECK: block .LBB0_8{{$}}
-; CHECK: block .LBB0_7{{$}}
-; CHECK: block .LBB0_6{{$}}
-; CHECK: block .LBB0_5{{$}}
-; CHECK: block .LBB0_4{{$}}
-; CHECK: block .LBB0_3{{$}}
-; CHECK: block .LBB0_2{{$}}
-; CHECK: tableswitch {{[^,]*}}, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_5, .LBB0_6, .LBB0_7{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: tableswitch {{[^,]*}}, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5{{$}}
 ; CHECK: .LBB0_2:
 ; CHECK:   call foo0@FUNCTION{{$}}
 ; CHECK: .LBB0_3:
@@ -94,14 +94,14 @@ sw.epilog:                                        ; preds = %entry, %sw.bb.5, %s
 }
 
 ; CHECK-LABEL: bar64:
-; CHECK: block .LBB1_8{{$}}
-; CHECK: block .LBB1_7{{$}}
-; CHECK: block .LBB1_6{{$}}
-; CHECK: block .LBB1_5{{$}}
-; CHECK: block .LBB1_4{{$}}
-; CHECK: block .LBB1_3{{$}}
-; CHECK: block .LBB1_2{{$}}
-; CHECK: tableswitch {{[^,]*}}, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_5, .LBB1_6, .LBB1_7{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: block{{$}}
+; CHECK: tableswitch {{[^,]*}}, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5{{$}}
 ; CHECK: .LBB1_2:
 ; CHECK:   call foo0@FUNCTION{{$}}
 ; CHECK: .LBB1_3: