@@ -3070,6 +3070,69 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
30703070 return nullptr ;
30713071}
30723072
3073+ enum class MonotonicType { GreaterEq, LowerEq };
3074+
3075+ // / Get values V_i such that V uge V_i (GreaterEq) or V ule V_i (LowerEq).
3076+ static void getUnsignedMonotonicValues (SmallPtrSetImpl<Value *> &Res, Value *V,
3077+ MonotonicType Type, unsigned Depth = 0 ) {
3078+ if (!Res.insert (V).second )
3079+ return ;
3080+
3081+ // Can be increased if useful.
3082+ if (++Depth > 1 )
3083+ return ;
3084+
3085+ auto *I = dyn_cast<Instruction>(V);
3086+ if (!I)
3087+ return ;
3088+
3089+ Value *X, *Y;
3090+ if (Type == MonotonicType::GreaterEq) {
3091+ if (match (I, m_Or (m_Value (X), m_Value (Y))) ||
3092+ match (I, m_Intrinsic<Intrinsic::uadd_sat>(m_Value (X), m_Value (Y)))) {
3093+ getUnsignedMonotonicValues (Res, X, Type, Depth);
3094+ getUnsignedMonotonicValues (Res, Y, Type, Depth);
3095+ }
3096+ } else {
3097+ assert (Type == MonotonicType::LowerEq);
3098+ switch (I->getOpcode ()) {
3099+ case Instruction::And:
3100+ getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Depth);
3101+ getUnsignedMonotonicValues (Res, I->getOperand (1 ), Type, Depth);
3102+ break ;
3103+ case Instruction::URem:
3104+ case Instruction::UDiv:
3105+ case Instruction::LShr:
3106+ getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Depth);
3107+ break ;
3108+ case Instruction::Call:
3109+ if (match (I, m_Intrinsic<Intrinsic::usub_sat>(m_Value (X))))
3110+ getUnsignedMonotonicValues (Res, X, Type, Depth);
3111+ break ;
3112+ default :
3113+ break ;
3114+ }
3115+ }
3116+ }
3117+
3118+ static Value *simplifyICmpUsingMonotonicValues (ICmpInst::Predicate Pred,
3119+ Value *LHS, Value *RHS) {
3120+ if (Pred != ICmpInst::ICMP_UGE && Pred != ICmpInst::ICMP_ULT)
3121+ return nullptr ;
3122+
3123+ // We have LHS uge GreaterValues and LowerValues uge RHS. If any of the
3124+ // GreaterValues and LowerValues are the same, it follows that LHS uge RHS.
3125+ SmallPtrSet<Value *, 4 > GreaterValues;
3126+ SmallPtrSet<Value *, 4 > LowerValues;
3127+ getUnsignedMonotonicValues (GreaterValues, LHS, MonotonicType::GreaterEq);
3128+ getUnsignedMonotonicValues (LowerValues, RHS, MonotonicType::LowerEq);
3129+ for (Value *GV : GreaterValues)
3130+ if (LowerValues.contains (GV))
3131+ return ConstantInt::getBool (getCompareTy (LHS),
3132+ Pred == ICmpInst::ICMP_UGE);
3133+ return nullptr ;
3134+ }
3135+
30733136static Value *simplifyICmpWithBinOpOnLHS (CmpInst::Predicate Pred,
30743137 BinaryOperator *LBO, Value *RHS,
30753138 const SimplifyQuery &Q,
@@ -3079,11 +3142,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
30793142 Value *Y = nullptr ;
30803143 // icmp pred (or X, Y), X
30813144 if (match (LBO, m_c_Or (m_Value (Y), m_Specific (RHS)))) {
3082- if (Pred == ICmpInst::ICMP_ULT)
3083- return getFalse (ITy);
3084- if (Pred == ICmpInst::ICMP_UGE)
3085- return getTrue (ITy);
3086-
30873145 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
30883146 KnownBits RHSKnown = computeKnownBits (RHS, /* Depth */ 0 , Q);
30893147 KnownBits YKnown = computeKnownBits (Y, /* Depth */ 0 , Q);
@@ -3094,14 +3152,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
30943152 }
30953153 }
30963154
3097- // icmp pred (and X, Y), X
3098- if (match (LBO, m_c_And (m_Value (), m_Specific (RHS)))) {
3099- if (Pred == ICmpInst::ICMP_UGT)
3100- return getFalse (ITy);
3101- if (Pred == ICmpInst::ICMP_ULE)
3102- return getTrue (ITy);
3103- }
3104-
31053155 // icmp pred (urem X, Y), Y
31063156 if (match (LBO, m_URem (m_Value (), m_Specific (RHS)))) {
31073157 switch (Pred) {
@@ -3132,27 +3182,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
31323182 }
31333183 }
31343184
3135- // icmp pred (urem X, Y), X
3136- if (match (LBO, m_URem (m_Specific (RHS), m_Value ()))) {
3137- if (Pred == ICmpInst::ICMP_ULE)
3138- return getTrue (ITy);
3139- if (Pred == ICmpInst::ICMP_UGT)
3140- return getFalse (ITy);
3141- }
3142-
3143- // x >>u y <=u x --> true.
3144- // x >>u y >u x --> false.
3145- // x udiv y <=u x --> true.
3146- // x udiv y >u x --> false.
3147- if (match (LBO, m_LShr (m_Specific (RHS), m_Value ())) ||
3148- match (LBO, m_UDiv (m_Specific (RHS), m_Value ()))) {
3149- // icmp pred (X op Y), X
3150- if (Pred == ICmpInst::ICMP_UGT)
3151- return getFalse (ITy);
3152- if (Pred == ICmpInst::ICMP_ULE)
3153- return getTrue (ITy);
3154- }
3155-
31563185 // If x is nonzero:
31573186 // x >>u C <u x --> true for C != 0.
31583187 // x >>u C != x --> true for C != 0.
@@ -3172,14 +3201,12 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
31723201 break ;
31733202 case ICmpInst::ICMP_EQ:
31743203 case ICmpInst::ICMP_UGE:
3204+ case ICmpInst::ICMP_UGT:
31753205 return getFalse (ITy);
31763206 case ICmpInst::ICMP_NE:
31773207 case ICmpInst::ICMP_ULT:
3178- return getTrue (ITy);
3179- case ICmpInst::ICMP_UGT:
31803208 case ICmpInst::ICMP_ULE:
3181- // UGT/ULE are handled by the more general case just above
3182- llvm_unreachable (" Unexpected UGT/ULE, should have been handled" );
3209+ return getTrue (ITy);
31833210 }
31843211 }
31853212 }
@@ -3702,13 +3729,6 @@ static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
37023729
37033730 switch (II->getIntrinsicID ()) {
37043731 case Intrinsic::uadd_sat:
3705- // uadd.sat(X, Y) uge X, uadd.sat(X, Y) uge Y
3706- if (II->getArgOperand (0 ) == RHS || II->getArgOperand (1 ) == RHS) {
3707- if (Pred == ICmpInst::ICMP_UGE)
3708- return ConstantInt::getTrue (getCompareTy (II));
3709- if (Pred == ICmpInst::ICMP_ULT)
3710- return ConstantInt::getFalse (getCompareTy (II));
3711- }
37123732 // uadd.sat(X, Y) uge X + Y
37133733 if (match (RHS, m_c_Add (m_Specific (II->getArgOperand (0 )),
37143734 m_Specific (II->getArgOperand (1 ))))) {
@@ -3719,13 +3739,6 @@ static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
37193739 }
37203740 return nullptr ;
37213741 case Intrinsic::usub_sat:
3722- // usub.sat(X, Y) ule X
3723- if (II->getArgOperand (0 ) == RHS) {
3724- if (Pred == ICmpInst::ICMP_ULE)
3725- return ConstantInt::getTrue (getCompareTy (II));
3726- if (Pred == ICmpInst::ICMP_UGT)
3727- return ConstantInt::getFalse (getCompareTy (II));
3728- }
37293742 // usub.sat(X, Y) ule X - Y
37303743 if (match (RHS, m_Sub (m_Specific (II->getArgOperand (0 )),
37313744 m_Specific (II->getArgOperand (1 ))))) {
@@ -4030,6 +4043,12 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
40304043 ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
40314044 return V;
40324045
4046+ if (Value *V = simplifyICmpUsingMonotonicValues (Pred, LHS, RHS))
4047+ return V;
4048+ if (Value *V = simplifyICmpUsingMonotonicValues (
4049+ ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
4050+ return V;
4051+
40334052 if (Value *V = simplifyICmpWithDominatingAssume (Pred, LHS, RHS, Q))
40344053 return V;
40354054
0 commit comments