Skip to content

dead code elimination: Fixed a crash when trying to get the immediate post-dominating block in an infinite loop. #16912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,12 @@ void DCE::propagateLiveness(SILInstruction *I) {
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
Expand Down Expand Up @@ -485,8 +487,11 @@ bool DCE::removeDead(SILFunction &F) {
// 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;
Expand Down
24 changes: 18 additions & 6 deletions test/SILOptimizer/dead_code_elimination.sil
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -59,17 +57,15 @@ bb3:
return %18 : $()
}

// We currently bail out on functions that have structurally infinite
// loops.
// CHECK-LABEL: sil @dead3
sil @dead3 : $@convention(thin) () -> () {
bb0:
// CHECK: bb0
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
}
Expand Down Expand Up @@ -247,3 +243,19 @@ bb0(%0 : $*Container):
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
}