ソースを参照

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();
         }
       }