From: Florian Hahn Date: Wed, 8 May 2019 09:09:54 +0000 (+0000) Subject: [SCCP] Fix crash when trying to constant-fold terminators multiple times. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec90eb442e3c0ee6fd5121c96f9f21b3bfd6af50;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360232 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index e75a5dbddba..66885ed57e2 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -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(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); diff --git a/test/Transforms/SCCP/switch-constantfold-crash.ll b/test/Transforms/SCCP/switch-constantfold-crash.ll new file mode 100644 index 00000000000..7596a56b812 --- /dev/null +++ b/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 +}