diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-11-10 23:56:20 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-11-10 23:56:20 +0000 |
commit | 925681053dd50567db83f254bf47107689373ca1 (patch) | |
tree | 46aa09a5b081bb811af19f950d2c2148b1aee5b3 /llvm/lib/Analysis | |
parent | af1400f84b6a4a7306b2a43ceef08a5b17936d38 (diff) | |
download | bcm5719-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.cpp | 30 |
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; } } |