Account for non-one user of dx.break call (#2802)
* Account for non-one user of dx.break call The original code expected that optimizations wouldn't remove any of the users of a call to dx.break(). In loop unrolling cases, simplifyCFG may do just that, which caused the original assert and assume we're right method to break. Now we assert we're in the confines of what is now known to be possible, but we don't assume anything. There's a loop over the users of the call instruction that I only ever expect to be executed once or never, but it's there just in case.
This commit is contained in:
Родитель
d3af7f1237
Коммит
9007354c61
|
@ -647,19 +647,27 @@ private:
|
|||
Constant *Gep = ConstantExpr::getGetElementPtr(nullptr, GV, Indices);
|
||||
SmallDenseMap<llvm::Function*, llvm::ICmpInst*, 16> DxBreakCmpMap;
|
||||
// Replace all uses of dx.break with references to the constant global
|
||||
for (User *U : BreakFunc->users()) {
|
||||
DXASSERT(U->hasOneUse() && isa<CallInst>(U), "User of dx.break function isn't call or has multiple users");
|
||||
BranchInst *BI = cast<BranchInst>(*U->user_begin());
|
||||
for (auto I = BreakFunc->user_begin(), E = BreakFunc->user_end(); I != E;) {
|
||||
User *U = *I++;
|
||||
CallInst *CI = cast<CallInst>(U);
|
||||
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));
|
||||
// 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);
|
||||
}
|
||||
BI->setCondition(Cmp);
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче