[llvm] goldsteinn/rem of mul simpl (PR #97037)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 28 03:51:47 PDT 2024
https://github.com/goldsteinn created https://github.com/llvm/llvm-project/pull/97037
- **[InstSimplify] Add test for simplifying `({u,s}rem (mul {nuw,nsw} X, C1), C0)`; NFC**
- **[InstSimplify] Add simplification for `({u,s}rem (mul {nuw,nsw} X, C1), C0)`**
>From d869e1af2ef419561b8e7dee16d86703d87b8360 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Fri, 28 Jun 2024 18:39:49 +0800
Subject: [PATCH 1/2] [InstSimplify] Add test for simplifying `({u,s}rem (mul
{nuw,nsw} X, C1), C0)`; NFC
---
llvm/test/Transforms/InstSimplify/rem.ll | 61 +++++++++++++++++++++++-
1 file changed, 59 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll
index a46db0342042f..be1764d91f339 100644
--- a/llvm/test/Transforms/InstSimplify/rem.ll
+++ b/llvm/test/Transforms/InstSimplify/rem.ll
@@ -265,12 +265,14 @@ define i32 @rem4() {
; CHECK-NEXT: [[CALL:%.*]] = call i32 @external(), !range [[RNG0:![0-9]+]]
; CHECK-NEXT: ret i32 [[CALL]]
;
- %call = call i32 @external(), !range !0
+ %call = call i32 @external() , !range !0
%urem = urem i32 %call, 3
ret i32 %urem
}
-!0 = !{i32 0, i32 3}
+!0 = ! {
+i32 0, i32 3
+}
define i32 @rem5(i32 %x, i32 %y) {
; CHECK-LABEL: @rem5(
@@ -488,3 +490,58 @@ define i8 @urem_mul_sdiv(i8 %x, i8 %y) {
%mod = urem i8 %mul, %y
ret i8 %mod
}
+
+define <2 x i8> @simplfy_srem_of_mul(<2 x i8> %x) {
+; CHECK-LABEL: @simplfy_srem_of_mul(
+; CHECK-NEXT: [[MUL:%.*]] = mul nsw <2 x i8> [[X:%.*]], <i8 20, i8 10>
+; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> [[MUL]], <i8 5, i8 5>
+; CHECK-NEXT: ret <2 x i8> [[R]]
+;
+ %mul = mul nsw <2 x i8> %x, <i8 20, i8 10>
+ %r = srem <2 x i8> %mul, <i8 5, i8 5>
+ ret <2 x i8> %r
+}
+
+define <2 x i8> @simplfy_srem_of_mul_fail_bad_mod(<2 x i8> %x) {
+; CHECK-LABEL: @simplfy_srem_of_mul_fail_bad_mod(
+; CHECK-NEXT: [[MUL:%.*]] = mul nsw <2 x i8> [[X:%.*]], <i8 20, i8 11>
+; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> [[MUL]], <i8 5, i8 5>
+; CHECK-NEXT: ret <2 x i8> [[R]]
+;
+ %mul = mul nsw <2 x i8> %x, <i8 20, i8 11>
+ %r = srem <2 x i8> %mul, <i8 5, i8 5>
+ ret <2 x i8> %r
+}
+
+define i8 @simplfy_urem_of_mul(i8 %x) {
+; CHECK-LABEL: @simplfy_urem_of_mul(
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[X:%.*]], 30
+; CHECK-NEXT: [[R:%.*]] = urem i8 [[MUL]], 10
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %mul = mul nuw i8 %x, 30
+ %r = urem i8 %mul, 10
+ ret i8 %r
+}
+
+define i8 @simplfy_urem_of_mul_fail_bad_flag(i8 %x) {
+; CHECK-LABEL: @simplfy_urem_of_mul_fail_bad_flag(
+; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 30
+; CHECK-NEXT: [[R:%.*]] = urem i8 [[MUL]], 10
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %mul = mul nsw i8 %x, 30
+ %r = urem i8 %mul, 10
+ ret i8 %r
+}
+
+define i8 @simplfy_urem_of_mul_fail_bad_mod(i8 %x) {
+; CHECK-LABEL: @simplfy_urem_of_mul_fail_bad_mod(
+; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 31
+; CHECK-NEXT: [[R:%.*]] = urem i8 [[MUL]], 10
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %mul = mul nsw i8 %x, 31
+ %r = urem i8 %mul, 10
+ ret i8 %r
+}
>From 6dc33fcda72ed58d9b4bbed91e42dad72934c200 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Fri, 28 Jun 2024 18:40:08 +0800
Subject: [PATCH 2/2] [InstSimplify] Add simplification for `({u,s}rem (mul
{nuw,nsw} X, C1), C0)`
We can simplify these to `0` if `C1 % C0 == 0`
Proofs: https://alive2.llvm.org/ce/z/EejAdk
---
llvm/lib/Analysis/InstructionSimplify.cpp | 13 +++++++++++++
llvm/test/Transforms/InstSimplify/rem.ll | 8 ++------
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cdcc40c596b77..446f97ebbc1ea 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1233,6 +1233,19 @@ static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
match(Op0, m_NUWShl(m_Specific(Op1), m_Value())))))
return Constant::getNullValue(Op0->getType());
+ const APInt * C0;
+ if (match(Op1, m_APInt(C0))) {
+ // (srem (mul nsw X, C1), C0) -> 0 if C1 s% C0 == 0
+ // (urem (mul nuw X, C1), C0) -> 0 if C1 u% C0 == 0
+ if (Opcode == Instruction::SRem
+ ? match(Op0, m_NSWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
+ return C.srem(*C0).isZero();
+ })))
+ : match(Op0, m_NUWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
+ return C.urem(*C0).isZero();
+ }))))
+ return Constant::getNullValue(Op0->getType());
+ }
return nullptr;
}
diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll
index be1764d91f339..cee0e0e346fc3 100644
--- a/llvm/test/Transforms/InstSimplify/rem.ll
+++ b/llvm/test/Transforms/InstSimplify/rem.ll
@@ -493,9 +493,7 @@ define i8 @urem_mul_sdiv(i8 %x, i8 %y) {
define <2 x i8> @simplfy_srem_of_mul(<2 x i8> %x) {
; CHECK-LABEL: @simplfy_srem_of_mul(
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw <2 x i8> [[X:%.*]], <i8 20, i8 10>
-; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> [[MUL]], <i8 5, i8 5>
-; CHECK-NEXT: ret <2 x i8> [[R]]
+; CHECK-NEXT: ret <2 x i8> zeroinitializer
;
%mul = mul nsw <2 x i8> %x, <i8 20, i8 10>
%r = srem <2 x i8> %mul, <i8 5, i8 5>
@@ -515,9 +513,7 @@ define <2 x i8> @simplfy_srem_of_mul_fail_bad_mod(<2 x i8> %x) {
define i8 @simplfy_urem_of_mul(i8 %x) {
; CHECK-LABEL: @simplfy_urem_of_mul(
-; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[X:%.*]], 30
-; CHECK-NEXT: [[R:%.*]] = urem i8 [[MUL]], 10
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%mul = mul nuw i8 %x, 30
%r = urem i8 %mul, 10
More information about the llvm-commits
mailing list