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;
}
}
+ // 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.
--- /dev/null
+; 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
+}