[llvm] ce5b88b - [InstCombine] Handle constant arms in `select` of `srem` fold
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 16 03:23:03 PDT 2023
Author: Antonio Frighetto
Date: 2023-09-16T12:22:46+02:00
New Revision: ce5b88bf10ac5841ca0691ef3f2d87e62748dcd7
URL: https://github.com/llvm/llvm-project/commit/ce5b88bf10ac5841ca0691ef3f2d87e62748dcd7
DIFF: https://github.com/llvm/llvm-project/commit/ce5b88bf10ac5841ca0691ef3f2d87e62748dcd7.diff
LOG: [InstCombine] Handle constant arms in `select` of `srem` fold
Extend folding for `2^n` euclidean division remainder operations
on signed integers by handling the specific instance in which one
`select` arm has already been replaced by 1.
Reported-By: HypheX
Fixes: https://github.com/llvm/llvm-project/issues/66417.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select-divrem.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e2965e7a5703976..a62bfd2e89c4aea 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2616,20 +2616,33 @@ static Instruction *foldSelectWithSRem(SelectInst &SI, InstCombinerImpl &IC,
if (!TrueIfSigned)
std::swap(TrueVal, FalseVal);
- // We are matching a quite specific pattern here:
+ auto FoldToBitwiseAnd = [&](Value *Remainder) -> Instruction * {
+ Value *Add = Builder.CreateAdd(
+ Remainder, Constant::getAllOnesValue(RemRes->getType()));
+ return BinaryOperator::CreateAnd(Op, Add);
+ };
+
+ // Match the general case:
// %rem = srem i32 %x, %n
// %cnd = icmp slt i32 %rem, 0
// %add = add i32 %rem, %n
// %sel = select i1 %cnd, i32 %add, i32 %rem
- if (!(match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
- match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) &&
- IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) &&
- FalseVal == RemRes))
- return nullptr;
+ if (match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
+ match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) &&
+ IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) &&
+ FalseVal == RemRes)
+ return FoldToBitwiseAnd(Remainder);
+
+ // Match the case where the one arm has been replaced by constant 1:
+ // %rem = srem i32 %n, 2
+ // %cnd = icmp slt i32 %rem, 0
+ // %sel = select i1 %cnd, i32 1, i32 %rem
+ if (match(TrueVal, m_One()) &&
+ match(RemRes, m_SRem(m_Value(Op), m_SpecificInt(2))) &&
+ FalseVal == RemRes)
+ return FoldToBitwiseAnd(ConstantInt::get(RemRes->getType(), 2));
- Value *Add = Builder.CreateAdd(Remainder,
- Constant::getAllOnesValue(RemRes->getType()));
- return BinaryOperator::CreateAnd(Op, Add);
+ return nullptr;
}
static Value *foldSelectWithFrozenICmp(SelectInst &Sel, InstCombiner::BuilderTy &Builder) {
diff --git a/llvm/test/Transforms/InstCombine/select-divrem.ll b/llvm/test/Transforms/InstCombine/select-divrem.ll
index a5b56609d606206..f007c53359ca5a1 100644
--- a/llvm/test/Transforms/InstCombine/select-divrem.ll
+++ b/llvm/test/Transforms/InstCombine/select-divrem.ll
@@ -321,3 +321,25 @@ define i8 @rem_euclid_non_const_pow2(i8 %0, i8 %1) {
%sel = select i1 %cond, i8 %add, i8 %rem
ret i8 %sel
}
+
+define i32 @rem_euclid_pow2_true_arm_folded(i32 %n) {
+; CHECK-LABEL: @rem_euclid_pow2_true_arm_folded(
+; CHECK-NEXT: [[RES:%.*]] = and i32 [[N:%.*]], 1
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %rem = srem i32 %n, 2
+ %neg = icmp slt i32 %rem, 0
+ %res = select i1 %neg, i32 1, i32 %rem
+ ret i32 %res
+}
+
+define i32 @rem_euclid_pow2_false_arm_folded(i32 %n) {
+; CHECK-LABEL: @rem_euclid_pow2_false_arm_folded(
+; CHECK-NEXT: [[RES:%.*]] = and i32 [[N:%.*]], 1
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %rem = srem i32 %n, 2
+ %nonneg = icmp sge i32 %rem, 0
+ %res = select i1 %nonneg, i32 %rem, i32 1
+ ret i32 %res
+}
More information about the llvm-commits
mailing list