Skip to content

Commit aef44e4

Browse files
committed
[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
1 parent 5880526 commit aef44e4

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,13 +1226,29 @@ static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
12261226
return V;
12271227

12281228
// (X << Y) % X -> 0
1229-
if (Q.IIQ.UseInstrInfo &&
1230-
((Opcode == Instruction::SRem &&
1231-
match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
1232-
(Opcode == Instruction::URem &&
1233-
match(Op0, m_NUWShl(m_Specific(Op1), m_Value())))))
1234-
return Constant::getNullValue(Op0->getType());
1229+
if (Q.IIQ.UseInstrInfo) {
1230+
if ((Opcode == Instruction::SRem &&
1231+
match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
1232+
(Opcode == Instruction::URem &&
1233+
match(Op0, m_NUWShl(m_Specific(Op1), m_Value()))))
1234+
return Constant::getNullValue(Op0->getType());
12351235

1236+
const APInt *C0;
1237+
if (match(Op1, m_APInt(C0))) {
1238+
// (srem (mul nsw X, C1), C0) -> 0 if C1 s% C0 == 0
1239+
// (urem (mul nuw X, C1), C0) -> 0 if C1 u% C0 == 0
1240+
if (Opcode == Instruction::SRem
1241+
? match(Op0,
1242+
m_NSWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
1243+
return C.srem(*C0).isZero();
1244+
})))
1245+
: match(Op0,
1246+
m_NUWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
1247+
return C.urem(*C0).isZero();
1248+
}))))
1249+
return Constant::getNullValue(Op0->getType());
1250+
}
1251+
}
12361252
return nullptr;
12371253
}
12381254

llvm/test/Transforms/InstSimplify/rem.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,7 @@ define i8 @urem_mul_sdiv(i8 %x, i8 %y) {
491491

492492
define <2 x i8> @simplfy_srem_of_mul(<2 x i8> %x) {
493493
; CHECK-LABEL: @simplfy_srem_of_mul(
494-
; CHECK-NEXT: [[MUL:%.*]] = mul nsw <2 x i8> [[X:%.*]], <i8 20, i8 10>
495-
; CHECK-NEXT: [[R:%.*]] = srem <2 x i8> [[MUL]], <i8 5, i8 5>
496-
; CHECK-NEXT: ret <2 x i8> [[R]]
494+
; CHECK-NEXT: ret <2 x i8> zeroinitializer
497495
;
498496
%mul = mul nsw <2 x i8> %x, <i8 20, i8 10>
499497
%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) {
513511

514512
define i8 @simplfy_urem_of_mul(i8 %x) {
515513
; CHECK-LABEL: @simplfy_urem_of_mul(
516-
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[X:%.*]], 30
517-
; CHECK-NEXT: [[R:%.*]] = urem i8 [[MUL]], 10
518-
; CHECK-NEXT: ret i8 [[R]]
514+
; CHECK-NEXT: ret i8 0
519515
;
520516
%mul = mul nuw i8 %x, 30
521517
%r = urem i8 %mul, 10

0 commit comments

Comments
 (0)