diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index b8f6066bf05..6a322438f5a 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4179,7 +4179,9 @@ static SelectPatternResult matchMinMaxOfMinMax(CmpInst::Predicate Pred, if (L.Flavor != R.Flavor) return {SPF_UNKNOWN, SPNB_NA, false}; - // Match the compare to the min/max operations of the select operands. + // We have something like: x Pred y ? min(a, b) : min(c, d). + // Try to match the compare to the min/max operations of the select operands. + // First, make sure we have the right compare predicate. switch (L.Flavor) { case SPF_SMIN: if (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SGE) { @@ -4217,21 +4219,38 @@ static SelectPatternResult matchMinMaxOfMinMax(CmpInst::Predicate Pred, return {SPF_UNKNOWN, SPNB_NA, false}; } - // a pred c ? m(a, b) : m(c, b) --> m(m(a, b), m(c, b)) - if (CmpLHS == A && CmpRHS == C && D == B) - return {L.Flavor, SPNB_NA, false}; + // If there is a common operand in the already matched min/max and the other + // min/max operands match the compare operands (either directly or inverted), + // then this is min/max of the same flavor. + // a pred c ? m(a, b) : m(c, b) --> m(m(a, b), m(c, b)) + // ~c pred ~a ? m(a, b) : m(c, b) --> m(m(a, b), m(c, b)) + if (D == B) { + if ((CmpLHS == A && CmpRHS == C) || (match(C, m_Not(m_Specific(CmpLHS))) && + match(A, m_Not(m_Specific(CmpRHS))))) + return {L.Flavor, SPNB_NA, false}; + } // a pred d ? m(a, b) : m(b, d) --> m(m(a, b), m(b, d)) - if (CmpLHS == A && CmpRHS == D && C == B) - return {L.Flavor, SPNB_NA, false}; - + // ~d pred ~a ? m(a, b) : m(b, d) --> m(m(a, b), m(b, d)) + if (C == B) { + if ((CmpLHS == A && CmpRHS == D) || (match(D, m_Not(m_Specific(CmpLHS))) && + match(A, m_Not(m_Specific(CmpRHS))))) + return {L.Flavor, SPNB_NA, false}; + } // b pred c ? m(a, b) : m(c, a) --> m(m(a, b), m(c, a)) - if (CmpLHS == B && CmpRHS == C && D == A) - return {L.Flavor, SPNB_NA, false}; - + // ~c pred ~b ? m(a, b) : m(c, a) --> m(m(a, b), m(c, a)) + if (D == A) { + if ((CmpLHS == B && CmpRHS == C) || (match(C, m_Not(m_Specific(CmpLHS))) && + match(B, m_Not(m_Specific(CmpRHS))))) + return {L.Flavor, SPNB_NA, false}; + } // b pred d ? m(a, b) : m(a, d) --> m(m(a, b), m(a, d)) - if (CmpLHS == B && CmpRHS == D && C == A) - return {L.Flavor, SPNB_NA, false}; + // ~d pred ~b ? m(a, b) : m(a, d) --> m(m(a, b), m(a, d)) + if (C == A) { + if ((CmpLHS == B && CmpRHS == D) || (match(D, m_Not(m_Specific(CmpLHS))) && + match(B, m_Not(m_Specific(CmpRHS))))) + return {L.Flavor, SPNB_NA, false}; + } return {SPF_UNKNOWN, SPNB_NA, false}; } |