summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.katkov@azul.com>2018-03-12 03:50:07 +0000
committerSerguei Katkov <serguei.katkov@azul.com>2018-03-12 03:50:07 +0000
commita20e05bb94789c01146fcc972712a1a9182b616e (patch)
treef2e5d58a10216689ac20e738be144b1f2fd15e45
parent8b8d6bf62f39c316c087543578edc7e4044e1d35 (diff)
downloadbcm5719-llvm-a20e05bb94789c01146fcc972712a1a9182b616e.tar.gz
bcm5719-llvm-a20e05bb94789c01146fcc972712a1a9182b616e.zip
[CGP] Fix the remove of matched phis in complex addressing mode
When we replace the Phi we created with matched ones it is possible that there are two identical phi nodes in IR. And matcher is smart enough to find that new created phi matches both of them. So we try to replace our phi node with matched ones twice and what is bad we delete our phi node twice causing a crash. As soon as we found that we have two identical Phi nodes it makes sense to do a clean-up and replace one phi node by other one. The patch implements it. Reviewers: john.brawn, reames Reviewed By: john.brawn Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D43758 llvm-svn: 327250
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp14
-rw-r--r--llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll27
2 files changed, 40 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 1b1bad1ac93..422a0a972fb 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2946,8 +2946,20 @@ private:
Matched.clear();
}
if (IsMatched) {
- // Replace all matched values and erase them.
+ // If we matched phi node to different but identical phis then
+ // make a simplification here.
+ DenseMap<PHINode *, PHINode *> MatchedPHINodeMapping;
for (auto MV : Matched) {
+ auto AlreadyMatched = MatchedPHINodeMapping.find(MV.first);
+ if (AlreadyMatched != MatchedPHINodeMapping.end()) {
+ MV.second->replaceAllUsesWith(AlreadyMatched->second);
+ ST.Put(MV.second, AlreadyMatched->second);
+ MV.second->eraseFromParent();
+ } else
+ MatchedPHINodeMapping.insert({ MV.first, MV.second });
+ }
+ // Replace all matched values and erase them.
+ for (auto MV : MatchedPHINodeMapping) {
MV.first->replaceAllUsesWith(MV.second);
PhiNodesToMatch.erase(MV.first);
ST.Put(MV.first, MV.second);
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll
new file mode 100644
index 00000000000..817382a07bd
--- /dev/null
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false %s | FileCheck %s --check-prefix=CHECK
+target datalayout =
+"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test() {
+entry:
+ %0 = getelementptr inbounds i64, i64 * null, i64 undef
+ br label %start
+
+start:
+ %val1 = phi i64 * [ %0, %entry ], [ %val4, %exit ]
+ %val2 = phi i64 * [ null, %entry ], [ %val5, %exit ]
+ br i1 false, label %slowpath, label %exit
+
+slowpath:
+ %elem1 = getelementptr inbounds i64, i64 * undef, i64 undef
+ br label %exit
+
+exit:
+; CHECK: sunkaddr
+ %val3 = phi i64 * [ undef, %slowpath ], [ %val2, %start ]
+ %val4 = phi i64 * [ %elem1, %slowpath ], [ %val1, %start ]
+ %val5 = phi i64 * [ undef, %slowpath ], [ %val2, %start ]
+ %loadx = load i64, i64 * %val4, align 8
+ br label %start
+}
OpenPOWER on IntegriCloud