@@ -2674,10 +2674,41 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
26742674Instruction *InstCombinerImpl::foldICmpSRemConstant (ICmpInst &Cmp,
26752675 BinaryOperator *SRem,
26762676 const APInt &C) {
2677+ const ICmpInst::Predicate Pred = Cmp.getPredicate ();
2678+ if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT) {
2679+ // Canonicalize unsigned predicates to signed:
2680+ // (X s% DivisorC) u> C -> (X s% DivisorC) s< 0
2681+ // iff (C s< 0 ? ~C : C) u>= abs(DivisorC)-1
2682+ // (X s% DivisorC) u< C+1 -> (X s% DivisorC) s> -1
2683+ // iff (C+1 s< 0 ? ~C : C) u>= abs(DivisorC)-1
2684+
2685+ const APInt *DivisorC;
2686+ if (!match (SRem->getOperand (1 ), m_APInt (DivisorC)))
2687+ return nullptr ;
2688+
2689+ APInt NormalizedC = C;
2690+ if (Pred == ICmpInst::ICMP_ULT) {
2691+ assert (!NormalizedC.isZero () &&
2692+ " ult X, 0 should have been simplified already." );
2693+ --NormalizedC;
2694+ }
2695+ if (C.isNegative ())
2696+ NormalizedC.flipAllBits ();
2697+ assert (!DivisorC->isZero () &&
2698+ " srem X, 0 should have been simplified already." );
2699+ if (!NormalizedC.uge (DivisorC->abs () - 1 ))
2700+ return nullptr ;
2701+
2702+ Type *Ty = SRem->getType ();
2703+ if (Pred == ICmpInst::ICMP_UGT)
2704+ return new ICmpInst (ICmpInst::ICMP_SLT, SRem,
2705+ ConstantInt::getNullValue (Ty));
2706+ return new ICmpInst (ICmpInst::ICMP_SGT, SRem,
2707+ ConstantInt::getAllOnesValue (Ty));
2708+ }
26772709 // Match an 'is positive' or 'is negative' comparison of remainder by a
26782710 // constant power-of-2 value:
26792711 // (X % pow2C) sgt/slt 0
2680- const ICmpInst::Predicate Pred = Cmp.getPredicate ();
26812712 if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT &&
26822713 Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE)
26832714 return nullptr ;
0 commit comments