@@ -2674,10 +2674,41 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
2674
2674
Instruction *InstCombinerImpl::foldICmpSRemConstant (ICmpInst &Cmp,
2675
2675
BinaryOperator *SRem,
2676
2676
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 % DivisorC) ugt C -> (X % DivisorC) slt 0
2681
+ // iff abs(DivisorC) ule (C slt 0 ? ~C : C)+1
2682
+ // (X % DivisorC) ult C+1 -> (X % DivisorC) sgt -1
2683
+ // iff abs(DivisorC) ule (C+1 slt 0 ? ~C : C)+1
2684
+
2685
+ const APInt *DivisorC;
2686
+ if (!match (SRem->getOperand (1 ), m_APInt (DivisorC)))
2687
+ return nullptr ;
2688
+
2689
+ APInt NormalizedC = C;
2690
+ assert (!NormalizedC.isZero () &&
2691
+ " srem X, 0 should have been simplified already." );
2692
+ if (Pred == ICmpInst::ICMP_ULT)
2693
+ --NormalizedC;
2694
+ if (C.isNegative ())
2695
+ NormalizedC.flipAllBits ();
2696
+ assert (!NormalizedC.isMaxValue () &&
2697
+ " srem i1 X, -1 should have been simplified already." );
2698
+ ++NormalizedC;
2699
+ if (!DivisorC->abs ().ule (NormalizedC))
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
+ }
2677
2709
// Match an 'is positive' or 'is negative' comparison of remainder by a
2678
2710
// constant power-of-2 value:
2679
2711
// (X % pow2C) sgt/slt 0
2680
- const ICmpInst::Predicate Pred = Cmp.getPredicate ();
2681
2712
if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT &&
2682
2713
Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE)
2683
2714
return nullptr ;
0 commit comments