@@ -3070,6 +3070,69 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
3070
3070
return nullptr ;
3071
3071
}
3072
3072
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
+
3073
3136
static Value *simplifyICmpWithBinOpOnLHS (CmpInst::Predicate Pred,
3074
3137
BinaryOperator *LBO, Value *RHS,
3075
3138
const SimplifyQuery &Q,
@@ -3079,11 +3142,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
3079
3142
Value *Y = nullptr ;
3080
3143
// icmp pred (or X, Y), X
3081
3144
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
-
3087
3145
if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
3088
3146
KnownBits RHSKnown = computeKnownBits (RHS, /* Depth */ 0 , Q);
3089
3147
KnownBits YKnown = computeKnownBits (Y, /* Depth */ 0 , Q);
@@ -3094,14 +3152,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
3094
3152
}
3095
3153
}
3096
3154
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
-
3105
3155
// icmp pred (urem X, Y), Y
3106
3156
if (match (LBO, m_URem (m_Value (), m_Specific (RHS)))) {
3107
3157
switch (Pred) {
@@ -3132,27 +3182,6 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
3132
3182
}
3133
3183
}
3134
3184
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
-
3156
3185
// If x is nonzero:
3157
3186
// x >>u C <u x --> true for C != 0.
3158
3187
// x >>u C != x --> true for C != 0.
@@ -3172,14 +3201,12 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
3172
3201
break ;
3173
3202
case ICmpInst::ICMP_EQ:
3174
3203
case ICmpInst::ICMP_UGE:
3204
+ case ICmpInst::ICMP_UGT:
3175
3205
return getFalse (ITy);
3176
3206
case ICmpInst::ICMP_NE:
3177
3207
case ICmpInst::ICMP_ULT:
3178
- return getTrue (ITy);
3179
- case ICmpInst::ICMP_UGT:
3180
3208
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);
3183
3210
}
3184
3211
}
3185
3212
}
@@ -3702,13 +3729,6 @@ static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
3702
3729
3703
3730
switch (II->getIntrinsicID ()) {
3704
3731
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
- }
3712
3732
// uadd.sat(X, Y) uge X + Y
3713
3733
if (match (RHS, m_c_Add (m_Specific (II->getArgOperand (0 )),
3714
3734
m_Specific (II->getArgOperand (1 ))))) {
@@ -3719,13 +3739,6 @@ static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
3719
3739
}
3720
3740
return nullptr ;
3721
3741
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
- }
3729
3742
// usub.sat(X, Y) ule X - Y
3730
3743
if (match (RHS, m_Sub (m_Specific (II->getArgOperand (0 )),
3731
3744
m_Specific (II->getArgOperand (1 ))))) {
@@ -4030,6 +4043,12 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
4030
4043
ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
4031
4044
return V;
4032
4045
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
+
4033
4052
if (Value *V = simplifyICmpWithDominatingAssume (Pred, LHS, RHS, Q))
4034
4053
return V;
4035
4054
0 commit comments