diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 14 | ||||
-rw-r--r-- | llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll | 39 |
2 files changed, 50 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index 345b030ddc1..33eb80734d1 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -1930,10 +1930,7 @@ bool llvm::runIPSCCP(Module &M, const DataLayout &DL, for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { if (!Solver.isBlockExecutable(&*BB)) { LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << *BB); - ++NumDeadBlocks; - NumInstRemoved += - changeToUnreachable(BB->getFirstNonPHI(), /*UseLLVMTrap=*/false); MadeChanges = true; @@ -1956,6 +1953,17 @@ bool llvm::runIPSCCP(Module &M, const DataLayout &DL, } } + // Change dead blocks to unreachable. We do it after replacing constants in + // all executable blocks, because changeToUnreachable may remove PHI nodes + // in executable blocks we found values for. The function's entry block is + // not part of BlocksToErase, so we have to handle it separately. + for (BasicBlock *BB : BlocksToErase) + NumInstRemoved += + changeToUnreachable(BB->getFirstNonPHI(), /*UseLLVMTrap=*/false); + if (!Solver.isBlockExecutable(&F.front())) + NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHI(), + /*UseLLVMTrap=*/false); + // Now that all instructions in the function are constant folded, erase dead // blocks, because we can now use ConstantFoldTerminator to get rid of // in-edges. diff --git a/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll b/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll new file mode 100644 index 00000000000..afba1f41957 --- /dev/null +++ b/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S -ipsccp | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" + +define void @test() { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label %Flow5.pre +; CHECK: Flow6: +; CHECK-NEXT: br label %end2 +; CHECK: Flow5.pre: +; CHECK-NEXT: br label %Flow5 +; CHECK: Flow5: +; CHECK-NEXT: br label %Flow6 +; CHECK: end2: +; CHECK-NEXT: unreachable +; +entry: + br i1 true, label %Flow5.pre, label %Flow5.pre.unreachable + +Flow5.pre.unreachable: + br label %Flow5 + +Flow6: + br i1 %0, label %end1, label %end2 + +Flow5.pre: + br label %Flow5 + +Flow5: + %0 = phi i1 [ undef, %Flow5.pre ], [ false, %Flow5.pre.unreachable ] + br label %Flow6 + +end1: + unreachable + +end2: + unreachable +} |