@@ -3168,22 +3168,27 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31683168 Builder.CreateAdd (X, ConstantInt::get (Ty, *C2 - C - 1 )),
31693169 ConstantInt::get (Ty, ~C));
31703170
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
31723172 Value *V;
3173- if (Pred == ICmpInst::ICMP_ULT && match (X, m_ZExt (m_Value (V)))) {
3173+ if (match (X, m_ZExt (m_Value (V)))) {
31743174 Type *NewCmpTy = V->getType ();
3175+ unsigned CmpBW = Ty->getScalarSizeInBits ();
31753176 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));
31873192 }
31883193 }
31893194 }
0 commit comments