@@ -3168,22 +3168,27 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
3168
3168
Builder.CreateAdd (X, ConstantInt::get (Ty, *C2 - C - 1 )),
3169
3169
ConstantInt::get (Ty, ~C));
3170
3170
3171
- // zext(V) + C2 <u C -> V + trunc(C2) <u trunc(C) iff C2 s<0 && C s>0
3171
+ // zext(V) + C2 pred C -> V + C3 pred' C4
3172
3172
Value *V;
3173
- if (Pred == ICmpInst::ICMP_ULT && match (X, m_ZExt (m_Value (V)))) {
3173
+ if (match (X, m_ZExt (m_Value (V)))) {
3174
3174
Type *NewCmpTy = V->getType ();
3175
+ unsigned CmpBW = Ty->getScalarSizeInBits ();
3175
3176
unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits ();
3176
- if (shouldChangeType (Ty, NewCmpTy) &&
3177
- C2->getSignificantBits () <= NewCmpBW &&
3178
- C.getSignificantBits () <= NewCmpBW) {
3179
- APInt TruncatedOffset = C2->trunc (NewCmpBW);
3180
- APInt TruncatedRHS = C.trunc (NewCmpBW);
3181
- if (TruncatedOffset.isNegative () && TruncatedRHS.isNonNegative ()) {
3182
- Value *TruncatedOffsetV = ConstantInt::get (NewCmpTy, TruncatedOffset);
3183
- Value *TruncatedRV = ConstantInt::get (NewCmpTy, TruncatedRHS);
3184
- return new ICmpInst (ICmpInst::ICMP_ULT,
3185
- Builder.CreateAdd (V, TruncatedOffsetV),
3186
- TruncatedRV);
3177
+ if (shouldChangeType (Ty, NewCmpTy)) {
3178
+ if (auto ZExtCR = CR.exactIntersectWith (ConstantRange (
3179
+ APInt::getZero (CmpBW), APInt::getOneBitSet (CmpBW, NewCmpBW)))) {
3180
+ ConstantRange SrcCR = ZExtCR->truncate (NewCmpBW);
3181
+ CmpInst::Predicate EquivPred;
3182
+ APInt EquivInt;
3183
+ APInt EquivOffset;
3184
+
3185
+ SrcCR.getEquivalentICmp (EquivPred, EquivInt, EquivOffset);
3186
+ return new ICmpInst (
3187
+ EquivPred,
3188
+ EquivOffset.isZero ()
3189
+ ? V
3190
+ : Builder.CreateAdd (V, ConstantInt::get (NewCmpTy, EquivOffset)),
3191
+ ConstantInt::get (NewCmpTy, EquivInt));
3187
3192
}
3188
3193
}
3189
3194
}
0 commit comments