mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[SCCP] Fix crash when trying to constant-fold terminators multiple times.
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
This commit is contained in:
parent
19f9180ee5
commit
cf5cd7dbe8
@ -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);
|
||||
|
92
test/Transforms/SCCP/switch-constantfold-crash.ll
Normal file
92
test/Transforms/SCCP/switch-constantfold-crash.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user