summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-11-10 23:56:20 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-11-10 23:56:20 +0000
commit925681053dd50567db83f254bf47107689373ca1 (patch)
tree46aa09a5b081bb811af19f950d2c2148b1aee5b3 /llvm/lib/Analysis
parentaf1400f84b6a4a7306b2a43ceef08a5b17936d38 (diff)
downloadbcm5719-llvm-925681053dd50567db83f254bf47107689373ca1.tar.gz
bcm5719-llvm-925681053dd50567db83f254bf47107689373ca1.zip
[ValueTracking] Teach isImpliedCondition a new bitwise trick
Summary: This change teaches isImpliedCondition to prove things like (A | 15) < L ==> (A | 14) < L if the low 4 bits of A are known to be zero. Depends on D14391 Reviewers: majnemer, reames, hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14392 llvm-svn: 252673
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e4cbdb9249f..f851892d3d3 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4136,6 +4136,36 @@ static bool isTruePredicate(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
return C->isMinValue();
return true;
}
+
+ // Match A to (X +_{nuw} CA) and B to (X +_{nuw} CB)
+ auto MatchNUWAddsToSameValue = [&](Value *A, Value *B, Value *&X,
+ const APInt *&CA, const APInt *&CB) {
+ if (match(A, m_NUWAdd(m_Value(X), m_APInt(CA))) &&
+ match(B, m_NUWAdd(m_Specific(X), m_APInt(CB))))
+ return true;
+
+ // If X & C == 0 then (X | C) == X +_{nuw} C
+ if (match(A, m_Or(m_Value(X), m_APInt(CA))) &&
+ match(B, m_Or(m_Specific(X), m_APInt(CB)))) {
+ unsigned BitWidth = CA->getBitWidth();
+ APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+ computeKnownBits(X, KnownZero, KnownOne, DL, Depth + 1, AC, CxtI, DT);
+
+ if ((KnownZero & *CA) == *CA && (KnownZero & *CB) == *CB)
+ return true;
+ }
+
+ return false;
+ };
+
+ Value *X;
+ const APInt *CLHS, *CRHS;
+ if (MatchNUWAddsToSameValue(LHS, RHS, X, CLHS, CRHS)) {
+ if (Pred == CmpInst::ICMP_ULE)
+ return CLHS->ule(*CRHS);
+ return CLHS->ult(*CRHS);
+ }
+
return false;
}
}
OpenPOWER on IntegriCloud