@@ -2528,6 +2528,30 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
2528
2528
Instruction *InstCombinerImpl::foldICmpSRemConstant (ICmpInst &Cmp,
2529
2529
BinaryOperator *SRem,
2530
2530
const APInt &C) {
2531
+ {
2532
+ const APInt *C1;
2533
+ ICmpInst::Predicate Pred = Cmp.getPredicate ();
2534
+ if ((match (SRem->getOperand (1 ), m_NonNegative (C1))) &&
2535
+ ((Pred == ICmpInst::ICMP_SLT && C == *C1 - 1 ) ||
2536
+ (Pred == ICmpInst::ICMP_SGT && C == *C1 - 2 ) ||
2537
+ (Pred == ICmpInst::ICMP_SGT && C == -*C1 + 1 ) ||
2538
+ (Pred == ICmpInst::ICMP_SLT && C == -*C1 + 2 ))) {
2539
+ // icmp slt (X s% C), (C - 1) --> icmp ne (X s% C), (C - 1), if C >= 0
2540
+ // icmp sgt (X s% C), (C - 2) --> icmp eq (X s% C), (C - 1), if C >= 0
2541
+ // icmp sgt (X s% C), (-C + 1) --> icmp ne (X s% C), (-C + 1), if C >= 0
2542
+ // icmp slt (X s% C), (-C + 2) --> icmp eq (X s% C), (-C + 1), if C >= 0
2543
+ return new ICmpInst (
2544
+ ((Pred == ICmpInst::ICMP_SLT && C == *C1 - 1 ) ||
2545
+ (Pred == ICmpInst::ICMP_SGT && C == -*C1 + 1 ))
2546
+ ? ICmpInst::ICMP_NE
2547
+ : ICmpInst::ICMP_EQ,
2548
+ SRem,
2549
+ ConstantInt::get (SRem->getType (), C == -*C1 + 1 || C == -*C1 + 2
2550
+ ? -*C1 + 1
2551
+ : *C1 - 1 ));
2552
+ }
2553
+ }
2554
+
2531
2555
// Match an 'is positive' or 'is negative' comparison of remainder by a
2532
2556
// constant power-of-2 value:
2533
2557
// (X % pow2C) sgt/slt 0
@@ -2575,6 +2599,23 @@ Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
2575
2599
return new ICmpInst (ICmpInst::ICMP_UGT, And, ConstantInt::get (Ty, SignMask));
2576
2600
}
2577
2601
2602
+ Instruction *InstCombinerImpl::foldICmpURemConstant (ICmpInst &Cmp,
2603
+ BinaryOperator *URem,
2604
+ const APInt &C) {
2605
+ const APInt *C1;
2606
+ ICmpInst::Predicate Pred = Cmp.getPredicate ();
2607
+ if (match (URem->getOperand (1 ), m_APInt (C1)) &&
2608
+ ((Pred == ICmpInst::ICMP_ULT && C == *C1 - 1 ) ||
2609
+ (Pred == ICmpInst::ICMP_UGT && C == *C1 - 2 && C.ugt (1 )))) {
2610
+ // icmp ult (X u% C), (C - 1) --> icmp ne (X u% C), (C - 1)
2611
+ // icmp ugt (X u% C), (C - 2) --> icmp eq (X u% C), (C - 1), if C >u 1
2612
+ return new ICmpInst (Pred == ICmpInst::ICMP_UGT ? ICmpInst::ICMP_EQ
2613
+ : ICmpInst::ICMP_NE,
2614
+ URem, ConstantInt::get (URem->getType (), *C1 - 1 ));
2615
+ }
2616
+ return nullptr ;
2617
+ }
2618
+
2578
2619
// / Fold icmp (udiv X, Y), C.
2579
2620
Instruction *InstCombinerImpl::foldICmpUDivConstant (ICmpInst &Cmp,
2580
2621
BinaryOperator *UDiv,
@@ -3712,6 +3753,10 @@ Instruction *InstCombinerImpl::foldICmpBinOpWithConstant(ICmpInst &Cmp,
3712
3753
if (Instruction *I = foldICmpSRemConstant (Cmp, BO, C))
3713
3754
return I;
3714
3755
break ;
3756
+ case Instruction::URem:
3757
+ if (Instruction *I = foldICmpURemConstant (Cmp, BO, C))
3758
+ return I;
3759
+ break ;
3715
3760
case Instruction::UDiv:
3716
3761
if (Instruction *I = foldICmpUDivConstant (Cmp, BO, C))
3717
3762
return I;
0 commit comments