Переглянути джерело

[spirv] Better handling of unreachable statements. (#561)

Ehsan 8 роки тому
батько
коміт
c40a24cbd9

+ 1 - 3
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -72,9 +72,7 @@ public:
 
 
   /// \brief Creates a SPIR-V basic block. On success, returns the <label-id>
   /// \brief Creates a SPIR-V basic block. On success, returns the <label-id>
   /// for the basic block. On failure, returns zero.
   /// for the basic block. On failure, returns zero.
-  /// All basic blocks are reachable by default. If isReachable is set to false,
-  /// a debug name will not be created for the basic block.
-  uint32_t createBasicBlock(llvm::StringRef name = "", bool isReachable = true);
+  uint32_t createBasicBlock(llvm::StringRef name = "");
 
 
   /// \brief Adds the basic block with the given label as a successor to the
   /// \brief Adds the basic block with the given label as a successor to the
   /// current basic block.
   /// current basic block.

+ 17 - 11
tools/clang/include/clang/SPIRV/Structure.h

@@ -80,9 +80,7 @@ private:
 class BasicBlock {
 class BasicBlock {
 public:
 public:
   /// \brief Constructs a basic block with the given <label-id>.
   /// \brief Constructs a basic block with the given <label-id>.
-  /// By default all basic blocks are considered reachable, unless the caller
-  /// specifies otherwise.
-  inline explicit BasicBlock(uint32_t labelId, bool isReachable = true);
+  inline explicit BasicBlock(uint32_t labelId, llvm::StringRef debugName = "");
 
 
   // Disable copy constructor/assignment
   // Disable copy constructor/assignment
   BasicBlock(const BasicBlock &) = delete;
   BasicBlock(const BasicBlock &) = delete;
@@ -134,20 +132,23 @@ public:
   /// OpLoopMerge instruction. Returns nullptr otherwise.
   /// OpLoopMerge instruction. Returns nullptr otherwise.
   inline BasicBlock *getContinueTarget() const;
   inline BasicBlock *getContinueTarget() const;
 
 
+  /// \brief Returns the label id of this basic block.
+  inline uint32_t getLabelId() const;
+
+  /// \brief Returns the debug name of this basic block.
+  inline llvm::StringRef getDebugName() const;
+
   /// \brief Returns true if this basic block is terminated.
   /// \brief Returns true if this basic block is terminated.
   bool isTerminated() const;
   bool isTerminated() const;
 
 
-  /// \brief Returns true if this basic block is reachable in the control flow.
-  inline bool isReachable() const;
-
 private:
 private:
   uint32_t labelId; ///< The label id for this basic block. Zero means invalid.
   uint32_t labelId; ///< The label id for this basic block. Zero means invalid.
+  std::string debugName;
   std::deque<Instruction> instructions;
   std::deque<Instruction> instructions;
 
 
   llvm::SmallVector<BasicBlock *, 2> successors;
   llvm::SmallVector<BasicBlock *, 2> successors;
   BasicBlock *mergeTarget;
   BasicBlock *mergeTarget;
   BasicBlock *continueTarget;
   BasicBlock *continueTarget;
-  bool reachable;
 };
 };
 
 
 // === Function definition ===
 // === Function definition ===
@@ -188,6 +189,10 @@ public:
   /// \brief Adds a basic block to this function.
   /// \brief Adds a basic block to this function.
   inline void addBasicBlock(std::unique_ptr<BasicBlock> block);
   inline void addBasicBlock(std::unique_ptr<BasicBlock> block);
 
 
+  /// \brief Adds the reachable basic blocks of this function to the given
+  /// vector.
+  void getReachableBasicBlocks(std::vector<BasicBlock *> *) const;
+
 private:
 private:
   uint32_t resultType;
   uint32_t resultType;
   uint32_t resultId;
   uint32_t resultId;
@@ -357,9 +362,9 @@ std::vector<uint32_t> Instruction::take() { return std::move(words); }
 
 
 // === Basic block inline implementations ===
 // === Basic block inline implementations ===
 
 
-BasicBlock::BasicBlock(uint32_t id, bool isReachable)
-    : labelId(id), mergeTarget(nullptr), continueTarget(nullptr),
-      reachable(isReachable) {}
+BasicBlock::BasicBlock(uint32_t id, llvm::StringRef name)
+    : labelId(id), debugName(name), mergeTarget(nullptr),
+      continueTarget(nullptr) {}
 
 
 bool BasicBlock::isEmpty() const {
 bool BasicBlock::isEmpty() const {
   return labelId == 0 && instructions.empty();
   return labelId == 0 && instructions.empty();
@@ -391,7 +396,8 @@ void BasicBlock::setContinueTarget(BasicBlock *target) {
 
 
 BasicBlock *BasicBlock::getContinueTarget() const { return continueTarget; }
 BasicBlock *BasicBlock::getContinueTarget() const { return continueTarget; }
 
 
-bool BasicBlock::isReachable() const { return reachable; }
+uint32_t BasicBlock::getLabelId() const { return labelId; }
+llvm::StringRef BasicBlock::getDebugName() const { return debugName; }
 
 
 // === Function inline implementations ===
 // === Function inline implementations ===
 
 

+ 2 - 12
tools/clang/lib/SPIRV/ModuleBuilder.cpp

@@ -97,24 +97,14 @@ bool ModuleBuilder::endFunction() {
   return true;
   return true;
 }
 }
 
 
-uint32_t ModuleBuilder::createBasicBlock(llvm::StringRef name,
-                                         bool isReachable) {
+uint32_t ModuleBuilder::createBasicBlock(llvm::StringRef name) {
   if (theFunction == nullptr) {
   if (theFunction == nullptr) {
     assert(false && "found detached basic block");
     assert(false && "found detached basic block");
     return 0;
     return 0;
   }
   }
 
 
   const uint32_t labelId = theContext.takeNextId();
   const uint32_t labelId = theContext.takeNextId();
-  basicBlocks[labelId] = llvm::make_unique<BasicBlock>(labelId, isReachable);
-
-  // OpName instructions should not be added for unreachable basic blocks
-  // because such blocks are *not* discovered by BlockReadableOrderVisitor and
-  // therefore they are not emitted.
-  // The newly created basic block is unreachable if specified by the caller,
-  // or, if this block is being created by a block that is already unreachable.
-  if (isReachable && (!insertPoint || insertPoint->isReachable()))
-    theModule.addDebugName(labelId, name);
-
+  basicBlocks[labelId] = llvm::make_unique<BasicBlock>(labelId, name);
   return labelId;
   return labelId;
 }
 }
 
 

+ 23 - 111
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -129,45 +129,6 @@ const Stmt *getImmediateParent(ASTContext &astContext, const Stmt *stmt) {
   return parents.empty() ? nullptr : parents[0].get<Stmt>();
   return parents.empty() ? nullptr : parents[0].get<Stmt>();
 }
 }
 
 
-/// \brief Returns true if there are no unreachable statements after the given
-/// statement. A "continue" statement and "break" statement cause a branch to a
-/// loop header and a loop merge block, respectively. A "return" statement
-/// causes a branch out of the function. In such situations, any statement that
-/// follows the break/continue/return will not be executed. When this method
-/// returns false, it indicates that there exists statements that are not going
-/// to be executed.
-bool isLastStmtBeforeControlFlowBranching(ASTContext &astContext,
-                                          const Stmt *stmt) {
-  const Stmt *parent = getImmediateParent(astContext, stmt);
-  if (const auto *parentCS = dyn_cast_or_null<CompoundStmt>(parent)) {
-    if (stmt == *(parentCS->body_rbegin())) {
-      // The current statement is the last child node of the parent.
-
-      // Handle nested compound statements. e.g.
-      // while (cond) {
-      //   StmtA;
-      //   {
-      //      StmtB;
-      //      {{continue;}}
-      //   }
-      //   {StmtC;}
-      //   StmtD;
-      // }
-      //
-      // The continue statement is the last statement in its CompoundStmt scope,
-      // but, if nested compound statements are flattened, the continue
-      // statement is not the last statement in the current loop scope.
-      const Stmt *grandparent = getImmediateParent(astContext, parent);
-      if (grandparent && isa<CompoundStmt>(grandparent))
-        return isLastStmtBeforeControlFlowBranching(astContext, parent);
-
-      return true;
-    }
-  }
-
-  return false;
-}
-
 bool isLoopStmt(const Stmt *stmt) {
 bool isLoopStmt(const Stmt *stmt) {
   return isa<ForStmt>(stmt) || isa<WhileStmt>(stmt) || isa<DoStmt>(stmt);
   return isa<ForStmt>(stmt) || isa<WhileStmt>(stmt) || isa<DoStmt>(stmt);
 }
 }
@@ -533,11 +494,11 @@ spv::LoopControlMask SPIRVEmitter::translateLoopAttribute(const Attr &attr) {
 void SPIRVEmitter::doDiscardStmt(const DiscardStmt *discardStmt) {
 void SPIRVEmitter::doDiscardStmt(const DiscardStmt *discardStmt) {
   assert(!theBuilder.isCurrentBasicBlockTerminated());
   assert(!theBuilder.isCurrentBasicBlockTerminated());
   theBuilder.createKill();
   theBuilder.createKill();
-  if (!isLastStmtBeforeControlFlowBranching(astContext, discardStmt)) {
-    const uint32_t unreachableBB =
-        theBuilder.createBasicBlock("unreachable", /*isReachable*/ false);
-    theBuilder.setInsertPoint(unreachableBB);
-  }
+  // Some statements that alter the control flow (break, continue, return, and
+  // discard), require creation of a new basic block to hold any statement that
+  // may follow them.
+  const uint32_t newBB = theBuilder.createBasicBlock();
+  theBuilder.setInsertPoint(newBB);
 }
 }
 
 
 void SPIRVEmitter::doDoStmt(const DoStmt *theDoStmt,
 void SPIRVEmitter::doDoStmt(const DoStmt *theDoStmt,
@@ -643,8 +604,10 @@ void SPIRVEmitter::doContinueStmt(const ContinueStmt *continueStmt) {
   theBuilder.createBranch(continueTargetBB);
   theBuilder.createBranch(continueTargetBB);
   theBuilder.addSuccessor(continueTargetBB);
   theBuilder.addSuccessor(continueTargetBB);
 
 
-  // If any statements follow a continue statement in a loop, they will not be
-  // executed. For example, StmtB and StmtC below are never executed:
+  // Some statements that alter the control flow (break, continue, return, and
+  // discard), require creation of a new basic block to hold any statement that
+  // may follow them. For example: StmtB and StmtC below are put inside a new
+  // basic block which is unreachable.
   //
   //
   // while (true) {
   // while (true) {
   //   StmtA;
   //   StmtA;
@@ -652,16 +615,8 @@ void SPIRVEmitter::doContinueStmt(const ContinueStmt *continueStmt) {
   //   StmtB;
   //   StmtB;
   //   StmtC;
   //   StmtC;
   // }
   // }
-  //
-  // To handle such cases, we do not stop tranlsation. We create a new basic
-  // block in which StmtB and StmtC will be translated.
-  // Note that since this basic block is unreachable, BlockReadableOrderVisitor
-  // will not emit it in the final module binary.
-  if (!isLastStmtBeforeControlFlowBranching(astContext, continueStmt)) {
-    const uint32_t unreachableBB =
-        theBuilder.createBasicBlock("unreachable", /*isReachable*/ false);
-    theBuilder.setInsertPoint(unreachableBB);
-  }
+  const uint32_t newBB = theBuilder.createBasicBlock();
+  theBuilder.setInsertPoint(newBB);
 }
 }
 
 
 void SPIRVEmitter::doWhileStmt(const WhileStmt *whileStmt,
 void SPIRVEmitter::doWhileStmt(const WhileStmt *whileStmt,
@@ -941,39 +896,12 @@ void SPIRVEmitter::doReturnStmt(const ReturnStmt *stmt) {
   else
   else
     theBuilder.createReturn();
     theBuilder.createReturn();
 
 
-  // Handle early returns
-  if (!isLastStmtBeforeControlFlowBranching(astContext, stmt)) {
-    const uint32_t unreachableBB =
-        theBuilder.createBasicBlock("unreachable", /*isReachable*/ false);
-    theBuilder.setInsertPoint(unreachableBB);
-  }
-}
-
-bool SPIRVEmitter::breakStmtIsLastStmtInCaseStmt(const BreakStmt *breakStmt,
-                                                 const SwitchStmt *switchStmt) {
-  std::vector<const Stmt *> flatSwitch;
-  flattenSwitchStmtAST(switchStmt->getBody(), &flatSwitch);
-  auto iter =
-      std::find(flatSwitch.begin(), flatSwitch.end(), cast<Stmt>(breakStmt));
-  assert(iter != std::end(flatSwitch));
-
-  // We are interested to know what comes after the BreakStmt.
-  ++iter;
-
-  // The break statement is the last statement in its case statement iff:
-  // it is the last statement in the switch, or,
-  // its next statement is either 'default' or 'case'
-  return iter == flatSwitch.end() || isa<CaseStmt>(*iter) ||
-         isa<DefaultStmt>(*iter);
-}
-
-const Stmt *SPIRVEmitter::breakStmtScope(const BreakStmt *breakStmt) {
-  const Stmt *curNode = breakStmt;
-  do {
-    curNode = getImmediateParent(astContext, curNode);
-  } while (curNode && !isLoopStmt(curNode) && !isa<SwitchStmt>(curNode));
-
-  return curNode;
+  // Some statements that alter the control flow (break, continue, return, and
+  // discard), require creation of a new basic block to hold any statement that
+  // may follow them. In this case, the newly created basic block will contain
+  // any statement that may come after an early return.
+  const uint32_t newBB = theBuilder.createBasicBlock();
+  theBuilder.setInsertPoint(newBB);
 }
 }
 
 
 void SPIRVEmitter::doBreakStmt(const BreakStmt *breakStmt) {
 void SPIRVEmitter::doBreakStmt(const BreakStmt *breakStmt) {
@@ -982,8 +910,10 @@ void SPIRVEmitter::doBreakStmt(const BreakStmt *breakStmt) {
   theBuilder.addSuccessor(breakTargetBB);
   theBuilder.addSuccessor(breakTargetBB);
   theBuilder.createBranch(breakTargetBB);
   theBuilder.createBranch(breakTargetBB);
 
 
-  // If any statements follow a break statement in a loop or switch, they will
-  // not be executed. For example, StmtB and StmtC below are never executed:
+  // Some statements that alter the control flow (break, continue, return, and
+  // discard), require creation of a new basic block to hold any statement that
+  // may follow them. For example: StmtB and StmtC below are put inside a new
+  // basic block which is unreachable.
   //
   //
   // while (true) {
   // while (true) {
   //   StmtA;
   //   StmtA;
@@ -991,26 +921,8 @@ void SPIRVEmitter::doBreakStmt(const BreakStmt *breakStmt) {
   //   StmtB;
   //   StmtB;
   //   StmtC;
   //   StmtC;
   // }
   // }
-  //
-  // To handle such cases, we do not stop tranlsation. We create a new basic
-  // block in which StmtB and StmtC will be translated.
-  // Note that since this basic block is unreachable, BlockReadableOrderVisitor
-  // will not emit it in the final module binary.
-  const Stmt *scope = breakStmtScope(breakStmt);
-  if (
-      // Have unreachable instructions after a break statement in a case of a
-      // switch statement
-      (isa<SwitchStmt>(scope) &&
-       !breakStmtIsLastStmtInCaseStmt(breakStmt,
-                                      dyn_cast<SwitchStmt>(scope))) ||
-      // Have unreachable instructions after a break statement in a loop
-      // statement
-      (isLoopStmt(scope) &&
-       !isLastStmtBeforeControlFlowBranching(astContext, breakStmt))) {
-    const uint32_t unreachableBB =
-        theBuilder.createBasicBlock("unreachable", false);
-    theBuilder.setInsertPoint(unreachableBB);
-  }
+  const uint32_t newBB = theBuilder.createBasicBlock();
+  theBuilder.setInsertPoint(newBB);
 }
 }
 
 
 void SPIRVEmitter::doSwitchStmt(const SwitchStmt *switchStmt,
 void SPIRVEmitter::doSwitchStmt(const SwitchStmt *switchStmt,

+ 0 - 12
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -405,18 +405,6 @@ private:
   /// statement.
   /// statement.
   void processSwitchStmtUsingIfStmts(const SwitchStmt *switchStmt);
   void processSwitchStmtUsingIfStmts(const SwitchStmt *switchStmt);
 
 
-private:
-  /// \brief Returns the statement that the given break statement applies to.
-  /// According to the spec, break statements can only apply to loops (do, for,
-  /// while) or case statements inside a switch statement. The frontend ensures
-  /// this is true (errors out otherwise).
-  const Stmt *breakStmtScope(const BreakStmt *);
-
-  /// \brief Returns true if the given BreakStmt is the last statement inside
-  /// its case statement of the given switch statement. Panics if the given
-  /// break statement is not inside the tree of the given switch statement.
-  bool breakStmtIsLastStmtInCaseStmt(const BreakStmt *, const SwitchStmt *);
-
 private:
 private:
   /// \brief Wrapper method to create an error message and report it
   /// \brief Wrapper method to create an error message and report it
   /// in the diagnostic engine associated with this consumer.
   /// in the diagnostic engine associated with this consumer.

+ 22 - 1
tools/clang/lib/SPIRV/Structure.cpp

@@ -47,12 +47,14 @@ bool Instruction::isTerminator() const {
 // === Basic block implementations ===
 // === Basic block implementations ===
 
 
 BasicBlock::BasicBlock(BasicBlock &&that)
 BasicBlock::BasicBlock(BasicBlock &&that)
-    : labelId(that.labelId), instructions(std::move(that.instructions)) {
+    : labelId(that.labelId), debugName(that.debugName),
+      instructions(std::move(that.instructions)) {
   that.clear();
   that.clear();
 }
 }
 
 
 BasicBlock &BasicBlock::operator=(BasicBlock &&that) {
 BasicBlock &BasicBlock::operator=(BasicBlock &&that) {
   labelId = that.labelId;
   labelId = that.labelId;
+  debugName = that.debugName;
   instructions = std::move(that.instructions);
   instructions = std::move(that.instructions);
 
 
   that.clear();
   that.clear();
@@ -62,6 +64,7 @@ BasicBlock &BasicBlock::operator=(BasicBlock &&that) {
 
 
 void BasicBlock::clear() {
 void BasicBlock::clear() {
   labelId = 0;
   labelId = 0;
+  debugName = "";
   instructions.clear();
   instructions.clear();
 }
 }
 
 
@@ -163,6 +166,14 @@ void Function::addVariable(uint32_t varType, uint32_t varId,
           .take());
           .take());
 }
 }
 
 
+void Function::getReachableBasicBlocks(std::vector<BasicBlock *> *bbVec) const {
+  if (!blocks.empty()) {
+    BlockReadableOrderVisitor(
+        [&bbVec](BasicBlock *block) { bbVec->push_back(block); })
+        .visit(blocks.front().get());
+  }
+}
+
 // === Module components implementations ===
 // === Module components implementations ===
 
 
 Header::Header()
 Header::Header()
@@ -244,6 +255,16 @@ void SPIRVModule::take(InstBuilder *builder) {
     consumer(inst.take());
     consumer(inst.take());
   }
   }
 
 
+  // BasicBlock debug names should be emitted only for blocks that are reachable.
+  // The debug name for a basic block is stored in the basic block object.
+  std::vector<BasicBlock*> reachableBasicBlocks;
+  for (const auto& fn : functions)
+    fn->getReachableBasicBlocks(&reachableBasicBlocks);
+  for (BasicBlock *bb : reachableBasicBlocks)
+    if (!bb->getDebugName().empty())
+      builder->opName(bb->getLabelId(), bb->getDebugName()).x();
+
+  // Emit other debug names
   for (auto &inst : debugNames) {
   for (auto &inst : debugNames) {
     if (inst.memberIndex.hasValue()) {
     if (inst.memberIndex.hasValue()) {
       builder
       builder

+ 23 - 23
tools/clang/test/CodeGenSPIRV/cf.if.for.hlsl

@@ -26,8 +26,8 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-LABEL: %for_check = OpLabel
 // CHECK-LABEL: %for_check = OpLabel
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[lt1:%\d+]] = OpSLessThan %bool [[i0]] %int_10
 // CHECK-NEXT: [[lt1:%\d+]] = OpSLessThan %bool [[i0]] %int_10
-// CHECK-NEXT: OpLoopMerge %for_merge %for_continue None
-// CHECK-NEXT: OpBranchConditional [[lt1]] %for_body %for_merge
+// CHECK-NEXT: OpLoopMerge %for_merge_1 %for_continue_1 None
+// CHECK-NEXT: OpBranchConditional [[lt1]] %for_body %for_merge_1
     for (int i = 0; i < 10; ++i) {
     for (int i = 0; i < 10; ++i) {
 // CHECK-LABEL: %for_body = OpLabel
 // CHECK-LABEL: %for_body = OpLabel
 // CHECK-NEXT: [[color1:%\d+]] = OpLoad %float %color
 // CHECK-NEXT: [[color1:%\d+]] = OpLoad %float %color
@@ -43,21 +43,21 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-LABEL: %for_check_0 = OpLabel
 // CHECK-LABEL: %for_check_0 = OpLabel
 // CHECK-NEXT: [[j0:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[j0:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[lt3:%\d+]] = OpSLessThan %bool [[j0]] %int_15
 // CHECK-NEXT: [[lt3:%\d+]] = OpSLessThan %bool [[j0]] %int_15
-// CHECK-NEXT: OpLoopMerge %for_merge_0 %for_continue_0 None
-// CHECK-NEXT: OpBranchConditional [[lt3]] %for_body_0 %for_merge_0
+// CHECK-NEXT: OpLoopMerge %for_merge %for_continue None
+// CHECK-NEXT: OpBranchConditional [[lt3]] %for_body_0 %for_merge
             for (int j = 0; j < 15; ++j) { // for-stmt deeply nested in if-then
             for (int j = 0; j < 15; ++j) { // for-stmt deeply nested in if-then
 // CHECK-LABEL: %for_body_0 = OpLabel
 // CHECK-LABEL: %for_body_0 = OpLabel
 // CHECK: OpStore %val
 // CHECK: OpStore %val
                 val = val * 2.;
                 val = val * 2.;
-// CHECK-NEXT: OpBranch %for_continue_0
+// CHECK-NEXT: OpBranch %for_continue
 
 
-// CHECK-LABEL: %for_continue_0 = OpLabel
+// CHECK-LABEL: %for_continue = OpLabel
 // CHECK-NEXT: [[j1:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[j1:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[incj:%\d+]] = OpIAdd %int [[j1]] %int_1
 // CHECK-NEXT: [[incj:%\d+]] = OpIAdd %int [[j1]] %int_1
 // CHECK-NEXT: OpStore %j [[incj]]
 // CHECK-NEXT: OpStore %j [[incj]]
 // CHECK-NEXT: OpBranch %for_check_0
 // CHECK-NEXT: OpBranch %for_check_0
             } // end for (int j
             } // end for (int j
-// CHECK-LABEL: %for_merge_0 = OpLabel
+// CHECK-LABEL: %for_merge = OpLabel
 // CHECK: OpStore %val
 // CHECK: OpStore %val
 
 
             val = val + 3.;
             val = val + 3.;
@@ -67,13 +67,13 @@ float4 main(float color: COLOR) : SV_TARGET {
 
 
 // CHECK-NEXT: [[color2:%\d+]] = OpLoad %float %color
 // CHECK-NEXT: [[color2:%\d+]] = OpLoad %float %color
 // CHECK-NEXT: [[lt4:%\d+]] = OpFOrdLessThan %bool [[color2]] %float_0_8
 // CHECK-NEXT: [[lt4:%\d+]] = OpFOrdLessThan %bool [[color2]] %float_0_8
-// CHECK-NEXT: OpSelectionMerge %if_merge_1 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
 // CHECK-NEXT: OpBranchConditional [[lt4]] %if_true_1 %if_false
 // CHECK-NEXT: OpBranchConditional [[lt4]] %if_true_1 %if_false
         if (color < 0.8) { // if-stmt following if-stmt
         if (color < 0.8) { // if-stmt following if-stmt
 // CHECK-LABEL: %if_true_1 = OpLabel
 // CHECK-LABEL: %if_true_1 = OpLabel
 // CHECK: OpStore %val
 // CHECK: OpStore %val
             val = val * 4.;
             val = val * 4.;
-// CHECK-NEXT: OpBranch %if_merge_1
+// CHECK-NEXT: OpBranch %if_merge_2
         } else {
         } else {
 // CHECK-LABEL: %if_false = OpLabel
 // CHECK-LABEL: %if_false = OpLabel
 // CHECK-NEXT: OpBranch %for_check_1
 // CHECK-NEXT: OpBranch %for_check_1
@@ -81,8 +81,8 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-LABEL: %for_check_1 = OpLabel
 // CHECK-LABEL: %for_check_1 = OpLabel
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[lt5:%\d+]] = OpSLessThan %bool [[k0]] %int_20
 // CHECK-NEXT: [[lt5:%\d+]] = OpSLessThan %bool [[k0]] %int_20
-// CHECK-NEXT: OpLoopMerge %for_merge_1 %for_continue_1 None
-// CHECK-NEXT: OpBranchConditional [[lt5]] %for_body_1 %for_merge_1
+// CHECK-NEXT: OpLoopMerge %for_merge_0 %for_continue_0 None
+// CHECK-NEXT: OpBranchConditional [[lt5]] %for_body_1 %for_merge_0
             for (int k = 0; k < 20; ++k) { // for-stmt deeply nested in if-else
             for (int k = 0; k < 20; ++k) { // for-stmt deeply nested in if-else
 // CHECK-LABEL: %for_body_1 = OpLabel
 // CHECK-LABEL: %for_body_1 = OpLabel
 // CHECK: OpStore %val
 // CHECK: OpStore %val
@@ -90,36 +90,36 @@ float4 main(float color: COLOR) : SV_TARGET {
 
 
 // CHECK-NEXT: [[val5:%\d+]] = OpLoad %float %val
 // CHECK-NEXT: [[val5:%\d+]] = OpLoad %float %val
 // CHECK-NEXT: [[lt6:%\d+]] = OpFOrdLessThan %bool [[val5]] %float_0
 // CHECK-NEXT: [[lt6:%\d+]] = OpFOrdLessThan %bool [[val5]] %float_0
-// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
-// CHECK-NEXT: OpBranchConditional [[lt6]] %if_true_2 %if_merge_2
+// CHECK-NEXT: OpSelectionMerge %if_merge_1 None
+// CHECK-NEXT: OpBranchConditional [[lt6]] %if_true_2 %if_merge_1
                 if (val < 0.) { // deeply nested if-stmt
                 if (val < 0.) { // deeply nested if-stmt
 // CHECK-LABEL: %if_true_2 = OpLabel
 // CHECK-LABEL: %if_true_2 = OpLabel
 // CHECK: OpStore %val
 // CHECK: OpStore %val
                     val = val + 100.;
                     val = val + 100.;
-// CHECK-NEXT: OpBranch %if_merge_2
+// CHECK-NEXT: OpBranch %if_merge_1
                 }
                 }
-// CHECK-LABEL: %if_merge_2 = OpLabel
-// CHECK-NEXT: OpBranch %for_continue_1
+// CHECK-LABEL: %if_merge_1 = OpLabel
+// CHECK-NEXT: OpBranch %for_continue_0
 
 
-// CHECK-LABEL: %for_continue_1 = OpLabel
+// CHECK-LABEL: %for_continue_0 = OpLabel
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[inck:%\d+]] = OpIAdd %int [[k1]] %int_1
 // CHECK-NEXT: [[inck:%\d+]] = OpIAdd %int [[k1]] %int_1
 // CHECK-NEXT: OpStore %k [[inck]]
 // CHECK-NEXT: OpStore %k [[inck]]
 // CHECK-NEXT: OpBranch %for_check_1
 // CHECK-NEXT: OpBranch %for_check_1
             } // end for (int k
             } // end for (int k
-// CHECK-LABEL: %for_merge_1 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_1
+// CHECK-LABEL: %for_merge_0 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_2
         } // end elsek
         } // end elsek
-// CHECK-LABEL: %if_merge_1 = OpLabel
-// CHECK-NEXT: OpBranch %for_continue
+// CHECK-LABEL: %if_merge_2 = OpLabel
+// CHECK-NEXT: OpBranch %for_continue_1
 
 
-// CHECK-LABEL: %for_continue = OpLabel
+// CHECK-LABEL: %for_continue_1 = OpLabel
 // CHECK-NEXT: [[i1:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i1:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[inci:%\d+]] = OpIAdd %int [[i1]] %int_1
 // CHECK-NEXT: [[inci:%\d+]] = OpIAdd %int [[i1]] %int_1
 // CHECK-NEXT: OpStore %i [[inci]]
 // CHECK-NEXT: OpStore %i [[inci]]
 // CHECK-NEXT: OpBranch %for_check
 // CHECK-NEXT: OpBranch %for_check
     } // end for (int i
     } // end for (int i
-// CHECK-LABEL: %for_merge = OpLabel
+// CHECK-LABEL: %for_merge_1 = OpLabel
 
 
     // if-stmt following for-stmt
     // if-stmt following for-stmt
 // CHECK-NEXT: [[color3:%\d+]] = OpLoad %float %color
 // CHECK-NEXT: [[color3:%\d+]] = OpLoad %float %color

+ 2 - 2
tools/clang/test/CodeGenSPIRV/constant-ps.hlsl2spv

@@ -8,16 +8,16 @@ float4 main(): SV_TARGET
 // ; SPIR-V
 // ; SPIR-V
 // ; Version: 1.0
 // ; Version: 1.0
 // ; Generator: Google spiregg; 0
 // ; Generator: Google spiregg; 0
-// ; Bound: 18
+// ; Bound: 19
 // ; Schema: 0
 // ; Schema: 0
 // OpCapability Shader
 // OpCapability Shader
 // OpMemoryModel Logical GLSL450
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Fragment %main "main" %out_var_SV_Target
 // OpEntryPoint Fragment %main "main" %out_var_SV_Target
 // OpExecutionMode %main OriginUpperLeft
 // OpExecutionMode %main OriginUpperLeft
+// OpName %bb_entry "bb.entry"
 // OpName %main "main"
 // OpName %main "main"
 // OpName %out_var_SV_Target "out.var.SV_Target"
 // OpName %out_var_SV_Target "out.var.SV_Target"
 // OpName %src_main "src.main"
 // OpName %src_main "src.main"
-// OpName %bb_entry "bb.entry"
 // OpDecorate %out_var_SV_Target Location 0
 // OpDecorate %out_var_SV_Target Location 0
 // %void = OpTypeVoid
 // %void = OpTypeVoid
 // %3 = OpTypeFunction %void
 // %3 = OpTypeFunction %void

+ 10 - 10
tools/clang/test/CodeGenSPIRV/do-stmt.break.hlsl

@@ -43,29 +43,29 @@ void main() {
 // CHECK-NEXT: OpBranch %do_while_header_0
 // CHECK-NEXT: OpBranch %do_while_header_0
 
 
 // CHECK-NEXT: %do_while_header_0 = OpLabel
 // CHECK-NEXT: %do_while_header_0 = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge_0 %do_while_continue_0 None
+// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 None
 // CHECK-NEXT: OpBranch %do_while_body_0
 // CHECK-NEXT: OpBranch %do_while_body_0
   do {
   do {
 // CHECK-NEXT: %do_while_body_0 = OpLabel
 // CHECK-NEXT: %do_while_body_0 = OpLabel
     ++i;
     ++i;
 // CHECK:      OpBranch %do_while_header_1
 // CHECK:      OpBranch %do_while_header_1
 // CHECK-NEXT: %do_while_header_1 = OpLabel
 // CHECK-NEXT: %do_while_header_1 = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 None
+// CHECK-NEXT: OpLoopMerge %do_while_merge_0 %do_while_continue_0 None
 // CHECK-NEXT: OpBranch %do_while_body_1
 // CHECK-NEXT: OpBranch %do_while_body_1
     do {
     do {
 // CHECK-NEXT: %do_while_body_1 = OpLabel
 // CHECK-NEXT: %do_while_body_1 = OpLabel
       ++val;
       ++val;
-// CHECK:      OpBranch %do_while_merge_1
+// CHECK:      OpBranch %do_while_merge_0
       break;
       break;
-// CHECK-NEXT: %do_while_continue_1 = OpLabel
-// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_1 %do_while_merge_1
+// CHECK-NEXT: %do_while_continue_0 = OpLabel
+// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_1 %do_while_merge_0
     } while (i < 10);
     } while (i < 10);
-// CHECK-NEXT: %do_while_merge_1 = OpLabel
+// CHECK-NEXT: %do_while_merge_0 = OpLabel
     --i;
     --i;
-// CHECK:      OpBranch %do_while_merge_0
+// CHECK:      OpBranch %do_while_merge_1
     {break;}
     {break;}
-// CHECK-NEXT: %do_while_continue_0 = OpLabel
-// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_0 %do_while_merge_0
+// CHECK-NEXT: %do_while_continue_1 = OpLabel
+// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_0 %do_while_merge_1
   } while(val < 10);
   } while(val < 10);
-// CHECK-NEXT: %do_while_merge_0 = OpLabel
+// CHECK-NEXT: %do_while_merge_1 = OpLabel
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/do-stmt.continue.hlsl

@@ -44,31 +44,31 @@ void main() {
 // CHECK-NEXT: OpBranch %do_while_header_0
 // CHECK-NEXT: OpBranch %do_while_header_0
 
 
 // CHECK-NEXT: %do_while_header_0 = OpLabel
 // CHECK-NEXT: %do_while_header_0 = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge_0 %do_while_continue_0 None
+// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 None
 // CHECK-NEXT: OpBranch %do_while_body_0
 // CHECK-NEXT: OpBranch %do_while_body_0
   do {
   do {
 // CHECK-NEXT: %do_while_body_0 = OpLabel
 // CHECK-NEXT: %do_while_body_0 = OpLabel
     ++i;
     ++i;
 // CHECK:      OpBranch %do_while_header_1
 // CHECK:      OpBranch %do_while_header_1
 // CHECK-NEXT: %do_while_header_1 = OpLabel
 // CHECK-NEXT: %do_while_header_1 = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 None
+// CHECK-NEXT: OpLoopMerge %do_while_merge_0 %do_while_continue_0 None
 // CHECK-NEXT: OpBranch %do_while_body_1
 // CHECK-NEXT: OpBranch %do_while_body_1
     do {
     do {
 // CHECK-NEXT: %do_while_body_1 = OpLabel
 // CHECK-NEXT: %do_while_body_1 = OpLabel
       ++val;
       ++val;
-// CHECK:      OpBranch %do_while_continue_1
+// CHECK:      OpBranch %do_while_continue_0
       continue;
       continue;
-// CHECK-NEXT: %do_while_continue_1 = OpLabel
-// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_1 %do_while_merge_1
+// CHECK-NEXT: %do_while_continue_0 = OpLabel
+// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_1 %do_while_merge_0
     } while (i < 10);
     } while (i < 10);
-// CHECK-NEXT: %do_while_merge_1 = OpLabel
+// CHECK-NEXT: %do_while_merge_0 = OpLabel
     --i;
     --i;
-// CHECK:      OpBranch %do_while_continue_0
+// CHECK:      OpBranch %do_while_continue_1
     continue;
     continue;
     continue;  // No SPIR-V should be emitted for this statement.
     continue;  // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %do_while_continue_0 = OpLabel
-// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_0 %do_while_merge_0
+// CHECK-NEXT: %do_while_continue_1 = OpLabel
+// CHECK:      OpBranchConditional {{%\d+}} %do_while_header_0 %do_while_merge_1
   } while(val < 10);
   } while(val < 10);
-// CHECK-NEXT: %do_while_merge_0 = OpLabel
+// CHECK-NEXT: %do_while_merge_1 = OpLabel
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/do-stmt.nested.hlsl

@@ -5,7 +5,7 @@ void main() {
 
 
 // CHECK:      OpBranch %do_while_header
 // CHECK:      OpBranch %do_while_header
 // CHECK-NEXT: %do_while_header = OpLabel
 // CHECK-NEXT: %do_while_header = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge %do_while_continue DontUnroll
+// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 DontUnroll
   [loop] do {
   [loop] do {
 // CHECK-NEXT: OpBranch %do_while_body
 // CHECK-NEXT: OpBranch %do_while_body
 // CHECK-NEXT: %do_while_body = OpLabel
 // CHECK-NEXT: %do_while_body = OpLabel
@@ -23,22 +23,22 @@ void main() {
 // CHECK-NEXT: OpBranch %do_while_header_1
 // CHECK-NEXT: OpBranch %do_while_header_1
 
 
 // CHECK-NEXT: %do_while_header_1 = OpLabel
 // CHECK-NEXT: %do_while_header_1 = OpLabel
-// CHECK-NEXT: OpLoopMerge %do_while_merge_1 %do_while_continue_1 DontUnroll
+// CHECK-NEXT: OpLoopMerge %do_while_merge %do_while_continue DontUnroll
 // CHECK-NEXT: OpBranch %do_while_body_1
 // CHECK-NEXT: OpBranch %do_while_body_1
       [fastopt] do {
       [fastopt] do {
 // CHECK-NEXT: %do_while_body_1 = OpLabel
 // CHECK-NEXT: %do_while_body_1 = OpLabel
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k_plus_1:%\d+]] = OpIAdd %int [[k0]] %int_1
 // CHECK-NEXT: [[k_plus_1:%\d+]] = OpIAdd %int [[k0]] %int_1
 // CHECK-NEXT: OpStore %k [[k_plus_1]]
 // CHECK-NEXT: OpStore %k [[k_plus_1]]
-// CHECK-NEXT: OpBranch %do_while_continue_1
+// CHECK-NEXT: OpBranch %do_while_continue
         ++k;
         ++k;
-// CHECK-NEXT: %do_while_continue_1 = OpLabel
+// CHECK-NEXT: %do_while_continue = OpLabel
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k_lt_30:%\d+]] = OpSLessThan %bool [[k1]] %int_30
 // CHECK-NEXT: [[k_lt_30:%\d+]] = OpSLessThan %bool [[k1]] %int_30
-// CHECK-NEXT: OpBranchConditional [[k_lt_30]] %do_while_header_1 %do_while_merge_1
+// CHECK-NEXT: OpBranchConditional [[k_lt_30]] %do_while_header_1 %do_while_merge
       } while (k < 30);
       } while (k < 30);
 
 
-// CHECK-NEXT: %do_while_merge_1 = OpLabel
+// CHECK-NEXT: %do_while_merge = OpLabel
 // CHECK-NEXT: [[j0:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[j0:%\d+]] = OpLoad %int %j
 // CHECK-NEXT: [[j_plus_1:%\d+]] = OpIAdd %int [[j0]] %int_1
 // CHECK-NEXT: [[j_plus_1:%\d+]] = OpIAdd %int [[j0]] %int_1
 // CHECK-NEXT: OpStore %j [[j_plus_1]]
 // CHECK-NEXT: OpStore %j [[j_plus_1]]
@@ -54,15 +54,15 @@ void main() {
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i_plus_1:%\d+]] = OpIAdd %int [[i0]] %int_1
 // CHECK-NEXT: [[i_plus_1:%\d+]] = OpIAdd %int [[i0]] %int_1
 // CHECK-NEXT: OpStore %i [[i_plus_1]]
 // CHECK-NEXT: OpStore %i [[i_plus_1]]
-// CHECK-NEXT: OpBranch %do_while_continue
+// CHECK-NEXT: OpBranch %do_while_continue_1
     ++i;
     ++i;
 
 
-// CHECK-NEXT: %do_while_continue = OpLabel
+// CHECK-NEXT: %do_while_continue_1 = OpLabel
 // CHECK-NEXT: [[i1:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i1:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i_lt_10:%\d+]] = OpSLessThan %bool [[i1]] %int_10
 // CHECK-NEXT: [[i_lt_10:%\d+]] = OpSLessThan %bool [[i1]] %int_10
-// CHECK-NEXT: OpBranchConditional [[i_lt_10]] %do_while_header %do_while_merge
+// CHECK-NEXT: OpBranchConditional [[i_lt_10]] %do_while_header %do_while_merge_1
   } while (i < 10);
   } while (i < 10);
-// CHECK-NEXT: %do_while_merge = OpLabel
+// CHECK-NEXT: %do_while_merge_1 = OpLabel
 
 
 
 
 // CHECK-NEXT: OpReturn
 // CHECK-NEXT: OpReturn

+ 1 - 1
tools/clang/test/CodeGenSPIRV/empty-void-main.hlsl2spv

@@ -14,9 +14,9 @@ void main()
 // OpMemoryModel Logical GLSL450
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Fragment %main "main"
 // OpEntryPoint Fragment %main "main"
 // OpExecutionMode %main OriginUpperLeft
 // OpExecutionMode %main OriginUpperLeft
+// OpName %bb_entry "bb.entry"
 // OpName %main "main"
 // OpName %main "main"
 // OpName %src_main "src.main"
 // OpName %src_main "src.main"
-// OpName %bb_entry "bb.entry"
 // %void = OpTypeVoid
 // %void = OpTypeVoid
 // %3 = OpTypeFunction %void
 // %3 = OpTypeFunction %void
 // %main = OpFunction %void None %3
 // %main = OpFunction %void None %3

+ 10 - 10
tools/clang/test/CodeGenSPIRV/for-stmt.break.hlsl

@@ -37,35 +37,35 @@ void main() {
   ////////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////////
 
 
 // CHECK-NEXT: %for_check_0 = OpLabel
 // CHECK-NEXT: %for_check_0 = OpLabel
-// CHECK:      OpLoopMerge %for_merge_0 %for_continue_0 None
-// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_0 %for_merge_0
+// CHECK:      OpLoopMerge %for_merge_1 %for_continue_1 None
+// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_0 %for_merge_1
   for (int j = 0; j < 10; ++j) {
   for (int j = 0; j < 10; ++j) {
 // CHECK-NEXT: %for_body_0 = OpLabel
 // CHECK-NEXT: %for_body_0 = OpLabel
     val = j+5;
     val = j+5;
 // CHECK:      OpBranch %for_check_1
 // CHECK:      OpBranch %for_check_1
 
 
 // CHECK-NEXT: %for_check_1 = OpLabel
 // CHECK-NEXT: %for_check_1 = OpLabel
-// CHECK:      OpLoopMerge %for_merge_1 %for_continue_1 None
-// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_1 %for_merge_1
+// CHECK:      OpLoopMerge %for_merge_0 %for_continue_0 None
+// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_1 %for_merge_0
     for ( ; val < 20; ++val) {
     for ( ; val < 20; ++val) {
 // CHECK-NEXT: %for_body_1 = OpLabel
 // CHECK-NEXT: %for_body_1 = OpLabel
       int k = val + j;
       int k = val + j;
-// CHECK:      OpBranch %for_merge_1
+// CHECK:      OpBranch %for_merge_0
       {{break;}}
       {{break;}}
       k++; // No SPIR-V should be emitted for this statement.
       k++; // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %for_continue_1 = OpLabel
+// CHECK-NEXT: %for_continue_0 = OpLabel
 // CHECK:      OpBranch %for_check_1
 // CHECK:      OpBranch %for_check_1
     }
     }
-// CHECK-NEXT: %for_merge_1 = OpLabel
+// CHECK-NEXT: %for_merge_0 = OpLabel
     val--;
     val--;
-// CHECK:      OpBranch %for_merge_0
+// CHECK:      OpBranch %for_merge_1
     break;
     break;
     break;        // No SPIR-V should be emitted for this statement.
     break;        // No SPIR-V should be emitted for this statement.
     val = val*10; // No SPIR-V should be emitted for this statement.
     val = val*10; // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %for_continue_0 = OpLabel
+// CHECK-NEXT: %for_continue_1 = OpLabel
 // CHECK:      OpBranch %for_check_0
 // CHECK:      OpBranch %for_check_0
   }
   }
-// CHECK-NEXT: %for_merge_0 = OpLabel
+// CHECK-NEXT: %for_merge_1 = OpLabel
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/for-stmt.continue.hlsl

@@ -39,35 +39,35 @@ void main() {
   //////////////////////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////////////////////
 
 
 // CHECK-NEXT: %for_check_0 = OpLabel
 // CHECK-NEXT: %for_check_0 = OpLabel
-// CHECK:      OpLoopMerge %for_merge_0 %for_continue_0 None
-// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_0 %for_merge_0
+// CHECK:      OpLoopMerge %for_merge_1 %for_continue_1 None
+// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_0 %for_merge_1
   for (int j = 0; j < 10; ++j) {
   for (int j = 0; j < 10; ++j) {
 // CHECK-NEXT: %for_body_0 = OpLabel
 // CHECK-NEXT: %for_body_0 = OpLabel
     val = j+5;
     val = j+5;
 // CHECK:      OpBranch %for_check_1
 // CHECK:      OpBranch %for_check_1
 
 
 // CHECK-NEXT: %for_check_1 = OpLabel
 // CHECK-NEXT: %for_check_1 = OpLabel
-// CHECK:      OpLoopMerge %for_merge_1 %for_continue_1 None
-// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_1 %for_merge_1
+// CHECK:      OpLoopMerge %for_merge_0 %for_continue_0 None
+// CHECK-NEXT: OpBranchConditional {{%\d+}} %for_body_1 %for_merge_0
     for ( ; val < 20; ++val) {
     for ( ; val < 20; ++val) {
 // CHECK-NEXT: %for_body_1 = OpLabel
 // CHECK-NEXT: %for_body_1 = OpLabel
       int k = val + j;
       int k = val + j;
-// CHECK:      OpBranch %for_continue_1
+// CHECK:      OpBranch %for_continue_0
       continue;
       continue;
       k++;      // No SPIR-V should be emitted for this statement.
       k++;      // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %for_continue_1 = OpLabel
+// CHECK-NEXT: %for_continue_0 = OpLabel
 // CHECK:      OpBranch %for_check_1
 // CHECK:      OpBranch %for_check_1
     }
     }
-// CHECK-NEXT: %for_merge_1 = OpLabel
+// CHECK-NEXT: %for_merge_0 = OpLabel
     val--;
     val--;
-// CHECK:      OpBranch %for_continue_0
+// CHECK:      OpBranch %for_continue_1
     continue;
     continue;
     continue;     // No SPIR-V should be emitted for this statement.
     continue;     // No SPIR-V should be emitted for this statement.
     val = val*10; // No SPIR-V should be emitted for this statement.
     val = val*10; // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %for_continue_0 = OpLabel
+// CHECK-NEXT: %for_continue_1 = OpLabel
 // CHECK:      OpBranch %for_check_0
 // CHECK:      OpBranch %for_check_0
   }
   }
-// CHECK-NEXT: %for_merge_0 = OpLabel
+// CHECK-NEXT: %for_merge_1 = OpLabel
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/for-stmt.nested.hlsl

@@ -13,8 +13,8 @@ void main() {
 // CHECK-LABEL: %for_check = OpLabel
 // CHECK-LABEL: %for_check = OpLabel
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[lt0:%\d+]] = OpSLessThan %bool [[i0]] %int_10
 // CHECK-NEXT: [[lt0:%\d+]] = OpSLessThan %bool [[i0]] %int_10
-// CHECK-NEXT: OpLoopMerge %for_merge %for_continue Unroll
-// CHECK-NEXT: OpBranchConditional [[lt0]] %for_body %for_merge
+// CHECK-NEXT: OpLoopMerge %for_merge_1 %for_continue_1 Unroll
+// CHECK-NEXT: OpBranchConditional [[lt0]] %for_body %for_merge_1
     [unroll] for (int i = 0; i < 10; ++i) {
     [unroll] for (int i = 0; i < 10; ++i) {
 // CHECK-LABEL: %for_body = OpLabel
 // CHECK-LABEL: %for_body = OpLabel
 // CHECK-NEXT: [[val0:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val0:%\d+]] = OpLoad %int %val
@@ -36,25 +36,25 @@ void main() {
 // CHECK-LABEL: %for_check_1 = OpLabel
 // CHECK-LABEL: %for_check_1 = OpLabel
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[lt2:%\d+]] = OpSLessThan %bool [[k0]] %int_10
 // CHECK-NEXT: [[lt2:%\d+]] = OpSLessThan %bool [[k0]] %int_10
-// CHECK-NEXT: OpLoopMerge %for_merge_1 %for_continue_1 DontUnroll
-// CHECK-NEXT: OpBranchConditional [[lt2]] %for_body_1 %for_merge_1
+// CHECK-NEXT: OpLoopMerge %for_merge %for_continue DontUnroll
+// CHECK-NEXT: OpBranchConditional [[lt2]] %for_body_1 %for_merge
             [fastopt] for (int k = 0; k < 10; ++k) {
             [fastopt] for (int k = 0; k < 10; ++k) {
 // CHECK-LABEL: %for_body_1 = OpLabel
 // CHECK-LABEL: %for_body_1 = OpLabel
 // CHECK-NEXT: [[val1:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val1:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k1:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[add1:%\d+]] = OpIAdd %int [[val1]] [[k1]]
 // CHECK-NEXT: [[add1:%\d+]] = OpIAdd %int [[val1]] [[k1]]
 // CHECK-NEXT: OpStore %val [[add1]]
 // CHECK-NEXT: OpStore %val [[add1]]
-// CHECK-NEXT: OpBranch %for_continue_1
+// CHECK-NEXT: OpBranch %for_continue
                 val = val + k;
                 val = val + k;
 
 
-// CHECK-LABEL: %for_continue_1 = OpLabel
+// CHECK-LABEL: %for_continue = OpLabel
 // CHECK-NEXT: [[k2:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k2:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[add2:%\d+]] = OpIAdd %int [[k2]] %int_1
 // CHECK-NEXT: [[add2:%\d+]] = OpIAdd %int [[k2]] %int_1
 // CHECK-NEXT: OpStore %k [[add2]]
 // CHECK-NEXT: OpStore %k [[add2]]
 // CHECK-NEXT: OpBranch %for_check_1
 // CHECK-NEXT: OpBranch %for_check_1
             }
             }
 
 
-// CHECK-LABEL: %for_merge_1 = OpLabel
+// CHECK-LABEL: %for_merge = OpLabel
 // CHECK-NEXT: [[val2:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val2:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[mul0:%\d+]] = OpIMul %int [[val2]] %int_2
 // CHECK-NEXT: [[mul0:%\d+]] = OpIMul %int [[val2]] %int_2
 // CHECK-NEXT: OpStore %val [[mul0]]
 // CHECK-NEXT: OpStore %val [[mul0]]
@@ -68,15 +68,15 @@ void main() {
 // CHECK-NEXT: OpBranch %for_check_0
 // CHECK-NEXT: OpBranch %for_check_0
         }
         }
 // CHECK-LABEL: %for_merge_0 = OpLabel
 // CHECK-LABEL: %for_merge_0 = OpLabel
-// CHECK-NEXT: OpBranch %for_continue
+// CHECK-NEXT: OpBranch %for_continue_1
 
 
-// CHECK-LABEL: %for_continue = OpLabel
+// CHECK-LABEL: %for_continue_1 = OpLabel
 // CHECK-NEXT: [[i2:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i2:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[add4:%\d+]] = OpIAdd %int [[i2]] %int_1
 // CHECK-NEXT: [[add4:%\d+]] = OpIAdd %int [[i2]] %int_1
 // CHECK-NEXT: OpStore %i [[add4]]
 // CHECK-NEXT: OpStore %i [[add4]]
 // CHECK-NEXT: OpBranch %for_check
 // CHECK-NEXT: OpBranch %for_check
     }
     }
 
 
-// CHECK-LABEL: %for_merge = OpLabel
+// CHECK-LABEL: %for_merge_1 = OpLabel
 // CHECK-NEXT: OpReturn
 // CHECK-NEXT: OpReturn
 }
 }

+ 12 - 12
tools/clang/test/CodeGenSPIRV/if-stmt.nested.hlsl

@@ -6,22 +6,22 @@ void main() {
     int val = 0;
     int val = 0;
 
 
 // CHECK:      [[c1:%\d+]] = OpLoad %bool %c1
 // CHECK:      [[c1:%\d+]] = OpLoad %bool %c1
-// CHECK-NEXT: OpSelectionMerge %if_merge None
+// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
 // CHECK-NEXT: OpBranchConditional [[c1]] %if_true %if_false
 // CHECK-NEXT: OpBranchConditional [[c1]] %if_true %if_false
     if (c1) {
     if (c1) {
 // CHECK-LABEL: %if_true = OpLabel
 // CHECK-LABEL: %if_true = OpLabel
 
 
 // CHECK-NEXT: [[c2:%\d+]] = OpLoad %bool %c2
 // CHECK-NEXT: [[c2:%\d+]] = OpLoad %bool %c2
-// CHECK-NEXT: OpSelectionMerge %if_merge_0 None
-// CHECK-NEXT: OpBranchConditional [[c2]] %if_true_0 %if_merge_0
+// CHECK-NEXT: OpSelectionMerge %if_merge None
+// CHECK-NEXT: OpBranchConditional [[c2]] %if_true_0 %if_merge
         if (c2)
         if (c2)
 // CHECK-LABEL: %if_true_0 = OpLabel
 // CHECK-LABEL: %if_true_0 = OpLabel
 // CHECK-NEXT: OpStore %val %int_1
 // CHECK-NEXT: OpStore %val %int_1
-// CHECK-NEXT: OpBranch %if_merge_0
+// CHECK-NEXT: OpBranch %if_merge
             val = 1;
             val = 1;
 
 
-// CHECK-LABEL: %if_merge_0 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge
+// CHECK-LABEL: %if_merge = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_2
     } else {
     } else {
 // CHECK-LABEL: %if_false = OpLabel
 // CHECK-LABEL: %if_false = OpLabel
 
 
@@ -38,23 +38,23 @@ void main() {
 // CHECK-LABEL: %if_false_0 = OpLabel
 // CHECK-LABEL: %if_false_0 = OpLabel
 
 
 // CHECK-NEXT: [[c4:%\d+]] = OpLoad %bool %c4
 // CHECK-NEXT: [[c4:%\d+]] = OpLoad %bool %c4
-// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
-// CHECK-NEXT: OpBranchConditional [[c4]] %if_true_2 %if_merge_2
+// CHECK-NEXT: OpSelectionMerge %if_merge_0 None
+// CHECK-NEXT: OpBranchConditional [[c4]] %if_true_2 %if_merge_0
             if (c4) {
             if (c4) {
 // CHECK-LABEL: %if_true_2 = OpLabel
 // CHECK-LABEL: %if_true_2 = OpLabel
 // CHECK-NEXT: OpStore %val %int_3
 // CHECK-NEXT: OpStore %val %int_3
-// CHECK-NEXT: OpBranch %if_merge_2
+// CHECK-NEXT: OpBranch %if_merge_0
                 val = 3;
                 val = 3;
             }
             }
 
 
-// CHECK-LABEL: %if_merge_2 = OpLabel
+// CHECK-LABEL: %if_merge_0 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge_1
 // CHECK-NEXT: OpBranch %if_merge_1
         }
         }
 
 
 // CHECK-LABEL: %if_merge_1 = OpLabel
 // CHECK-LABEL: %if_merge_1 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge
+// CHECK-NEXT: OpBranch %if_merge_2
     }
     }
 
 
-// CHECK-LABEL: %if_merge = OpLabel
+// CHECK-LABEL: %if_merge_2 = OpLabel
 // CHECK-NEXT: OpReturn
 // CHECK-NEXT: OpReturn
 }
 }

+ 2 - 2
tools/clang/test/CodeGenSPIRV/passthru-ps.hlsl2spv

@@ -9,19 +9,19 @@ float4 main(float4 input: COLOR): SV_TARGET
 // ; SPIR-V
 // ; SPIR-V
 // ; Version: 1.0
 // ; Version: 1.0
 // ; Generator: Google spiregg; 0
 // ; Generator: Google spiregg; 0
-// ; Bound: 20
+// ; Bound: 21
 // ; Schema: 0
 // ; Schema: 0
 // OpCapability Shader
 // OpCapability Shader
 // OpMemoryModel Logical GLSL450
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
 // OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
 // OpExecutionMode %main OriginUpperLeft
 // OpExecutionMode %main OriginUpperLeft
+// OpName %bb_entry "bb.entry"
 // OpName %main "main"
 // OpName %main "main"
 // OpName %param_var_input "param.var.input"
 // OpName %param_var_input "param.var.input"
 // OpName %in_var_COLOR "in.var.COLOR"
 // OpName %in_var_COLOR "in.var.COLOR"
 // OpName %out_var_SV_Target "out.var.SV_Target"
 // OpName %out_var_SV_Target "out.var.SV_Target"
 // OpName %src_main "src.main"
 // OpName %src_main "src.main"
 // OpName %input "input"
 // OpName %input "input"
-// OpName %bb_entry "bb.entry"
 // OpDecorate %in_var_COLOR Location 0
 // OpDecorate %in_var_COLOR Location 0
 // OpDecorate %out_var_SV_Target Location 0
 // OpDecorate %out_var_SV_Target Location 0
 // %void = OpTypeVoid
 // %void = OpTypeVoid

+ 2 - 2
tools/clang/test/CodeGenSPIRV/passthru-vs.hlsl2spv

@@ -17,11 +17,12 @@ PSInput VSmain(float4 position: POSITION, float4 color: COLOR) {
 // ; SPIR-V
 // ; SPIR-V
 // ; Version: 1.0
 // ; Version: 1.0
 // ; Generator: Google spiregg; 0
 // ; Generator: Google spiregg; 0
-// ; Bound: 37
+// ; Bound: 38
 // ; Schema: 0
 // ; Schema: 0
 // OpCapability Shader
 // OpCapability Shader
 // OpMemoryModel Logical GLSL450
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Vertex %VSmain "VSmain" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
 // OpEntryPoint Vertex %VSmain "VSmain" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
+// OpName %bb_entry "bb.entry"
 // OpName %VSmain "VSmain"
 // OpName %VSmain "VSmain"
 // OpName %param_var_position "param.var.position"
 // OpName %param_var_position "param.var.position"
 // OpName %in_var_POSITION "in.var.POSITION"
 // OpName %in_var_POSITION "in.var.POSITION"
@@ -34,7 +35,6 @@ PSInput VSmain(float4 position: POSITION, float4 color: COLOR) {
 // OpName %src_VSmain "src.VSmain"
 // OpName %src_VSmain "src.VSmain"
 // OpName %position "position"
 // OpName %position "position"
 // OpName %color "color"
 // OpName %color "color"
-// OpName %bb_entry "bb.entry"
 // OpName %result "result"
 // OpName %result "result"
 // OpDecorate %gl_Position BuiltIn Position
 // OpDecorate %gl_Position BuiltIn Position
 // OpDecorate %in_var_POSITION Location 0
 // OpDecorate %in_var_POSITION Location 0

+ 64 - 64
tools/clang/test/CodeGenSPIRV/switch-stmt.ifstmt.hlsl

@@ -25,26 +25,26 @@ void main() {
 
 
 // CHECK-NEXT: [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_1:%\d+]] = OpIEqual %bool [[a0]] %int_1
 // CHECK-NEXT: [[is_a_1:%\d+]] = OpIEqual %bool [[a0]] %int_1
-// CHECK-NEXT: OpSelectionMerge %if_merge None
+// CHECK-NEXT: OpSelectionMerge %if_merge_0 None
 // CHECK-NEXT: OpBranchConditional [[is_a_1]] %if_true %if_false
 // CHECK-NEXT: OpBranchConditional [[is_a_1]] %if_true %if_false
 // CHECK-NEXT: %if_true = OpLabel
 // CHECK-NEXT: %if_true = OpLabel
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: OpStore %b %int_1
-// CHECK-NEXT: OpBranch %if_merge
+// CHECK-NEXT: OpBranch %if_merge_0
 // CHECK-NEXT: %if_false = OpLabel
 // CHECK-NEXT: %if_false = OpLabel
 // CHECK-NEXT: [[a1:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a1:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_2:%\d+]] = OpIEqual %bool [[a1]] %int_2
 // CHECK-NEXT: [[is_a_2:%\d+]] = OpIEqual %bool [[a1]] %int_2
-// CHECK-NEXT: OpSelectionMerge %if_merge_0 None
+// CHECK-NEXT: OpSelectionMerge %if_merge None
 // CHECK-NEXT: OpBranchConditional [[is_a_2]] %if_true_0 %if_false_0
 // CHECK-NEXT: OpBranchConditional [[is_a_2]] %if_true_0 %if_false_0
 // CHECK-NEXT: %if_true_0 = OpLabel
 // CHECK-NEXT: %if_true_0 = OpLabel
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_0
+// CHECK-NEXT: OpBranch %if_merge
 // CHECK-NEXT: %if_false_0 = OpLabel
 // CHECK-NEXT: %if_false_0 = OpLabel
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: OpStore %b %int_1
-// CHECK-NEXT: OpBranch %if_merge_0
-// CHECK-NEXT: %if_merge_0 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge
 // CHECK-NEXT: OpBranch %if_merge
 // CHECK-NEXT: %if_merge = OpLabel
 // CHECK-NEXT: %if_merge = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_0
+// CHECK-NEXT: %if_merge_0 = OpLabel
   [branch] switch(a) {
   [branch] switch(a) {
     default:
     default:
       b=0;
       b=0;
@@ -62,28 +62,28 @@ void main() {
 
 
 // CHECK-NEXT: [[a2:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a2:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_10:%\d+]] = OpIEqual %bool [[a2]] %int_10
 // CHECK-NEXT: [[is_a_10:%\d+]] = OpIEqual %bool [[a2]] %int_10
-// CHECK-NEXT: OpSelectionMerge %if_merge_1 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
 // CHECK-NEXT: OpBranchConditional [[is_a_10]] %if_true_1 %if_false_1
 // CHECK-NEXT: OpBranchConditional [[is_a_10]] %if_true_1 %if_false_1
 // CHECK-NEXT: %if_true_1 = OpLabel
 // CHECK-NEXT: %if_true_1 = OpLabel
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_1
+// CHECK-NEXT: OpBranch %if_merge_2
 // CHECK-NEXT: %if_false_1 = OpLabel
 // CHECK-NEXT: %if_false_1 = OpLabel
 // CHECK-NEXT: [[a3:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a3:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_20:%\d+]] = OpIEqual %bool [[a3]] %int_20
 // CHECK-NEXT: [[is_a_20:%\d+]] = OpIEqual %bool [[a3]] %int_20
-// CHECK-NEXT: OpSelectionMerge %if_merge_2 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_1 None
 // CHECK-NEXT: OpBranchConditional [[is_a_20]] %if_true_2 %if_false_2
 // CHECK-NEXT: OpBranchConditional [[is_a_20]] %if_true_2 %if_false_2
 // CHECK-NEXT: %if_true_2 = OpLabel
 // CHECK-NEXT: %if_true_2 = OpLabel
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_2
+// CHECK-NEXT: OpBranch %if_merge_1
 // CHECK-NEXT: %if_false_2 = OpLabel
 // CHECK-NEXT: %if_false_2 = OpLabel
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_0
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_2
-// CHECK-NEXT: %if_merge_2 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge_1
 // CHECK-NEXT: OpBranch %if_merge_1
 // CHECK-NEXT: %if_merge_1 = OpLabel
 // CHECK-NEXT: %if_merge_1 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_2
+// CHECK-NEXT: %if_merge_2 = OpLabel
   [branch] switch(a) {
   [branch] switch(a) {
     case 10:
     case 10:
       b=1;
       b=1;
@@ -101,89 +101,89 @@ void main() {
 
 
 // CHECK-NEXT: [[d0:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d0:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_1:%\d+]] = OpIEqual %bool [[d0]] %int_1
 // CHECK-NEXT: [[is_d_1:%\d+]] = OpIEqual %bool [[d0]] %int_1
-// CHECK-NEXT: OpSelectionMerge %if_merge_3 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_10 None
 // CHECK-NEXT: OpBranchConditional [[is_d_1]] %if_true_3 %if_false_3
 // CHECK-NEXT: OpBranchConditional [[is_d_1]] %if_true_3 %if_false_3
 // CHECK-NEXT: %if_true_3 = OpLabel
 // CHECK-NEXT: %if_true_3 = OpLabel
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: OpStore %b %int_1
 // CHECK-NEXT: [[foo:%\d+]] = OpFunctionCall %int %foo
 // CHECK-NEXT: [[foo:%\d+]] = OpFunctionCall %int %foo
 // CHECK-NEXT: OpStore %c [[foo]]
 // CHECK-NEXT: OpStore %c [[foo]]
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_3
+// CHECK-NEXT: OpBranch %if_merge_10
 // CHECK-NEXT: %if_false_3 = OpLabel
 // CHECK-NEXT: %if_false_3 = OpLabel
 // CHECK-NEXT: [[d1:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d1:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_2:%\d+]] = OpIEqual %bool [[d1]] %int_2
 // CHECK-NEXT: [[is_d_2:%\d+]] = OpIEqual %bool [[d1]] %int_2
-// CHECK-NEXT: OpSelectionMerge %if_merge_4 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_9 None
 // CHECK-NEXT: OpBranchConditional [[is_d_2]] %if_true_4 %if_false_4
 // CHECK-NEXT: OpBranchConditional [[is_d_2]] %if_true_4 %if_false_4
 // CHECK-NEXT: %if_true_4 = OpLabel
 // CHECK-NEXT: %if_true_4 = OpLabel
 // CHECK-NEXT: OpStore %b %int_2
 // CHECK-NEXT: OpStore %b %int_2
-// CHECK-NEXT: OpBranch %if_merge_4
+// CHECK-NEXT: OpBranch %if_merge_9
 // CHECK-NEXT: %if_false_4 = OpLabel
 // CHECK-NEXT: %if_false_4 = OpLabel
 // CHECK-NEXT: [[d2:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d2:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_3:%\d+]] = OpIEqual %bool [[d2]] %int_3
 // CHECK-NEXT: [[is_d_3:%\d+]] = OpIEqual %bool [[d2]] %int_3
-// CHECK-NEXT: OpSelectionMerge %if_merge_5 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_8 None
 // CHECK-NEXT: OpBranchConditional [[is_d_3]] %if_true_5 %if_false_5
 // CHECK-NEXT: OpBranchConditional [[is_d_3]] %if_true_5 %if_false_5
 // CHECK-NEXT: %if_true_5 = OpLabel
 // CHECK-NEXT: %if_true_5 = OpLabel
 // CHECK-NEXT: OpStore %b %int_3
 // CHECK-NEXT: OpStore %b %int_3
-// CHECK-NEXT: OpBranch %if_merge_5
+// CHECK-NEXT: OpBranch %if_merge_8
 // CHECK-NEXT: %if_false_5 = OpLabel
 // CHECK-NEXT: %if_false_5 = OpLabel
 // CHECK-NEXT: [[d3:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d3:%\d+]] = OpLoad %int %d
 // TODO: We should try to const fold `t` and avoid the following OpLoad:
 // TODO: We should try to const fold `t` and avoid the following OpLoad:
 // CHECK-NEXT: [[t:%\d+]] = OpLoad %int %t
 // CHECK-NEXT: [[t:%\d+]] = OpLoad %int %t
 // CHECK-NEXT: [[is_d_eq_t:%\d+]] = OpIEqual %bool [[d3]] [[t]]
 // CHECK-NEXT: [[is_d_eq_t:%\d+]] = OpIEqual %bool [[d3]] [[t]]
-// CHECK-NEXT: OpSelectionMerge %if_merge_6 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_7 None
 // CHECK-NEXT: OpBranchConditional [[is_d_eq_t]] %if_true_6 %if_false_6
 // CHECK-NEXT: OpBranchConditional [[is_d_eq_t]] %if_true_6 %if_false_6
 // CHECK-NEXT: %if_true_6 = OpLabel
 // CHECK-NEXT: %if_true_6 = OpLabel
 // CHECK-NEXT: [[t1:%\d+]] = OpLoad %int %t
 // CHECK-NEXT: [[t1:%\d+]] = OpLoad %int %t
 // CHECK-NEXT: OpStore %b [[t1]]
 // CHECK-NEXT: OpStore %b [[t1]]
 // CHECK-NEXT: OpStore %b %int_5
 // CHECK-NEXT: OpStore %b %int_5
-// CHECK-NEXT: OpBranch %if_merge_6
+// CHECK-NEXT: OpBranch %if_merge_7
 // CHECK-NEXT: %if_false_6 = OpLabel
 // CHECK-NEXT: %if_false_6 = OpLabel
 // CHECK-NEXT: [[d4:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d4:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_4:%\d+]] = OpIEqual %bool [[d4]] %int_4
 // CHECK-NEXT: [[is_d_4:%\d+]] = OpIEqual %bool [[d4]] %int_4
-// CHECK-NEXT: OpSelectionMerge %if_merge_7 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_6 None
 // CHECK-NEXT: OpBranchConditional [[is_d_4]] %if_true_7 %if_false_7
 // CHECK-NEXT: OpBranchConditional [[is_d_4]] %if_true_7 %if_false_7
 // CHECK-NEXT: %if_true_7 = OpLabel
 // CHECK-NEXT: %if_true_7 = OpLabel
 // CHECK-NEXT: OpStore %b %int_5
 // CHECK-NEXT: OpStore %b %int_5
-// CHECK-NEXT: OpBranch %if_merge_7
+// CHECK-NEXT: OpBranch %if_merge_6
 // CHECK-NEXT: %if_false_7 = OpLabel
 // CHECK-NEXT: %if_false_7 = OpLabel
 // CHECK-NEXT: [[d5:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d5:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_5:%\d+]] = OpIEqual %bool [[d5]] %int_5
 // CHECK-NEXT: [[is_d_5:%\d+]] = OpIEqual %bool [[d5]] %int_5
-// CHECK-NEXT: OpSelectionMerge %if_merge_8 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_5 None
 // CHECK-NEXT: OpBranchConditional [[is_d_5]] %if_true_8 %if_false_8
 // CHECK-NEXT: OpBranchConditional [[is_d_5]] %if_true_8 %if_false_8
 // CHECK-NEXT: %if_true_8 = OpLabel
 // CHECK-NEXT: %if_true_8 = OpLabel
 // CHECK-NEXT: OpStore %b %int_5
 // CHECK-NEXT: OpStore %b %int_5
-// CHECK-NEXT: OpBranch %if_merge_8
+// CHECK-NEXT: OpBranch %if_merge_5
 // CHECK-NEXT: %if_false_8 = OpLabel
 // CHECK-NEXT: %if_false_8 = OpLabel
 // CHECK-NEXT: [[d6:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d6:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_6:%\d+]] = OpIEqual %bool [[d6]] %int_6
 // CHECK-NEXT: [[is_d_6:%\d+]] = OpIEqual %bool [[d6]] %int_6
-// CHECK-NEXT: OpSelectionMerge %if_merge_9 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_4 None
 // CHECK-NEXT: OpBranchConditional [[is_d_6]] %if_true_9 %if_false_9
 // CHECK-NEXT: OpBranchConditional [[is_d_6]] %if_true_9 %if_false_9
 // CHECK-NEXT: %if_true_9 = OpLabel
 // CHECK-NEXT: %if_true_9 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_9
+// CHECK-NEXT: OpBranch %if_merge_4
 // CHECK-NEXT: %if_false_9 = OpLabel
 // CHECK-NEXT: %if_false_9 = OpLabel
 // CHECK-NEXT: [[d7:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[d7:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_7:%\d+]] = OpIEqual %bool [[d7]] %int_7
 // CHECK-NEXT: [[is_d_7:%\d+]] = OpIEqual %bool [[d7]] %int_7
-// CHECK-NEXT: OpSelectionMerge %if_merge_10 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_3 None
 // CHECK-NEXT: OpBranchConditional [[is_d_7]] %if_true_10 %if_false_10
 // CHECK-NEXT: OpBranchConditional [[is_d_7]] %if_true_10 %if_false_10
 // CHECK-NEXT: %if_true_10 = OpLabel
 // CHECK-NEXT: %if_true_10 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_10
+// CHECK-NEXT: OpBranch %if_merge_3
 // CHECK-NEXT: %if_false_10 = OpLabel
 // CHECK-NEXT: %if_false_10 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_10
-// CHECK-NEXT: %if_merge_10 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_9
-// CHECK-NEXT: %if_merge_9 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_8
-// CHECK-NEXT: %if_merge_8 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_7
-// CHECK-NEXT: %if_merge_7 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_6
-// CHECK-NEXT: %if_merge_6 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_5
-// CHECK-NEXT: %if_merge_5 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_4
-// CHECK-NEXT: %if_merge_4 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge_3
 // CHECK-NEXT: OpBranch %if_merge_3
 // CHECK-NEXT: %if_merge_3 = OpLabel
 // CHECK-NEXT: %if_merge_3 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_4
+// CHECK-NEXT: %if_merge_4 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_5
+// CHECK-NEXT: %if_merge_5 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_6
+// CHECK-NEXT: %if_merge_6 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_7
+// CHECK-NEXT: %if_merge_7 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_8
+// CHECK-NEXT: %if_merge_8 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_9
+// CHECK-NEXT: %if_merge_9 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_10
+// CHECK-NEXT: %if_merge_10 = OpLabel
   [branch] switch(int d = 5) {
   [branch] switch(int d = 5) {
     case 1:
     case 1:
       b=1;
       b=1;
@@ -252,59 +252,59 @@ void main() {
 
 
 // CHECK-NEXT: [[a5:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a5:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_300:%\d+]] = OpIEqual %bool [[a5]] %int_300
 // CHECK-NEXT: [[is_a_300:%\d+]] = OpIEqual %bool [[a5]] %int_300
-// CHECK-NEXT: OpSelectionMerge %if_merge_12 None
-// CHECK-NEXT: OpBranchConditional [[is_a_300]] %if_true_12 %if_false_11
+// CHECK-NEXT: OpSelectionMerge %if_merge_17 None
+// CHECK-NEXT: OpBranchConditional [[is_a_300]] %if_true_12 %if_false_12
 // CHECK-NEXT: %if_true_12 = OpLabel
 // CHECK-NEXT: %if_true_12 = OpLabel
 // CHECK-NEXT: OpStore %b %int_300
 // CHECK-NEXT: OpStore %b %int_300
 // CHECK-NEXT: [[c0:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[c0:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[is_c_500:%\d+]] = OpIEqual %bool [[c0]] %int_500
 // CHECK-NEXT: [[is_c_500:%\d+]] = OpIEqual %bool [[c0]] %int_500
 // CHECK-NEXT: OpSelectionMerge %if_merge_13 None
 // CHECK-NEXT: OpSelectionMerge %if_merge_13 None
-// CHECK-NEXT: OpBranchConditional [[is_c_500]] %if_true_13 %if_false_12
+// CHECK-NEXT: OpBranchConditional [[is_c_500]] %if_true_13 %if_false_11
 // CHECK-NEXT: %if_true_13 = OpLabel
 // CHECK-NEXT: %if_true_13 = OpLabel
 // CHECK-NEXT: OpStore %b %int_500
 // CHECK-NEXT: OpStore %b %int_500
 // CHECK-NEXT: OpBranch %if_merge_13
 // CHECK-NEXT: OpBranch %if_merge_13
-// CHECK-NEXT: %if_false_12 = OpLabel
+// CHECK-NEXT: %if_false_11 = OpLabel
 // CHECK-NEXT: [[c1:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[c1:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[is_c_600:%\d+]] = OpIEqual %bool [[c1]] %int_600
 // CHECK-NEXT: [[is_c_600:%\d+]] = OpIEqual %bool [[c1]] %int_600
-// CHECK-NEXT: OpSelectionMerge %if_merge_14 None
-// CHECK-NEXT: OpBranchConditional [[is_c_600]] %if_true_14 %if_merge_14
+// CHECK-NEXT: OpSelectionMerge %if_merge_12 None
+// CHECK-NEXT: OpBranchConditional [[is_c_600]] %if_true_14 %if_merge_12
 // CHECK-NEXT: %if_true_14 = OpLabel
 // CHECK-NEXT: %if_true_14 = OpLabel
 // CHECK-NEXT: OpStore %a %int_600
 // CHECK-NEXT: OpStore %a %int_600
 // CHECK-NEXT: OpStore %b %int_600
 // CHECK-NEXT: OpStore %b %int_600
-// CHECK-NEXT: OpBranch %if_merge_14
-// CHECK-NEXT: %if_merge_14 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_12
+// CHECK-NEXT: %if_merge_12 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge_13
 // CHECK-NEXT: OpBranch %if_merge_13
 // CHECK-NEXT: %if_merge_13 = OpLabel
 // CHECK-NEXT: %if_merge_13 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_12
-// CHECK-NEXT: %if_false_11 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_17
+// CHECK-NEXT: %if_false_12 = OpLabel
 // CHECK-NEXT: [[a6:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a6:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_400:%\d+]] = OpIEqual %bool [[a6]] %int_400
 // CHECK-NEXT: [[is_a_400:%\d+]] = OpIEqual %bool [[a6]] %int_400
-// CHECK-NEXT: OpSelectionMerge %if_merge_15 None
-// CHECK-NEXT: OpBranchConditional [[is_a_400]] %if_true_15 %if_merge_15
+// CHECK-NEXT: OpSelectionMerge %if_merge_16 None
+// CHECK-NEXT: OpBranchConditional [[is_a_400]] %if_true_15 %if_merge_16
 // CHECK-NEXT: %if_true_15 = OpLabel
 // CHECK-NEXT: %if_true_15 = OpLabel
 // CHECK-NEXT: [[c2:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[c2:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[is_c_500_again:%\d+]] = OpIEqual %bool [[c2]] %int_500
 // CHECK-NEXT: [[is_c_500_again:%\d+]] = OpIEqual %bool [[c2]] %int_500
-// CHECK-NEXT: OpSelectionMerge %if_merge_16 None
+// CHECK-NEXT: OpSelectionMerge %if_merge_15 None
 // CHECK-NEXT: OpBranchConditional [[is_c_500_again]] %if_true_16 %if_false_13
 // CHECK-NEXT: OpBranchConditional [[is_c_500_again]] %if_true_16 %if_false_13
 // CHECK-NEXT: %if_true_16 = OpLabel
 // CHECK-NEXT: %if_true_16 = OpLabel
 // CHECK-NEXT: OpStore %b %int_500
 // CHECK-NEXT: OpStore %b %int_500
-// CHECK-NEXT: OpBranch %if_merge_16
+// CHECK-NEXT: OpBranch %if_merge_15
 // CHECK-NEXT: %if_false_13 = OpLabel
 // CHECK-NEXT: %if_false_13 = OpLabel
 // CHECK-NEXT: [[c3:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[c3:%\d+]] = OpLoad %int %c
 // CHECK-NEXT: [[is_c_600_again:%\d+]] = OpIEqual %bool [[c3]] %int_600
 // CHECK-NEXT: [[is_c_600_again:%\d+]] = OpIEqual %bool [[c3]] %int_600
-// CHECK-NEXT: OpSelectionMerge %if_merge_17 None
-// CHECK-NEXT: OpBranchConditional [[is_c_600_again]] %if_true_17 %if_merge_17
+// CHECK-NEXT: OpSelectionMerge %if_merge_14 None
+// CHECK-NEXT: OpBranchConditional [[is_c_600_again]] %if_true_17 %if_merge_14
 // CHECK-NEXT: %if_true_17 = OpLabel
 // CHECK-NEXT: %if_true_17 = OpLabel
 // CHECK-NEXT: OpStore %a %int_600
 // CHECK-NEXT: OpStore %a %int_600
 // CHECK-NEXT: OpStore %b %int_600
 // CHECK-NEXT: OpStore %b %int_600
-// CHECK-NEXT: OpBranch %if_merge_17
-// CHECK-NEXT: %if_merge_17 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_16
-// CHECK-NEXT: %if_merge_16 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_14
+// CHECK-NEXT: %if_merge_14 = OpLabel
 // CHECK-NEXT: OpBranch %if_merge_15
 // CHECK-NEXT: OpBranch %if_merge_15
 // CHECK-NEXT: %if_merge_15 = OpLabel
 // CHECK-NEXT: %if_merge_15 = OpLabel
-// CHECK-NEXT: OpBranch %if_merge_12
-// CHECK-NEXT: %if_merge_12 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_16
+// CHECK-NEXT: %if_merge_16 = OpLabel
+// CHECK-NEXT: OpBranch %if_merge_17
+// CHECK-NEXT: %if_merge_17 = OpLabel
   [branch] switch(a) {
   [branch] switch(a) {
     case 300:
     case 300:
       b=300;
       b=300;

+ 9 - 9
tools/clang/test/CodeGenSPIRV/switch-stmt.opswitch.hlsl

@@ -262,15 +262,15 @@ void main() {
   ////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////
 
 
 // CHECK-NEXT: [[a7:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[a7:%\d+]] = OpLoad %int %a
-// CHECK-NEXT: OpSelectionMerge %switch_merge_6 None
-// CHECK-NEXT: OpSwitch [[a7]] %switch_merge_6 30 %switch_30
+// CHECK-NEXT: OpSelectionMerge %switch_merge_7 None
+// CHECK-NEXT: OpSwitch [[a7]] %switch_merge_7 30 %switch_30
   switch(a) {
   switch(a) {
 // CHECK-NEXT: %switch_30 = OpLabel
 // CHECK-NEXT: %switch_30 = OpLabel
     case 30: {
     case 30: {
 // CHECK-NEXT: OpStore %result %int_30
 // CHECK-NEXT: OpStore %result %int_30
         result = 30;
         result = 30;
 // CHECK-NEXT: [[result:%\d+]] = OpLoad %int %result
 // CHECK-NEXT: [[result:%\d+]] = OpLoad %int %result
-// CHECK-NEXT: OpSelectionMerge %switch_merge_7 None
+// CHECK-NEXT: OpSelectionMerge %switch_merge_6 None
 // CHECK-NEXT: OpSwitch [[result]] %switch_default_2 50 %switch_50 51 %switch_51 52 %switch_52 53 %switch_53 54 %switch_54
 // CHECK-NEXT: OpSwitch [[result]] %switch_default_2 50 %switch_50 51 %switch_51 52 %switch_52 53 %switch_53 54 %switch_54
         switch(result) {
         switch(result) {
 // CHECK-NEXT: %switch_default_2 = OpLabel
 // CHECK-NEXT: %switch_default_2 = OpLabel
@@ -280,7 +280,7 @@ void main() {
             a = 55;
             a = 55;
 // CHECK-NEXT: %switch_50 = OpLabel
 // CHECK-NEXT: %switch_50 = OpLabel
 // CHECK-NEXT: OpStore %a %int_50
 // CHECK-NEXT: OpStore %a %int_50
-// CHECK-NEXT: OpBranch %switch_merge_7
+// CHECK-NEXT: OpBranch %switch_merge_6
           case 50:
           case 50:
             a = 50;
             a = 50;
             break;
             break;
@@ -294,23 +294,23 @@ void main() {
             a = 52;
             a = 52;
 // CHECK-NEXT: %switch_53 = OpLabel
 // CHECK-NEXT: %switch_53 = OpLabel
 // CHECK-NEXT: OpStore %a %int_53
 // CHECK-NEXT: OpStore %a %int_53
-// CHECK-NEXT: OpBranch %switch_merge_7
+// CHECK-NEXT: OpBranch %switch_merge_6
           case 53:
           case 53:
             a = 53;
             a = 53;
             break;
             break;
 // CHECK-NEXT: %switch_54 = OpLabel
 // CHECK-NEXT: %switch_54 = OpLabel
 // CHECK-NEXT: OpStore %a %int_54
 // CHECK-NEXT: OpStore %a %int_54
-// CHECK-NEXT: OpBranch %switch_merge_7
+// CHECK-NEXT: OpBranch %switch_merge_6
           case 54 : {
           case 54 : {
             a = 54;
             a = 54;
             break;
             break;
           }
           }
         }
         }
-// CHECK-NEXT: %switch_merge_7 = OpLabel
-// CHECK-NEXT: OpBranch %switch_merge_6
+// CHECK-NEXT: %switch_merge_6 = OpLabel
+// CHECK-NEXT: OpBranch %switch_merge_7
     }
     }
   }
   }
-// CHECK-NEXT: %switch_merge_6 = OpLabel
+// CHECK-NEXT: %switch_merge_7 = OpLabel
 
 
 
 
 
 

+ 10 - 10
tools/clang/test/CodeGenSPIRV/while-stmt.break.hlsl

@@ -55,8 +55,8 @@ void main() {
 
 
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: %while_check_0 = OpLabel
 // CHECK-NEXT: %while_check_0 = OpLabel
-// CHECK-NEXT: OpLoopMerge %while_merge_0 %while_continue_0 None
-// CHECK-NEXT: OpBranchConditional %true %while_body_0 %while_merge_0
+// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 None
+// CHECK-NEXT: OpBranchConditional %true %while_body_0 %while_merge_1
   while (true) {
   while (true) {
 // CHECK-NEXT: %while_body_0 = OpLabel
 // CHECK-NEXT: %while_body_0 = OpLabel
     i++;
     i++;
@@ -64,23 +64,23 @@ void main() {
 // CHECK:      OpBranch %while_check_1
 // CHECK:      OpBranch %while_check_1
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK:      [[i_lt_20:%\d+]] = OpSLessThan %bool {{%\d+}} %int_20
 // CHECK:      [[i_lt_20:%\d+]] = OpSLessThan %bool {{%\d+}} %int_20
-// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 None
-// CHECK-NEXT: OpBranchConditional [[i_lt_20]] %while_body_1 %while_merge_1
+// CHECK-NEXT: OpLoopMerge %while_merge_0 %while_continue_0 None
+// CHECK-NEXT: OpBranchConditional [[i_lt_20]] %while_body_1 %while_merge_0
     while(i<20) {
     while(i<20) {
 // CHECK-NEXT: %while_body_1 = OpLabel
 // CHECK-NEXT: %while_body_1 = OpLabel
       val = i;
       val = i;
-// CHECK:      OpBranch %while_merge_1
+// CHECK:      OpBranch %while_merge_0
       {{break;}}
       {{break;}}
-// CHECK-NEXT: %while_continue_1 = OpLabel
+// CHECK-NEXT: %while_continue_0 = OpLabel
 // CHECK-NEXT: OpBranch %while_check_1
 // CHECK-NEXT: OpBranch %while_check_1
     }
     }
-// CHECK-NEXT: %while_merge_1 = OpLabel
+// CHECK-NEXT: %while_merge_0 = OpLabel
     --i;
     --i;
-// CHECK:      OpBranch %while_merge_0
+// CHECK:      OpBranch %while_merge_1
     break;
     break;
-// CHECK-NEXT: %while_continue_0 = OpLabel
+// CHECK-NEXT: %while_continue_1 = OpLabel
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: OpBranch %while_check_0
   }
   }
-// CHECK-NEXT: %while_merge_0 = OpLabel
+// CHECK-NEXT: %while_merge_1 = OpLabel
 
 
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/while-stmt.continue.hlsl

@@ -55,8 +55,8 @@ void main() {
 
 
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: %while_check_0 = OpLabel
 // CHECK-NEXT: %while_check_0 = OpLabel
-// CHECK-NEXT: OpLoopMerge %while_merge_0 %while_continue_0 None
-// CHECK-NEXT: OpBranchConditional %true %while_body_0 %while_merge_0
+// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 None
+// CHECK-NEXT: OpBranchConditional %true %while_body_0 %while_merge_1
   while (true) {
   while (true) {
 // CHECK-NEXT: %while_body_0 = OpLabel
 // CHECK-NEXT: %while_body_0 = OpLabel
     i++;
     i++;
@@ -64,25 +64,25 @@ void main() {
 // CHECK:      OpBranch %while_check_1
 // CHECK:      OpBranch %while_check_1
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK:      [[i_lt_20:%\d+]] = OpSLessThan %bool {{%\d+}} %int_20
 // CHECK:      [[i_lt_20:%\d+]] = OpSLessThan %bool {{%\d+}} %int_20
-// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 None
-// CHECK-NEXT: OpBranchConditional [[i_lt_20]] %while_body_1 %while_merge_1
+// CHECK-NEXT: OpLoopMerge %while_merge_0 %while_continue_0 None
+// CHECK-NEXT: OpBranchConditional [[i_lt_20]] %while_body_1 %while_merge_0
     while(i<20) {
     while(i<20) {
 // CHECK-NEXT: %while_body_1 = OpLabel
 // CHECK-NEXT: %while_body_1 = OpLabel
       val = i;
       val = i;
-// CHECK:      OpBranch %while_continue_1
+// CHECK:      OpBranch %while_continue_0
       continue;
       continue;
-// CHECK-NEXT: %while_continue_1 = OpLabel
+// CHECK-NEXT: %while_continue_0 = OpLabel
 // CHECK-NEXT: OpBranch %while_check_1
 // CHECK-NEXT: OpBranch %while_check_1
     }
     }
-// CHECK-NEXT: %while_merge_1 = OpLabel
+// CHECK-NEXT: %while_merge_0 = OpLabel
     --i;
     --i;
-// CHECK:      OpBranch %while_continue_0
+// CHECK:      OpBranch %while_continue_1
     continue;
     continue;
     continue;  // No SPIR-V should be emitted for this statement.
     continue;  // No SPIR-V should be emitted for this statement.
 
 
-// CHECK-NEXT: %while_continue_0 = OpLabel
+// CHECK-NEXT: %while_continue_1 = OpLabel
 // CHECK-NEXT: OpBranch %while_check_0
 // CHECK-NEXT: OpBranch %while_check_0
   }
   }
-// CHECK-NEXT: %while_merge_0 = OpLabel
+// CHECK-NEXT: %while_merge_1 = OpLabel
 
 
 }
 }

+ 10 - 10
tools/clang/test/CodeGenSPIRV/while-stmt.nested.hlsl

@@ -7,8 +7,8 @@ void main() {
 // CHECK-NEXT: %while_check = OpLabel
 // CHECK-NEXT: %while_check = OpLabel
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i0:%\d+]] = OpLoad %int %i
 // CHECK-NEXT: [[i_lt_10:%\d+]] = OpSLessThan %bool [[i0]] %int_10
 // CHECK-NEXT: [[i_lt_10:%\d+]] = OpSLessThan %bool [[i0]] %int_10
-// CHECK-NEXT: OpLoopMerge %while_merge %while_continue DontUnroll
-// CHECK-NEXT: OpBranchConditional [[i_lt_10]] %while_body %while_merge
+// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 DontUnroll
+// CHECK-NEXT: OpBranchConditional [[i_lt_10]] %while_body %while_merge_1
   [loop] while (i < 10) {
   [loop] while (i < 10) {
 // CHECK-NEXT: %while_body = OpLabel
 // CHECK-NEXT: %while_body = OpLabel
 // CHECK-NEXT: [[val1:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val1:%\d+]] = OpLoad %int %val
@@ -29,8 +29,8 @@ void main() {
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK-NEXT: %while_check_1 = OpLabel
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k0:%\d+]] = OpLoad %int %k
 // CHECK-NEXT: [[k_lt_30:%\d+]] = OpSLessThan %bool [[k0]] %int_30
 // CHECK-NEXT: [[k_lt_30:%\d+]] = OpSLessThan %bool [[k0]] %int_30
-// CHECK-NEXT: OpLoopMerge %while_merge_1 %while_continue_1 DontUnroll
-// CHECK-NEXT: OpBranchConditional [[k_lt_30]] %while_body_1 %while_merge_1
+// CHECK-NEXT: OpLoopMerge %while_merge %while_continue DontUnroll
+// CHECK-NEXT: OpBranchConditional [[k_lt_30]] %while_body_1 %while_merge
       [fastopt] while (k < 30) {
       [fastopt] while (k < 30) {
 // CHECK-NEXT: %while_body_1 = OpLabel
 // CHECK-NEXT: %while_body_1 = OpLabel
 // CHECK-NEXT: [[val2:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val2:%\d+]] = OpLoad %int %val
@@ -42,11 +42,11 @@ void main() {
 // CHECK-NEXT: [[k_plus_1:%\d+]] = OpIAdd %int [[k3]] %int_1
 // CHECK-NEXT: [[k_plus_1:%\d+]] = OpIAdd %int [[k3]] %int_1
 // CHECK-NEXT: OpStore %k [[k_plus_1]]
 // CHECK-NEXT: OpStore %k [[k_plus_1]]
         ++k;
         ++k;
-// CHECK-NEXT: OpBranch %while_continue_1
-// CHECK-NEXT: %while_continue_1 = OpLabel
+// CHECK-NEXT: OpBranch %while_continue
+// CHECK-NEXT: %while_continue = OpLabel
 // CHECK-NEXT: OpBranch %while_check_1
 // CHECK-NEXT: OpBranch %while_check_1
       }
       }
-// CHECK-NEXT: %while_merge_1 = OpLabel
+// CHECK-NEXT: %while_merge = OpLabel
 
 
 // CHECK-NEXT: [[val3:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val3:%\d+]] = OpLoad %int %val
 // CHECK-NEXT: [[val_mult_2:%\d+]] = OpIMul %int [[val3]] %int_2
 // CHECK-NEXT: [[val_mult_2:%\d+]] = OpIMul %int [[val3]] %int_2
@@ -66,11 +66,11 @@ void main() {
 // CHECK-NEXT: [[i_plus_1:%\d+]] = OpIAdd %int [[i2]] %int_1
 // CHECK-NEXT: [[i_plus_1:%\d+]] = OpIAdd %int [[i2]] %int_1
 // CHECK-NEXT: OpStore %i [[i_plus_1]]
 // CHECK-NEXT: OpStore %i [[i_plus_1]]
     ++i;
     ++i;
-// CHECK-NEXT: OpBranch %while_continue
-// CHECK-NEXT: %while_continue = OpLabel
+// CHECK-NEXT: OpBranch %while_continue_1
+// CHECK-NEXT: %while_continue_1 = OpLabel
 // CHECK-NEXT: OpBranch %while_check
 // CHECK-NEXT: OpBranch %while_check
   }
   }
-// CHECK-NEXT: %while_merge = OpLabel
+// CHECK-NEXT: %while_merge_1 = OpLabel
 
 
 
 
 // CHECK-NEXT: OpReturn
 // CHECK-NEXT: OpReturn