Merge pull request #16913 from eeckstein/fix-dce-4.2
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 535cd1a..a8773e9 100644
--- a/test/SILOptimizer/dead_code_elimination.sil
+++ b/test/SILOptimizer/dead_code_elimination.sil
@@ -1,7 +1,5 @@
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -dce %s | %FileCheck %s
-// REQUIRES: rdar34013900
-
sil_stage canonical
import Builtin
@@ -59,8 +57,6 @@
return %18 : $()
}
-// We currently bail out on functions that have structurally infinite
-// loops.
// CHECK-LABEL: sil @dead3
sil @dead3 : $@convention(thin) () -> () {
bb0:
@@ -68,8 +64,8 @@
br bb1
// CHECK: bb1
bb1:
-// CHECK: integer_literal $Builtin.Int32, 0
-// CHECK: br bb1
+// CHECK: bb1:
+// CHECK-NEXT: br bb1
%0 = integer_literal $Builtin.Int32, 0
br bb1
}
@@ -247,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
+}