dead code elimination: Fixed a crash when trying to get the immediate post-dominating block in an infinite loop.
SR-7805
rdar://problem/40650953
diff --git a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
index e17dfeb..d438071 100644
--- a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
+++ b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
@@ -419,10 +419,12 @@
SILBasicBlock *DCE::nearestUsefulPostDominator(SILBasicBlock *Block) {
// Find the nearest post-dominator that has useful instructions.
auto *PostDomNode = PDT->getNode(Block)->getIDom();
- while (!LiveBlocks.count(PostDomNode->getBlock()))
+ while (PostDomNode && !LiveBlocks.count(PostDomNode->getBlock()))
PostDomNode = PostDomNode->getIDom();
- return PostDomNode->getBlock();
+ if (PostDomNode)
+ return PostDomNode->getBlock();
+ return nullptr;
}
// Replace the given conditional branching instruction with a plain
@@ -485,8 +487,11 @@
// We want to replace dead terminators with unconditional branches to
// the nearest post-dominator that has useful instructions.
if (isa<TermInst>(Inst)) {
- replaceBranchWithJump(Inst,
- nearestUsefulPostDominator(Inst->getParent()));
+ SILBasicBlock *postDom = nearestUsefulPostDominator(Inst->getParent());
+ if (!postDom)
+ continue;
+
+ replaceBranchWithJump(Inst, postDom);
Inst->eraseFromParent();
BranchesChanged = true;
Changed = true;
diff --git a/test/SILOptimizer/dead_code_elimination.sil b/test/SILOptimizer/dead_code_elimination.sil
index 511e97b..a8773e9 100644
--- a/test/SILOptimizer/dead_code_elimination.sil
+++ b/test/SILOptimizer/dead_code_elimination.sil
@@ -243,3 +243,19 @@
return %90 : $()
}
+// Check that DCE does not crash with an infinite loop through a cond_br.
+// CHECK-LABEL: sil @deal_with_infinite_loop
+// CHECK: cond_br
+sil @deal_with_infinite_loop : $@convention(thin) () -> () {
+bb0:
+ br bb1
+
+bb1:
+ cond_br undef, bb2, bb3
+
+bb2:
+ br bb1
+
+bb3:
+ br bb1
+}