Skip to content

Commit 1c7e87a

Browse files
authored
Merge pull request #34320 from eeckstein/fix-simplify-cfg
2 parents 529660d + 6c85f26 commit 1c7e87a

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,21 +1248,8 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12481248
LLVM_DEBUG(llvm::dbgs() << "merge bb" << BB->getDebugID() << " with bb"
12491249
<< DestBB->getDebugID() << '\n');
12501250

1251-
// If there are any BB arguments in the destination, replace them with the
1252-
// branch operands, since they must dominate the dest block.
12531251
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
1254-
if (DestBB->getArgument(i) != BI->getArg(i)) {
1255-
SILValue Val = BI->getArg(i);
1256-
DestBB->getArgument(i)->replaceAllUsesWith(Val);
1257-
if (!isVeryLargeFunction) {
1258-
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
1259-
// Replacing operands may trigger constant folding which then could
1260-
// trigger other simplify-CFG optimizations.
1261-
ConstFolder.addToWorklist(I);
1262-
ConstFolder.processWorkList();
1263-
}
1264-
}
1265-
} else {
1252+
if (DestBB->getArgument(i) == BI->getArg(i)) {
12661253
// We must be processing an unreachable part of the cfg with a cycle.
12671254
// bb1(arg1): // preds: bb3
12681255
// br bb2
@@ -1273,6 +1260,23 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12731260
// bb3: // preds: bb2
12741261
// br bb1(arg1)
12751262
assert(!isReachable(BB) && "Should only occur in unreachable block");
1263+
return Simplified;
1264+
}
1265+
}
1266+
1267+
// If there are any BB arguments in the destination, replace them with the
1268+
// branch operands, since they must dominate the dest block.
1269+
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
1270+
assert(DestBB->getArgument(i) != BI->getArg(i));
1271+
SILValue Val = BI->getArg(i);
1272+
DestBB->getArgument(i)->replaceAllUsesWith(Val);
1273+
if (!isVeryLargeFunction) {
1274+
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
1275+
// Replacing operands may trigger constant folding which then could
1276+
// trigger other simplify-CFG optimizations.
1277+
ConstFolder.addToWorklist(I);
1278+
ConstFolder.processWorkList();
1279+
}
12761280
}
12771281
}
12781282

lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ bool ReachableBlocks::visit(SILFunction *f,
4444
/// Remove all instructions in the body of \p bb in safe manner by using
4545
/// undef.
4646
void swift::clearBlockBody(SILBasicBlock *bb) {
47+
48+
for (SILArgument *arg : bb->getArguments()) {
49+
arg->replaceAllUsesWithUndef();
50+
}
51+
4752
// Instructions in the dead block may be used by other dead blocks. Replace
4853
// any uses of them with undef values.
4954
while (!bb->empty()) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
2+
3+
// Check that the optimizer does not crash.
4+
5+
6+
public class Base {
7+
@inline(never)
8+
final func next() -> Base? {
9+
return self
10+
}
11+
}
12+
13+
public class Derived : Base {}
14+
15+
// CHECK: sil {{.*}}testit
16+
public func testit(_ x: Base?) -> Derived? {
17+
var i: Base? = x
18+
while (i is Derived) == false && i != nil {
19+
i = i?.next()
20+
}
21+
return i as? Derived
22+
}
23+

0 commit comments

Comments
 (0)