aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikolai Bozhenov <nikolai.bozhenov@intel.com>2017-10-17 11:50:48 +0000
committerNikolai Bozhenov <nikolai.bozhenov@intel.com>2017-10-17 11:50:48 +0000
commit346f4329c4eef0e5a9ff36bef087c6648de7f952 (patch)
tree9b1521f164519013c1b26dcc837782efc340465c /llvm/lib/Analysis/ValueTracking.cpp
parenta18b0b181755a6dc7b50b8caa48758907364aaf8 (diff)
downloadllvm-346f4329c4eef0e5a9ff36bef087c6648de7f952.zip
llvm-346f4329c4eef0e5a9ff36bef087c6648de7f952.tar.gz
llvm-346f4329c4eef0e5a9ff36bef087c6648de7f952.tar.bz2
Improve clamp recognition in ValueTracking.
Summary: ValueTracking was recognizing not all variations of clamp. Swapping of true value and false value of select was added to fix this problem. This change breaks the canonical form of cmp inside the matchMinMax function, that is why additional checks for compare predicates is needed. Added corresponding test cases. Reviewers: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D38531 Patch by: Artur Gainullin <artur.gainullin@intel.com> llvm-svn: 315992
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp45
1 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3eddebb..f70f2d1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4083,6 +4083,14 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
Value *CmpLHS, Value *CmpRHS,
Value *TrueVal, Value *FalseVal,
Value *&LHS, Value *&RHS) {
+ assert(!ICmpInst::isEquality(Pred) && "Expected not equality predicate only!");
+
+ // First, check if select has inverse order of what we will check below:
+ if (CmpRHS == FalseVal) {
+ std::swap(TrueVal, FalseVal);
+ Pred = CmpInst::getInversePredicate(Pred);
+ }
+
// Assume success. If there's no match, callers should not use these anyway.
LHS = TrueVal;
RHS = FalseVal;
@@ -4095,26 +4103,30 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
// (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1)
if (match(FalseVal, m_SMin(m_Specific(CmpLHS), m_APInt(C2))) &&
- C1->slt(*C2) && Pred == CmpInst::ICMP_SLT)
+ C1->slt(*C2) &&
+ (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE))
return {SPF_SMAX, SPNB_NA, false};
// (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1)
if (match(FalseVal, m_SMax(m_Specific(CmpLHS), m_APInt(C2))) &&
- C1->sgt(*C2) && Pred == CmpInst::ICMP_SGT)
+ C1->sgt(*C2) &&
+ (Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE))
return {SPF_SMIN, SPNB_NA, false};
// (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1)
if (match(FalseVal, m_UMin(m_Specific(CmpLHS), m_APInt(C2))) &&
- C1->ult(*C2) && Pred == CmpInst::ICMP_ULT)
+ C1->ult(*C2) &&
+ (Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE))
return {SPF_UMAX, SPNB_NA, false};
// (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1)
if (match(FalseVal, m_UMax(m_Specific(CmpLHS), m_APInt(C2))) &&
- C1->ugt(*C2) && Pred == CmpInst::ICMP_UGT)
+ C1->ugt(*C2) &&
+ (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE))
return {SPF_UMIN, SPNB_NA, false};
}
- if (Pred != CmpInst::ICMP_SGT && Pred != CmpInst::ICMP_SLT)
+ if (!CmpInst::isSigned(Pred))
return {SPF_UNKNOWN, SPNB_NA, false};
// Z = X -nsw Y
@@ -4122,14 +4134,18 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
// (X <s Y) ? 0 : Z ==> (Z <s 0) ? 0 : Z ==> SMAX(Z, 0)
if (match(TrueVal, m_Zero()) &&
match(FalseVal, m_NSWSub(m_Specific(CmpLHS), m_Specific(CmpRHS))))
- return {Pred == CmpInst::ICMP_SGT ? SPF_SMIN : SPF_SMAX, SPNB_NA, false};
+ return {(Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) ? SPF_SMIN
+ : SPF_SMAX,
+ SPNB_NA, false};
// Z = X -nsw Y
// (X >s Y) ? Z : 0 ==> (Z >s 0) ? Z : 0 ==> SMAX(Z, 0)
// (X <s Y) ? Z : 0 ==> (Z <s 0) ? Z : 0 ==> SMIN(Z, 0)
if (match(FalseVal, m_Zero()) &&
match(TrueVal, m_NSWSub(m_Specific(CmpLHS), m_Specific(CmpRHS))))
- return {Pred == CmpInst::ICMP_SGT ? SPF_SMAX : SPF_SMIN, SPNB_NA, false};
+ return {(Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) ? SPF_SMAX
+ : SPF_SMIN,
+ SPNB_NA, false};
if (!match(CmpRHS, m_APInt(C1)))
return {SPF_UNKNOWN, SPNB_NA, false};
@@ -4141,14 +4157,15 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
// Is the sign bit set?
// (X <s 0) ? X : MAXVAL ==> (X >u MAXVAL) ? X : MAXVAL ==> UMAX
// (X <s 0) ? MAXVAL : X ==> (X >u MAXVAL) ? MAXVAL : X ==> UMIN
- if (Pred == CmpInst::ICMP_SLT && *C1 == 0 && C2->isMaxSignedValue())
+ if ((Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE) && *C1 == 0 &&
+ C2->isMaxSignedValue())
return {CmpLHS == TrueVal ? SPF_UMAX : SPF_UMIN, SPNB_NA, false};
// Is the sign bit clear?
// (X >s -1) ? MINVAL : X ==> (X <u MINVAL) ? MINVAL : X ==> UMAX
// (X >s -1) ? X : MINVAL ==> (X <u MINVAL) ? X : MINVAL ==> UMIN
- if (Pred == CmpInst::ICMP_SGT && C1->isAllOnesValue() &&
- C2->isMinSignedValue())
+ if ((Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) &&
+ C1->isAllOnesValue() && C2->isMinSignedValue())
return {CmpLHS == FalseVal ? SPF_UMAX : SPF_UMIN, SPNB_NA, false};
}
@@ -4157,13 +4174,17 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
// (X <s C) ? ~X : ~C ==> (~X >s ~C) ? ~X : ~C ==> SMAX(~X, ~C)
if (match(TrueVal, m_Not(m_Specific(CmpLHS))) &&
match(FalseVal, m_APInt(C2)) && ~(*C1) == *C2)
- return {Pred == CmpInst::ICMP_SGT ? SPF_SMIN : SPF_SMAX, SPNB_NA, false};
+ return {(Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) ? SPF_SMIN
+ : SPF_SMAX,
+ SPNB_NA, false};
// (X >s C) ? ~C : ~X ==> (~X <s ~C) ? ~C : ~X ==> SMAX(~C, ~X)
// (X <s C) ? ~C : ~X ==> (~X >s ~C) ? ~C : ~X ==> SMIN(~C, ~X)
if (match(FalseVal, m_Not(m_Specific(CmpLHS))) &&
match(TrueVal, m_APInt(C2)) && ~(*C1) == *C2)
- return {Pred == CmpInst::ICMP_SGT ? SPF_SMAX : SPF_SMIN, SPNB_NA, false};
+ return {(Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) ? SPF_SMAX
+ : SPF_SMIN,
+ SPNB_NA, false};
return {SPF_UNKNOWN, SPNB_NA, false};
}