Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -1933,10 +1933,7 @@ 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; @@ -1959,6 +1956,17 @@ } } + // 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. Index: test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll =================================================================== --- /dev/null +++ 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 +}