[PATCH] D122942: [InstCombine] Fold srem(X, PowerOf2) == C into (X & Mask) == C for positive C
Alexander Shaposhnikov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 2 20:57:52 PDT 2022
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6cf10b7e6e83: [InstCombine] Fold srem(X, PowerOf2) == C into (X & Mask) == C for positive C (authored by alexander-shaposhnikov).
Changed prior to commit:
https://reviews.llvm.org/D122942?vs=419877&id=420025#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122942/new/
https://reviews.llvm.org/D122942
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/rem.ll
Index: llvm/test/Transforms/InstCombine/rem.ll
===================================================================
--- llvm/test/Transforms/InstCombine/rem.ll
+++ llvm/test/Transforms/InstCombine/rem.ll
@@ -742,7 +742,7 @@
define i1 @positive_and_odd_eq(i32 %A) {
; CHECK-LABEL: @positive_and_odd_eq(
-; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2
+; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -2147483647
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B]], 1
; CHECK-NEXT: ret i1 [[C]]
;
@@ -764,7 +764,7 @@
define i1 @positive_and_odd_ne(i32 %A) {
; CHECK-LABEL: @positive_and_odd_ne(
-; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2
+; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -2147483647
; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[B]], 1
; CHECK-NEXT: ret i1 [[C]]
;
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2335,7 +2335,8 @@
// constant power-of-2 value:
// (X % pow2C) sgt/slt 0
const ICmpInst::Predicate Pred = Cmp.getPredicate();
- if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT)
+ if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT &&
+ Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE)
return nullptr;
// TODO: The one-use check is standard because we do not typically want to
@@ -2345,7 +2346,15 @@
return nullptr;
const APInt *DivisorC;
- if (!C.isZero() || !match(SRem->getOperand(1), m_Power2(DivisorC)))
+ if (!match(SRem->getOperand(1), m_Power2(DivisorC)))
+ return nullptr;
+
+ // For cmp_sgt/cmp_slt only zero valued C is handled.
+ // For cmp_eq/cmp_ne only positive valued C is handled.
+ if (((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT) &&
+ !C.isZero()) ||
+ ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) &&
+ !C.isStrictlyPositive()))
return nullptr;
// Mask off the sign bit and the modulo bits (low-bits).
@@ -2354,6 +2363,9 @@
Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
Value *And = Builder.CreateAnd(SRem->getOperand(0), MaskC);
+ if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE)
+ return new ICmpInst(Pred, And, ConstantInt::get(Ty, C));
+
// For 'is positive?' check that the sign-bit is clear and at least 1 masked
// bit is set. Example:
// (i8 X % 32) s> 0 --> (X & 159) s> 0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122942.420025.patch
Type: text/x-patch
Size: 2540 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220403/f6dc61a8/attachment.bin>
More information about the llvm-commits
mailing list