summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorFlorian Hahn <florian.hahn@arm.com>2018-06-26 10:15:02 +0000
committerFlorian Hahn <florian.hahn@arm.com>2018-06-26 10:15:02 +0000
commit4a69b0bb3680cb83b0ebc4dbe661e7477cc4c49b (patch)
tree58a226cf55fc79d9a5ac7ebd5654c157091ef689 /llvm
parentdcf5bd271f7b3b5b4e4c7865f6fa352356daa077 (diff)
downloadbcm5719-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.cpp14
-rw-r--r--llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll39
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
+}
OpenPOWER on IntegriCloud