@@ -3103,6 +3103,54 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
31033103 return nullptr ;
31043104}
31053105
3106+ // / Get values V_i such that V uge V_i (Greater) or V ule V_i (!Greater).
3107+ static void getUnsignedMonotonicValues (SmallPtrSetImpl<Value *> &Res, Value *V,
3108+ bool Greater, unsigned Depth = 0 ) {
3109+ if (!Res.insert (V).second )
3110+ return ;
3111+
3112+ // Can be increased if useful.
3113+ if (++Depth > 1 )
3114+ return ;
3115+
3116+ Value *X, *Y;
3117+ if (Greater) {
3118+ if (match (V, m_Or (m_Value (X), m_Value (Y))) ||
3119+ match (V, m_Intrinsic<Intrinsic::uadd_sat>(m_Value (X), m_Value (Y)))) {
3120+ getUnsignedMonotonicValues (Res, X, Greater, Depth);
3121+ getUnsignedMonotonicValues (Res, Y, Greater, Depth);
3122+ }
3123+ } else {
3124+ if (match (V, m_And (m_Value (X), m_Value (Y)))) {
3125+ getUnsignedMonotonicValues (Res, X, Greater, Depth);
3126+ getUnsignedMonotonicValues (Res, Y, Greater, Depth);
3127+ } else if (match (V, m_URem (m_Value (X), m_Value ())) ||
3128+ match (V, m_UDiv (m_Value (X), m_Value ())) ||
3129+ match (V, m_LShr (m_Value (X), m_Value ())) ||
3130+ match (V, m_Intrinsic<Intrinsic::usub_sat>(m_Value (X)))) {
3131+ getUnsignedMonotonicValues (Res, X, Greater, Depth);
3132+ }
3133+ }
3134+ }
3135+
3136+ static Value *simplifyICmpUsingMonotonicValues (ICmpInst::Predicate Pred,
3137+ Value *LHS, Value *RHS) {
3138+ if (Pred != ICmpInst::ICMP_UGE && Pred != ICmpInst::ICMP_ULT)
3139+ return nullptr ;
3140+
3141+ // We have LHS uge GreaterValues and LowerValues uge RHS. If any of the
3142+ // GreaterValues and LowerValues are the same, it follows that LHS uge RHS.
3143+ SmallPtrSet<Value *, 4 > GreaterValues;
3144+ SmallPtrSet<Value *, 4 > LowerValues;
3145+ getUnsignedMonotonicValues (GreaterValues, LHS, /* Greater*/ true );
3146+ getUnsignedMonotonicValues (LowerValues, RHS, /* Greater*/ false );
3147+ for (Value *GV : GreaterValues)
3148+ if (LowerValues.contains (GV))
3149+ return ConstantInt::getBool (getCompareTy (LHS),
3150+ Pred == ICmpInst::ICMP_UGE);
3151+ return nullptr ;
3152+ }
3153+
31063154static Value *simplifyICmpWithBinOpOnLHS (CmpInst::Predicate Pred,
31073155 BinaryOperator *LBO, Value *RHS,
31083156 const SimplifyQuery &Q,
@@ -3112,11 +3160,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
31123160 Value *Y = nullptr ;
31133161 // icmp pred (or X, Y), X
31143162 if (match (LBO, m_c_Or (m_Value (Y), m_Specific (RHS)))) {
3115- if (Pred == ICmpInst::ICMP_ULT)
3116- return getFalse (ITy);
3117- if (Pred == ICmpInst::ICMP_UGE)
3118- return getTrue (ITy);
3119-
31203163 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
31213164 KnownBits RHSKnown = computeKnownBits (RHS, Q.DL , 0 , Q.AC , Q.CxtI , Q.DT );
31223165 KnownBits YKnown = computeKnownBits (Y, Q.DL , 0 , Q.AC , Q.CxtI , Q.DT );
@@ -3127,14 +3170,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
31273170 }
31283171 }
31293172
3130- // icmp pred (and X, Y), X
3131- if (match (LBO, m_c_And (m_Value (), m_Specific (RHS)))) {
3132- if (Pred == ICmpInst::ICMP_UGT)
3133- return getFalse (ITy);
3134- if (Pred == ICmpInst::ICMP_ULE)
3135- return getTrue (ITy);
3136- }
3137-
31383173 // icmp pred (urem X, Y), Y
31393174 if (match (LBO, m_URem (m_Value (), m_Specific (RHS)))) {
31403175 switch (Pred) {
@@ -3165,27 +3200,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
31653200 }
31663201 }
31673202
3168- // icmp pred (urem X, Y), X
3169- if (match (LBO, m_URem (m_Specific (RHS), m_Value ()))) {
3170- if (Pred == ICmpInst::ICMP_ULE)
3171- return getTrue (ITy);
3172- if (Pred == ICmpInst::ICMP_UGT)
3173- return getFalse (ITy);
3174- }
3175-
3176- // x >>u y <=u x --> true.
3177- // x >>u y >u x --> false.
3178- // x udiv y <=u x --> true.
3179- // x udiv y >u x --> false.
3180- if (match (LBO, m_LShr (m_Specific (RHS), m_Value ())) ||
3181- match (LBO, m_UDiv (m_Specific (RHS), m_Value ()))) {
3182- // icmp pred (X op Y), X
3183- if (Pred == ICmpInst::ICMP_UGT)
3184- return getFalse (ITy);
3185- if (Pred == ICmpInst::ICMP_ULE)
3186- return getTrue (ITy);
3187- }
3188-
31893203 // If x is nonzero:
31903204 // x >>u C <u x --> true for C != 0.
31913205 // x >>u C != x --> true for C != 0.
@@ -3727,36 +3741,6 @@ static Value *simplifyICmpWithDominatingAssume(CmpInst::Predicate Predicate,
37273741 return nullptr ;
37283742}
37293743
3730- static Value *simplifyICmpWithIntrinsicOnLHS (CmpInst::Predicate Pred,
3731- Value *LHS, Value *RHS) {
3732- auto *II = dyn_cast<IntrinsicInst>(LHS);
3733- if (!II)
3734- return nullptr ;
3735-
3736- switch (II->getIntrinsicID ()) {
3737- case Intrinsic::uadd_sat:
3738- // uadd.sat(X, Y) uge X, uadd.sat(X, Y) uge Y
3739- if (II->getArgOperand (0 ) == RHS || II->getArgOperand (1 ) == RHS) {
3740- if (Pred == ICmpInst::ICMP_UGE)
3741- return ConstantInt::getTrue (getCompareTy (II));
3742- if (Pred == ICmpInst::ICMP_ULT)
3743- return ConstantInt::getFalse (getCompareTy (II));
3744- }
3745- return nullptr ;
3746- case Intrinsic::usub_sat:
3747- // usub.sat(X, Y) ule X
3748- if (II->getArgOperand (0 ) == RHS) {
3749- if (Pred == ICmpInst::ICMP_ULE)
3750- return ConstantInt::getTrue (getCompareTy (II));
3751- if (Pred == ICmpInst::ICMP_UGT)
3752- return ConstantInt::getFalse (getCompareTy (II));
3753- }
3754- return nullptr ;
3755- default :
3756- return nullptr ;
3757- }
3758- }
3759-
37603744// / Given operands for an ICmpInst, see if we can fold the result.
37613745// / If not, this returns null.
37623746static Value *simplifyICmpInst (unsigned Predicate, Value *LHS, Value *RHS,
@@ -4034,9 +4018,9 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
40344018 if (Value *V = simplifyICmpWithMinMax (Pred, LHS, RHS, Q, MaxRecurse))
40354019 return V;
40364020
4037- if (Value *V = simplifyICmpWithIntrinsicOnLHS (Pred, LHS, RHS))
4021+ if (Value *V = simplifyICmpUsingMonotonicValues (Pred, LHS, RHS))
40384022 return V;
4039- if (Value *V = simplifyICmpWithIntrinsicOnLHS (
4023+ if (Value *V = simplifyICmpUsingMonotonicValues (
40404024 ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
40414025 return V;
40424026
0 commit comments