diff options
author | Florian Hahn <florian.hahn@arm.com> | 2018-06-26 10:15:02 +0000 |
---|---|---|
committer | Florian Hahn <florian.hahn@arm.com> | 2018-06-26 10:15:02 +0000 |
commit | 4a69b0bb3680cb83b0ebc4dbe661e7477cc4c49b (patch) | |
tree | 58a226cf55fc79d9a5ac7ebd5654c157091ef689 /llvm | |
parent | dcf5bd271f7b3b5b4e4c7865f6fa352356daa077 (diff) | |
download | bcm5719-llvm-4a69b0bb3680cb83b0ebc4dbe661e7477cc4c49b.tar.gz bcm5719-llvm-4a69b0bb3680cb83b0ebc4dbe661e7477cc4c49b.zip |
[IPSCCP] Change dead blocks to unreachable after visiting all executable blocks.
changeToUnreachable may remove PHI nodes from executable blocks we found values
for and we would fail to replace them. By changing dead blocks to unreachable after
we replaced constants in all executable blocks, we ensure such PHI nodes are replaced
by their known value before.
Fixes PR37780.
Reviewers: efriedma, davide
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D48421
llvm-svn: 335588
Diffstat (limited to 'llvm')
-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 +} |