[llvm] aef44e4 - [InstSimplify] Add simplification for `({u,s}rem (mul {nuw,nsw} X, C1), C0)`
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 07:22:59 PDT 2024
Author: Noah Goldstein
Date: 2024-07-01T22:22:36+08:00
New Revision: aef44e49a7b79cfaf4d7c09133ba7c30ddfdfdc7
URL: https://github.com/llvm/llvm-project/commit/aef44e49a7b79cfaf4d7c09133ba7c30ddfdfdc7
DIFF: https://github.com/llvm/llvm-project/commit/aef44e49a7b79cfaf4d7c09133ba7c30ddfdfdc7.diff
LOG: [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
Closes #97037
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/rem.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cdcc40c596b77..1b72f151e3692 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1226,13 +1226,29 @@ static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
return V;
// (X << Y) % X -> 0
- if (Q.IIQ.UseInstrInfo &&
- ((Opcode == Instruction::SRem &&
- match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
- (Opcode == Instruction::URem &&
- match(Op0, m_NUWShl(m_Specific(Op1), m_Value())))))
- return Constant::getNullValue(Op0->getType());
+ if (Q.IIQ.UseInstrInfo) {
+ if ((Opcode == Instruction::SRem &&
+ match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
+ (Opcode == Instruction::URem &&
+ 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 ad9cb21a12cc9..aceb7cb12185d 100644
--- a/llvm/test/Transforms/InstSimplify/rem.ll
+++ b/llvm/test/Transforms/InstSimplify/rem.ll
@@ -491,9 +491,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>
@@ -513,9 +511,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