@@ -3183,22 +3183,27 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31833183 Builder.CreateAdd (X, ConstantInt::get (Ty, *C2 - C - 1 )),
31843184 ConstantInt::get (Ty, ~C));
31853185
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
31873187 Value *V;
3188- if (Pred == ICmpInst::ICMP_ULT && match (X, m_ZExt (m_Value (V)))) {
3188+ if (match (X, m_ZExt (m_Value (V)))) {
31893189 Type *NewCmpTy = V->getType ();
3190+ unsigned CmpBW = Ty->getScalarSizeInBits ();
31903191 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));
32023207 }
32033208 }
32043209 }
0 commit comments