mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user