aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorJohn Brawn <john.brawn@arm.com>2018-06-04 16:53:57 +0000
committerJohn Brawn <john.brawn@arm.com>2018-06-04 16:53:57 +0000
commitc5a6392be3bd00c5ab31450a42a2fb713257f4ee (patch)
tree3064442c13c57ff7cdd6ff3ca4e0ccbc0a73c941 /llvm/lib/Analysis/ValueTracking.cpp
parentf0b93f1e9e649dde693c40ce4fc929fba068abae (diff)
downloadllvm-c5a6392be3bd00c5ab31450a42a2fb713257f4ee.zip
llvm-c5a6392be3bd00c5ab31450a42a2fb713257f4ee.tar.gz
llvm-c5a6392be3bd00c5ab31450a42a2fb713257f4ee.tar.bz2
[ValueTracking] Match select abs pattern when there's an sext involved
When checking a select to see if it matches an abs, allow the true/false values to be a sign-extension of the comparison value instead of requiring that they're directly the comparison value, as all the comparison cares about is the sign of the value. This fixes a regression due to r333702, where we were no longer generating ctlz due to isKnownNonNegative failing to match such a pattern. Differential Revision: https://reviews.llvm.org/D47631 llvm-svn: 333927
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 8cff7a6..12002de 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4604,23 +4604,35 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
const APInt *C1;
if (match(CmpRHS, m_APInt(C1))) {
- if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) ||
- (CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) {
- // Set RHS to the negate operand. LHS was assigned to CmpLHS earlier.
- RHS = (CmpLHS == TrueVal) ? FalseVal : TrueVal;
+ // Sign-extending LHS does not change its sign, so TrueVal/FalseVal can
+ // match against either LHS or sext(LHS).
+ auto MaybeSExtLHS = m_CombineOr(m_Specific(CmpLHS),
+ m_SExt(m_Specific(CmpLHS)));
+ if ((match(TrueVal, MaybeSExtLHS) &&
+ match(FalseVal, m_Neg(m_Specific(TrueVal)))) ||
+ (match(FalseVal, MaybeSExtLHS) &&
+ match(TrueVal, m_Neg(m_Specific(FalseVal))))) {
+ // Set LHS and RHS so that RHS is the negated operand of the select
+ if (match(TrueVal, MaybeSExtLHS)) {
+ LHS = TrueVal;
+ RHS = FalseVal;
+ } else {
+ LHS = FalseVal;
+ RHS = TrueVal;
+ }
// ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X
// NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X
if (Pred == ICmpInst::ICMP_SGT &&
(C1->isNullValue() || C1->isAllOnesValue())) {
- return {(CmpLHS == TrueVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
+ return {(LHS == TrueVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
}
// ABS(X) ==> (X <s 0) ? -X : X and (X <s 1) ? -X : X
// NABS(X) ==> (X <s 0) ? X : -X and (X <s 1) ? X : -X
if (Pred == ICmpInst::ICMP_SLT &&
(C1->isNullValue() || C1->isOneValue())) {
- return {(CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
+ return {(LHS == FalseVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
}
}
}