@@ -3183,22 +3183,27 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
3183
3183
Builder.CreateAdd (X, ConstantInt::get (Ty, *C2 - C - 1 )),
3184
3184
ConstantInt::get (Ty, ~C));
3185
3185
3186
- // zext(V) + C2 <u C -> V + trunc(C2) <u trunc(C) iff C2 s<0 && C s>0
3186
+ // zext(V) + C2 pred C -> V + C3 pred' C4
3187
3187
Value *V;
3188
- if (Pred == ICmpInst::ICMP_ULT && match (X, m_ZExt (m_Value (V)))) {
3188
+ if (match (X, m_ZExt (m_Value (V)))) {
3189
3189
Type *NewCmpTy = V->getType ();
3190
+ unsigned CmpBW = Ty->getScalarSizeInBits ();
3190
3191
unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits ();
3191
- if (shouldChangeType (Ty, NewCmpTy) &&
3192
- C2->getSignificantBits () <= NewCmpBW &&
3193
- C.getSignificantBits () <= NewCmpBW) {
3194
- APInt TruncatedOffset = C2->trunc (NewCmpBW);
3195
- APInt TruncatedRHS = C.trunc (NewCmpBW);
3196
- if (TruncatedOffset.isNegative () && TruncatedRHS.isNonNegative ()) {
3197
- Value *TruncatedOffsetV = ConstantInt::get (NewCmpTy, TruncatedOffset);
3198
- Value *TruncatedRV = ConstantInt::get (NewCmpTy, TruncatedRHS);
3199
- return new ICmpInst (ICmpInst::ICMP_ULT,
3200
- Builder.CreateAdd (V, TruncatedOffsetV),
3201
- TruncatedRV);
3192
+ if (shouldChangeType (Ty, NewCmpTy)) {
3193
+ if (auto ZExtCR = CR.exactIntersectWith (ConstantRange (
3194
+ APInt::getZero (CmpBW), APInt::getOneBitSet (CmpBW, NewCmpBW)))) {
3195
+ ConstantRange SrcCR = ZExtCR->truncate (NewCmpBW);
3196
+ CmpInst::Predicate EquivPred;
3197
+ APInt EquivInt;
3198
+ APInt EquivOffset;
3199
+
3200
+ SrcCR.getEquivalentICmp (EquivPred, EquivInt, EquivOffset);
3201
+ return new ICmpInst (
3202
+ EquivPred,
3203
+ EquivOffset.isZero ()
3204
+ ? V
3205
+ : Builder.CreateAdd (V, ConstantInt::get (NewCmpTy, EquivOffset)),
3206
+ ConstantInt::get (NewCmpTy, EquivInt));
3202
3207
}
3203
3208
}
3204
3209
}
0 commit comments