Skip to content

Commit

Permalink
[SCCP] Fix crash when trying to constant-fold terminators multiple ti…
Browse files Browse the repository at this point in the history
…mes.

If we fold a branch/switch to an unconditional branch to another dead block we
replace the branch with unreachable, to avoid attempting to fold the
unconditional branch.

Reviewers: davide, efriedma, mssimpso, jdoerfert

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D61300

llvm-svn: 360232
  • Loading branch information
fhahn authored and MrSidims committed May 17, 2019
1 parent 4b38436 commit 26cae0d
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 1 deletion.
12 changes: 11 additions & 1 deletion llvm/lib/Transforms/Scalar/SCCP.cpp
Expand Up @@ -2083,12 +2083,22 @@ bool llvm::runIPSCCP(
// If we have forced an edge for an indeterminate value, then force the
// terminator to fold to that edge.
forceIndeterminateEdge(I, Solver);
bool Folded = ConstantFoldTerminator(I->getParent(),
BasicBlock *InstBB = I->getParent();
bool Folded = ConstantFoldTerminator(InstBB,
/*DeleteDeadConditions=*/false,
/*TLI=*/nullptr, &DTU);
assert(Folded &&
"Expect TermInst on constantint or blockaddress to be folded");
(void) Folded;
// If we folded the terminator to an unconditional branch to another
// dead block, replace it with Unreachable, to avoid trying to fold that
// branch again.
BranchInst *BI = cast<BranchInst>(InstBB->getTerminator());
if (BI && BI->isUnconditional() &&
!Solver.isBlockExecutable(BI->getSuccessor(0))) {
InstBB->getTerminator()->eraseFromParent();
new UnreachableInst(InstBB->getContext(), InstBB);
}
}
// Mark dead BB for deletion.
DTU.deleteBB(DeadBB);
Expand Down
92 changes: 92 additions & 0 deletions llvm/test/Transforms/SCCP/switch-constantfold-crash.ll
@@ -0,0 +1,92 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -ipsccp < %s -S | FileCheck %s
; RUN: opt -passes=ipsccp < %s -S | FileCheck %s

define void @barney() {
; CHECK-LABEL: @barney(
; CHECK-NEXT: bb:
; CHECK-NEXT: br label %bb9
; CHECK: bb6:
; CHECK-NEXT: unreachable
; CHECK: bb9:
; CHECK-NEXT: unreachable
;
bb:
br label %bb9

bb6: ; preds = %bb9
unreachable

bb7: ; preds = %bb9
unreachable

bb9: ; preds = %bb
switch i16 0, label %bb6 [
i16 61, label %bb7
]
}

define void @blam() {
; CHECK-LABEL: @blam(
; CHECK-NEXT: bb:
; CHECK-NEXT: br label %bb16
; CHECK: bb16:
; CHECK-NEXT: br label %bb38
; CHECK: bb38:
; CHECK-NEXT: unreachable
;
bb:
br label %bb16

bb16: ; preds = %bb
switch i32 0, label %bb38 [
i32 66, label %bb17
i32 63, label %bb18
i32 86, label %bb19
]

bb17: ; preds = %bb16
unreachable

bb18: ; preds = %bb16
unreachable

bb19: ; preds = %bb16
unreachable

bb38: ; preds = %bb16
unreachable
}


define void @hoge() {
; CHECK-LABEL: @hoge(
; CHECK-NEXT: bb:
; CHECK-NEXT: br label %bb2
; CHECK: bb2:
; CHECK-NEXT: unreachable
; CHECK: bb3:
; CHECK-NEXT: unreachable
;
bb:
switch i16 undef, label %bb1 [
i16 135, label %bb2
i16 66, label %bb2
]

bb1: ; preds = %bb
ret void

bb2: ; preds = %bb, %bb
switch i16 0, label %bb3 [
i16 61, label %bb4
i16 54, label %bb4
i16 49, label %bb4
]

bb3: ; preds = %bb2
unreachable

bb4: ; preds = %bb2, %bb2, %bb2
unreachable
}

0 comments on commit 26cae0d

Please sign in to comment.