[PATCH] D143026: [InstCombine] Add transform for `(mul X, OddC) eq/ne N * C` --> `X eq/ne N`
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 6 12:17:07 PST 2023
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2a3732f934b1: Add transform for `(mul X, OddC) eq/ne N * C` --> `X eq/ne N` (authored by goldstein.w.n).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D143026/new/
https://reviews.llvm.org/D143026
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-mul.ll
Index: llvm/test/Transforms/InstCombine/icmp-mul.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-mul.ll
+++ llvm/test/Transforms/InstCombine/icmp-mul.ll
@@ -424,8 +424,7 @@
define i1 @eq_rem_zero_nonuw(i8 %x) {
; CHECK-LABEL: @eq_rem_zero_nonuw(
-; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5
-; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[A]], 20
+; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X:%.*]], 4
; CHECK-NEXT: ret i1 [[B]]
;
%a = mul i8 %x, 5
@@ -435,8 +434,7 @@
define i1 @ne_rem_zero_nonuw(i8 %x) {
; CHECK-LABEL: @ne_rem_zero_nonuw(
-; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[A]], 30
+; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[X:%.*]], 6
; CHECK-NEXT: ret i1 [[B]]
;
%a = mul i8 %x, 5
@@ -995,8 +993,7 @@
define <2 x i1> @mul_oddC_ne_vec(<2 x i8> %v) {
; CHECK-LABEL: @mul_oddC_ne_vec(
-; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i8> [[V:%.*]], <i8 3, i8 3>
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[MUL]], <i8 12, i8 12>
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[V:%.*]], <i8 4, i8 4>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%mul = mul <2 x i8> %v, <i8 3, i8 3>
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2035,24 +2035,35 @@
return new ICmpInst(Pred, X, ConstantInt::getNullValue(MulTy));
}
- if (MulC->isZero() || (!Mul->hasNoSignedWrap() && !Mul->hasNoUnsignedWrap()))
+ if (MulC->isZero())
return nullptr;
- // If the multiply does not wrap, try to divide the compare constant by the
- // multiplication factor.
+ // If the multiply does not wrap or the constant is odd, try to divide the
+ // compare constant by the multiplication factor.
if (Cmp.isEquality()) {
- // (mul nsw X, MulC) == C --> X == C /s MulC
+ // (mul nsw X, MulC) eq/ne C --> X eq/ne C /s MulC
if (Mul->hasNoSignedWrap() && C.srem(*MulC).isZero()) {
Constant *NewC = ConstantInt::get(MulTy, C.sdiv(*MulC));
return new ICmpInst(Pred, X, NewC);
}
- // (mul nuw X, MulC) == C --> X == C /u MulC
- if (Mul->hasNoUnsignedWrap() && C.urem(*MulC).isZero()) {
- Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));
- return new ICmpInst(Pred, X, NewC);
+
+ // C % MulC == 0 is weaker than we could use if MulC is odd because it
+ // correct to transform if MulC * N == C including overflow. I.e with i8
+ // (icmp eq (mul X, 5), 101) -> (icmp eq X, 225) but since 101 % 5 != 0, we
+ // miss that case.
+ if (C.urem(*MulC).isZero()) {
+ // (mul nuw X, MulC) eq/ne C --> X eq/ne C /u MulC
+ // (mul X, OddC) eq/ne N * C --> X eq/ne N
+ if ((*MulC & 1).isOne() || Mul->hasNoUnsignedWrap()) {
+ Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));
+ return new ICmpInst(Pred, X, NewC);
+ }
}
}
+ if (!Mul->hasNoSignedWrap() && !Mul->hasNoUnsignedWrap())
+ return nullptr;
+
// With a matching no-overflow guarantee, fold the constants:
// (X * MulC) < C --> X < (C / MulC)
// (X * MulC) > C --> X > (C / MulC)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143026.495245.patch
Type: text/x-patch
Size: 3308 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230206/68cb1346/attachment.bin>
More information about the llvm-commits
mailing list