[PATCH] D156811: [InstCombine] Fold `select` of `srem` and conditional add
Antonio Frighetto via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 10:14:32 PDT 2023
antoniofrighetto created this revision.
antoniofrighetto added reviewers: nikic, goldstein.w.n, arsenm.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
antoniofrighetto requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.
Simplify a pattern that may show up when computing the remainder of euclidean division.
Fixes: #64305 <https://github.com/llvm/llvm-project/issues/64305>
Proofs: https://alive2.llvm.org/ce/z/WBssHE
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D156811
Files:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select-divrem.ll
Index: llvm/test/Transforms/InstCombine/select-divrem.ll
===================================================================
--- llvm/test/Transforms/InstCombine/select-divrem.ll
+++ llvm/test/Transforms/InstCombine/select-divrem.ll
@@ -213,3 +213,27 @@
%sel = select i1 %b, i5 %r2, i5 %r1
ret i5 %sel
}
+
+define i32 @rem_euclid_1(i32 %0) {
+; CHECK-LABEL: @rem_euclid_1(
+; CHECK-NEXT: [[SEL:%.*]] = and i32 [[TMP0:%.*]], 7
+; CHECK-NEXT: ret i32 [[SEL]]
+;
+ %rem = srem i32 %0, 8
+ %cond = icmp slt i32 %rem, 0
+ %add = add nsw i32 %rem, 8
+ %sel = select i1 %cond, i32 %add, i32 %rem
+ ret i32 %sel
+}
+
+define i32 @rem_euclid_2(i32 %0) {
+; CHECK-LABEL: @rem_euclid_2(
+; CHECK-NEXT: [[SEL:%.*]] = and i32 [[TMP0:%.*]], 7
+; CHECK-NEXT: ret i32 [[SEL]]
+;
+ %rem = srem i32 %0, 8
+ %cond = icmp sgt i32 %rem, -1
+ %add = add nsw i32 %rem, 8
+ %sel = select i1 %cond, i32 %rem, i32 %add
+ ret i32 %sel
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2584,6 +2584,41 @@
return nullptr;
}
+/// Tries to reduce a pattern that arises when calculating the remainder of the
+/// Euclidean division. When the divisor is a power of two and is guaranteed not
+/// to be negative, a signed remainder can be folded with a bitwise and.
+///
+/// (x % n) < 0 ? (x % n) + n : (x % n)
+/// -> x & (n - 1)
+static Instruction *foldSelectWithSRem(SelectInst &SI) {
+ Value *CondVal = SI.getCondition();
+ Value *TrueVal = SI.getTrueValue();
+ Value *FalseVal = SI.getFalseValue();
+
+ ICmpInst::Predicate Pred;
+ Value *Op, *Rem, *CmpCond;
+
+ // We are matching a quite specific pattern here:
+ // %rem = srem i32 %x, %n
+ // %cnd = icmp slt i32 %rem, 0
+ // %add = add nsw i32 %rem, %n
+ // %sel = select i1 %cnd, i32 %add, i32 %rem
+ const APInt *I0, *I1;
+ if (!(match(TrueVal, m_Add(m_Value(Rem), m_Power2(I0))) &&
+ match(Rem, m_SRem(m_Value(Op), m_Power2(I1))) && FalseVal == Rem &&
+ I0 == I1))
+ return nullptr;
+
+ // Signed comparisons have been canonicalized into a ICMP_SLT at this point,
+ // we can safely check this type of comparison.
+ if (!(match(CondVal, m_ICmp(Pred, m_Value(CmpCond), m_Zero())) &&
+ Pred == ICmpInst::ICMP_SLT && CmpCond == Rem))
+ return nullptr;
+
+ Value *Mask = ConstantInt::get(Rem->getType(), I0->getZExtValue() - 1);
+ return BinaryOperator::CreateAnd(Op, Mask);
+}
+
static Value *foldSelectWithFrozenICmp(SelectInst &Sel, InstCombiner::BuilderTy &Builder) {
FreezeInst *FI = dyn_cast<FreezeInst>(Sel.getCondition());
if (!FI)
@@ -3616,6 +3651,9 @@
if (Instruction *I = foldVectorSelect(SI))
return I;
+ if (Instruction *I = foldSelectWithSRem(SI))
+ return I;
+
// If we can compute the condition, there's no need for a select.
// Like the above fold, we are attempting to reduce compile-time cost by
// putting this fold here with limitations rather than in InstSimplify.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156811.546116.patch
Type: text/x-patch
Size: 3126 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230801/3f5ed183/attachment.bin>
More information about the llvm-commits
mailing list