SimplifyCFG: fix a crash caused by an unreachable CFG cycles with block arguments.

When SimplifyCFG (temporarily) produces an unreachable CFG cycle, some other transformations in SimplifyCFG didn't deal with this situation correctly.

Unfortunately I couldn't create a SIL test case for this bug, so I just added a swift test case.

https://bugs.swift.org/browse/SR-13650
rdar://problem/69942431
This commit is contained in:
Erik Eckstein
2020-10-15 15:04:16 +02:00
parent aa3e5904f8
commit 6c85f267bf
3 changed files with 46 additions and 14 deletions

View File

@@ -1248,21 +1248,8 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
LLVM_DEBUG(llvm::dbgs() << "merge bb" << BB->getDebugID() << " with bb"
<< DestBB->getDebugID() << '\n');
// If there are any BB arguments in the destination, replace them with the
// branch operands, since they must dominate the dest block.
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
if (DestBB->getArgument(i) != BI->getArg(i)) {
SILValue Val = BI->getArg(i);
DestBB->getArgument(i)->replaceAllUsesWith(Val);
if (!isVeryLargeFunction) {
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
// Replacing operands may trigger constant folding which then could
// trigger other simplify-CFG optimizations.
ConstFolder.addToWorklist(I);
ConstFolder.processWorkList();
}
}
} else {
if (DestBB->getArgument(i) == BI->getArg(i)) {
// We must be processing an unreachable part of the cfg with a cycle.
// bb1(arg1): // preds: bb3
// br bb2
@@ -1273,6 +1260,23 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
// bb3: // preds: bb2
// br bb1(arg1)
assert(!isReachable(BB) && "Should only occur in unreachable block");
return Simplified;
}
}
// If there are any BB arguments in the destination, replace them with the
// branch operands, since they must dominate the dest block.
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
assert(DestBB->getArgument(i) != BI->getArg(i));
SILValue Val = BI->getArg(i);
DestBB->getArgument(i)->replaceAllUsesWith(Val);
if (!isVeryLargeFunction) {
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
// Replacing operands may trigger constant folding which then could
// trigger other simplify-CFG optimizations.
ConstFolder.addToWorklist(I);
ConstFolder.processWorkList();
}
}
}