[llvm] [InstCombine] Fold `(mul (div exact X, C0), C1)` -> `(div exact X, C0/C1)` (PR #96915)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 27 20:30:36 PDT 2024
================
@@ -365,6 +365,28 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
return BinaryOperator::CreateMul(NegOp0, X);
}
+ if (Op0->hasOneUse()) {
+ // (mul (div exact X, C0), C1)
+ // -> (div exact C0 / C1)
+ // iff C0 % C1 == 0 and C0 / C1 doesn't create UB.
+ const APInt *C1;
+ auto UDivCheck = [&C1](const APInt &C) { return C.urem(*C1).isZero(); };
+ auto SDivCheck = [&C1](const APInt &C) {
+ APInt Quot, Rem;
+ APInt::sdivrem(C, *C1, Quot, Rem);
+ return Rem.isZero() && !Quot.isMinSignedValue();
+ };
+ if (match(Op1, m_APInt(C1)) &&
+ (match(Op0, m_Exact(m_UDiv(m_Value(X), m_CheckedInt(UDivCheck)))) ||
+ match(Op0, m_Exact(m_SDiv(m_Value(X), m_CheckedInt(SDivCheck)))))) {
+ auto BOpc = cast<BinaryOperator>(Op0)->getOpcode();
+ return BinaryOperator::CreateExact(
+ BOpc, X,
+ Builder.CreateBinOp(BOpc, cast<BinaryOperator>(Op0)->getOperand(1),
----------------
dtcxzyw wrote:
```suggestion
Builder.CreateBinOp(BOpc, RHSC,
```
Can we use `m_CheckedInt(const Constant *&V, ... CheckFn)` ?
https://github.com/llvm/llvm-project/pull/96915
More information about the llvm-commits
mailing list