summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Mi <wmi@google.com>2018-05-01 14:47:24 +0000
committerWei Mi <wmi@google.com>2018-05-01 14:47:24 +0000
commiteec5ba9faea38b911cdd8aaf48cde1bd2e194be4 (patch)
treef198ba8fbc56f21bcb1ac84eb14fd86ea2ae2612
parent54596e1c1a1b1579ab54f4e55cf51a61d10be27d (diff)
downloadbcm5719-llvm-eec5ba9faea38b911cdd8aaf48cde1bd2e194be4.tar.gz
bcm5719-llvm-eec5ba9faea38b911cdd8aaf48cde1bd2e194be4.zip
Fix the issue that ComputeValueKnownInPredecessors only handles the case when
phi is on lhs of a comparison op. For the following testcase, L1: %t0 = add i32 %m, 7 %t3 = icmp eq i32* %t2, null br i1 %t3, label %L3, label %L2 L2: %t4 = load i32, i32* %t2, align 4 br label %L3 L3: %t5 = phi i32 [ %t0, %L1 ], [ %t4, %L2 ] %t6 = icmp eq i32 %t0, %t5 br i1 %t6, label %L4, label %L5 We know if we go through the path L1 --> L3, %t6 should always be true. However currently, if the rhs of the eq comparison is phi, JumpThreading fails to evaluate %t6 to true. And we know that Instcombine cannot guarantee always canonicalizing phi to the left hand side of the comparison operation according to the operand priority comparison mechanism in instcombine. The patch handles the case when rhs of the comparison op is a phi. Differential Revision: https://reviews.llvm.org/D46275 llvm-svn: 331266
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp18
-rw-r--r--llvm/test/Other/pr32085.ll3
-rw-r--r--llvm/test/Transforms/JumpThreading/phi-known.ll38
3 files changed, 55 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 29c707799bd..4e02fc7da20 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -752,6 +752,8 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors(
CmpInst::Predicate Pred = Cmp->getPredicate();
PHINode *PN = dyn_cast<PHINode>(CmpLHS);
+ if (!PN)
+ PN = dyn_cast<PHINode>(CmpRHS);
if (PN && PN->getParent() == BB) {
const DataLayout &DL = PN->getModule()->getDataLayout();
// We can do this simplification if any comparisons fold to true or false.
@@ -762,14 +764,24 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors(
LVI->enableDT();
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
BasicBlock *PredBB = PN->getIncomingBlock(i);
- Value *LHS = PN->getIncomingValue(i);
- Value *RHS = CmpRHS->DoPHITranslation(BB, PredBB);
-
+ Value *LHS, *RHS;
+ if (PN == CmpLHS) {
+ LHS = PN->getIncomingValue(i);
+ RHS = CmpRHS->DoPHITranslation(BB, PredBB);
+ } else {
+ LHS = CmpLHS->DoPHITranslation(BB, PredBB);
+ RHS = PN->getIncomingValue(i);
+ }
Value *Res = SimplifyCmpInst(Pred, LHS, RHS, {DL});
if (!Res) {
if (!isa<Constant>(RHS))
continue;
+ // getPredicateOnEdge call will make no sense if LHS is defined in BB.
+ auto LHSInst = dyn_cast<Instruction>(LHS);
+ if (LHSInst && LHSInst->getParent() == BB)
+ continue;
+
LazyValueInfo::Tristate
ResT = LVI->getPredicateOnEdge(Pred, LHS,
cast<Constant>(RHS), PredBB, BB,
diff --git a/llvm/test/Other/pr32085.ll b/llvm/test/Other/pr32085.ll
index 428f91e52b5..d850bf2761e 100644
--- a/llvm/test/Other/pr32085.ll
+++ b/llvm/test/Other/pr32085.ll
@@ -1,6 +1,7 @@
; RUN: opt -S -O1 < %s -o %t1.ll
;; Show that there's no difference after running another simplify CFG
-; RUN: opt -S -simplifycfg < %t1.ll -o %t2.ll
+; RUN: opt -S -simplifycfg < %t1.ll -o %t2.ll
+; RUN: sed -i 's/; preds = .*//g' %t1.ll %t2.ll
; RUN: diff %t1.ll %t2.ll
; Test from LoopSink pass, leaves some single-entry single-exit basic blocks.
diff --git a/llvm/test/Transforms/JumpThreading/phi-known.ll b/llvm/test/Transforms/JumpThreading/phi-known.ll
index 8eaf57f748a..3473806c0a6 100644
--- a/llvm/test/Transforms/JumpThreading/phi-known.ll
+++ b/llvm/test/Transforms/JumpThreading/phi-known.ll
@@ -64,3 +64,41 @@ exit:
ret void
}
+; The eq predicate is always true if we go through the path from
+; L1 to L3, no matter the phi result %t5 is on the lhs or rhs of
+; the predicate.
+declare void @goo()
+declare void @hoo()
+
+define void @test3(i32 %m, i32** %t1) {
+L1:
+ %t0 = add i32 %m, 7
+ %t2 = load i32*, i32** %t1, align 8
+; CHECK-LABEL: @test3
+; CHECK: %t3 = icmp eq i32* %t2, null
+; CHECK: br i1 %t3, label %[[LABEL2:.*]], label %[[LABEL1:.*]]
+
+ %t3 = icmp eq i32* %t2, null
+ br i1 %t3, label %L3, label %L2
+
+; CHECK: [[LABEL1]]:
+; CHECK-NEXT: %t4 = load i32, i32* %t2, align 4
+L2:
+ %t4 = load i32, i32* %t2, align 4
+ br label %L3
+
+L3:
+ %t5 = phi i32 [ %t0, %L1 ], [ %t4, %L2 ]
+ %t6 = icmp eq i32 %t0, %t5
+ br i1 %t6, label %L4, label %L5
+
+; CHECK: [[LABEL2]]:
+; CHECK-NEXT: call void @goo()
+L4:
+ call void @goo()
+ ret void
+
+L5:
+ call void @hoo()
+ ret void
+}
OpenPOWER on IntegriCloud