浏览代码

Don't assume branch user of dx.break (#2806)

The previous lowering of dx.break() assumed that the user was still a
branch as it was when it was set up. However, optimizations can switch
things around so this assumption is wrong.

By allowing for other instructions, the replacement takes place just the 
same regardless of whether its a branch.

Various code simplifications too.
Greg Roth 5 年之前
父节点
当前提交
9ecca8cfbb
共有 1 个文件被更改,包括 8 次插入17 次删除
  1. 8 17
      lib/HLSL/DxilPreparePasses.cpp

+ 8 - 17
lib/HLSL/DxilPreparePasses.cpp

@@ -650,24 +650,15 @@ private:
         for (auto I = BreakFunc->user_begin(), E = BreakFunc->user_end(); I != E;) {
           User *U = *I++;
           CallInst *CI = cast<CallInst>(U);
-          // SimplifyCFG might have removed our user
-          DXASSERT(U->getNumUses() <= 1,
-            "User of dx.break function has multiple users");
-
-          // In spite of the <=1 assert above, loop here in case the assumption is wrong
-          for (auto II = U->user_begin(), EE = U->user_end(); II != EE;) {
-            User *UU = *II++;
-            BranchInst *BI = cast<BranchInst>(UU);
-            Function *F = BI->getParent()->getParent();
-            ICmpInst *Cmp = DxBreakCmpMap.lookup(F);
-            if (!Cmp) {
-              BasicBlock &EntryBB = F->getEntryBlock();
-              LoadInst *LI = new LoadInst(Gep, nullptr, false, EntryBB.getTerminator());
-              Cmp = new ICmpInst(EntryBB.getTerminator(), ICmpInst::ICMP_EQ, LI, llvm::ConstantInt::get(i32Ty,0));
-              DxBreakCmpMap.insert(std::make_pair(F, Cmp));
-            }
-            BI->setCondition(Cmp);
+          Function *F = CI->getParent()->getParent();
+          ICmpInst *Cmp = DxBreakCmpMap.lookup(F);
+          if (!Cmp) {
+            Instruction *IP = dxilutil::FirstNonAllocaInsertionPt(F);
+            LoadInst *LI = new LoadInst(Gep, nullptr, false, IP);
+            Cmp = new ICmpInst(IP, ICmpInst::ICMP_EQ, LI, llvm::ConstantInt::get(i32Ty,0));
+            DxBreakCmpMap[F] = Cmp;
           }
+          CI->replaceAllUsesWith(Cmp);
           CI->eraseFromParent();
         }
       }