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