Skip to content

Commit 01f4d40

Browse files
authored
Simplify (a % b) lt/ge (b-1) into (a % b) eq/ne (b-1) (llvm#72504)
Alive2: https://alive2.llvm.org/ce/z/i7zYtE Fixes: llvm#71280
1 parent 8f2d83d commit 01f4d40

File tree

3 files changed

+396
-0
lines changed

3 files changed

+396
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,6 +2528,30 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
25282528
Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
25292529
BinaryOperator *SRem,
25302530
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+
25312555
// Match an 'is positive' or 'is negative' comparison of remainder by a
25322556
// constant power-of-2 value:
25332557
// (X % pow2C) sgt/slt 0
@@ -2575,6 +2599,23 @@ Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
25752599
return new ICmpInst(ICmpInst::ICMP_UGT, And, ConstantInt::get(Ty, SignMask));
25762600
}
25772601

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+
25782619
/// Fold icmp (udiv X, Y), C.
25792620
Instruction *InstCombinerImpl::foldICmpUDivConstant(ICmpInst &Cmp,
25802621
BinaryOperator *UDiv,
@@ -3712,6 +3753,10 @@ Instruction *InstCombinerImpl::foldICmpBinOpWithConstant(ICmpInst &Cmp,
37123753
if (Instruction *I = foldICmpSRemConstant(Cmp, BO, C))
37133754
return I;
37143755
break;
3756+
case Instruction::URem:
3757+
if (Instruction *I = foldICmpURemConstant(Cmp, BO, C))
3758+
return I;
3759+
break;
37153760
case Instruction::UDiv:
37163761
if (Instruction *I = foldICmpUDivConstant(Cmp, BO, C))
37173762
return I;

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
676676
const APInt &C);
677677
Instruction *foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv,
678678
const APInt &C);
679+
Instruction *foldICmpURemConstant(ICmpInst &Cmp, BinaryOperator *UDiv,
680+
const APInt &C);
679681
Instruction *foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv,
680682
const APInt &C);
681683
Instruction *foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div,

0 commit comments

Comments
 (0)