[llvm] r257505 - [WebAssembly] Make CFG stackification independent of basic-block labels.

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 12 11:14:47 PST 2016


Author: djg
Date: Tue Jan 12 13:14:46 2016
New Revision: 257505

URL: http://llvm.org/viewvc/llvm-project?rev=257505&view=rev
Log:
[WebAssembly] Make CFG stackification independent of basic-block labels.

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.

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

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Tue Jan 12 13:14:46 2016
@@ -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(c
 
   // 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::printOperan
   } 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::printOperan
   } 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");

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Tue Jan 12 13:14:46 2016
@@ -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);

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Tue Jan 12 13:14:46 2016
@@ -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
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Tue Jan 12 13:14:46 2016
@@ -208,10 +208,6 @@ void WebAssemblyAsmPrinter::EmitInstruct
     // 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;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp Tue Jan 12 13:14:46 2016
@@ -326,13 +326,21 @@ static void PlaceBlockMarker(MachineBasi
     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(MachineBasi
 }
 
 /// 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(MachineBasic
     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(MachineBasic
     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
   // 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::runOnMachin
   // 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;
 }

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Tue Jan 12 13:14:46 2016
@@ -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">;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp Tue Jan 12 13:14:46 2016
@@ -74,6 +74,9 @@ bool WebAssemblyInstrInfo::AnalyzeBranch
     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
     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

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp Tue Jan 12 13:14:46 2016
@@ -66,6 +66,9 @@ void WebAssemblyMCInstLower::Lower(const
     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
         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");

Modified: llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll Tue Jan 12 13:14:46 2016
@@ -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
+}

Modified: llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll Tue Jan 12 13:14:46 2016
@@ -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:

Modified: llvm/trunk/test/CodeGen/WebAssembly/switch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/switch.ll?rev=257505&r1=257504&r2=257505&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/switch.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/switch.ll Tue Jan 12 13:14:46 2016
@@ -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 at FUNCTION{{$}}
 ; CHECK: .LBB0_3:
@@ -94,14 +94,14 @@ sw.epilog:
 }
 
 ; 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 at FUNCTION{{$}}
 ; CHECK: .LBB1_3:




More information about the llvm-commits mailing list