[llvm] Simplify `(a % b) lt/ge (b-1)` into `(a % b) eq/ne (b-1)` (PR #72504)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 13 00:54:59 PST 2024
================
@@ -2519,6 +2519,30 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
BinaryOperator *SRem,
const APInt &C) {
+ {
+ const APInt *C1;
+ ICmpInst::Predicate Pred = Cmp.getPredicate();
+ if ((match(SRem->getOperand(1), m_NonNegative(C1)) &&
+ ((Pred == ICmpInst::ICMP_SLT && C == *C1 - 1) ||
+ (Pred == ICmpInst::ICMP_SGT && C == *C1 - 2))) ||
+ (match(SRem->getOperand(1), m_Negative(C1)) &&
+ ((Pred == ICmpInst::ICMP_SGT && C == *C1 + 1) ||
+ (Pred == ICmpInst::ICMP_SLT && C == *C1 + 2)))) {
----------------
nikic wrote:
Sorry to bring this up only now, but playing around with this a bit, I don't think the way negative numbers are handled here makes sense. The thing is that `srem %x, -C` will be canonicalized to `srem %x, C` (the sign of the srem result is determined by the first operand, not the second one!) so we will never actually hit the `m_Negative()` branch.
We should still keep the `m_NonNegative(C1)` due to worklist order considerations, but the `m_Negative(C1)` branch can be dropped.
Instead, we'd want to add more cases to the positive case, such as `(srem %x, C) sgt (-C + 1)`. This would be one of the new cases: https://alive2.llvm.org/ce/z/MeiohD Same for slt and +2.
https://github.com/llvm/llvm-project/pull/72504
More information about the llvm-commits
mailing list