[llvm] [InstCombine] simplify `(X * C0) / (X * C1)` into `C0 / C1`. (PR #73204)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 28 22:35:40 PST 2023
================
@@ -1207,6 +1207,45 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
}
}
+ // (X * Y) / (X * Z) --> Y / X (and commuted variants)
+ if (match(Op0, m_Mul(m_Value(X), m_Value(Y)))) {
+ auto OB0HasNSW = cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap();
+ auto OB0HasNUW = cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap();
+
+ auto CreateDivOrNull = [&](Value *A, Value *B) -> Instruction * {
+ auto OB1HasNSW = cast<OverflowingBinaryOperator>(Op1)->hasNoSignedWrap();
+ auto OB1HasNUW =
+ cast<OverflowingBinaryOperator>(Op1)->hasNoUnsignedWrap();
+ const APInt *C;
+ if (IsSigned && OB0HasNSW && OB1HasNSW && (match(A, m_APInt(C))) &&
+ (*C != -1 ||
+ *C != APInt::getSignedMinValue(Ty->getScalarSizeInBits())))
----------------
dtcxzyw wrote:
Sorry for my mistake here.
You need to check `A != sign mask || B != -1`.
Since `mul nsw X, -1` will be canonicalized into `sub nsw 0, X`, I think the defense checking `B != -1` is enough as @goldsteinn suggested.
Please also add the following test:
```
define i4 @sdiv_mul_nsw_mul_nsw_allones(i4 %a, i4 %c2) {
%add4 = mul nsw i4 %a, -1
%add5 = mul nsw i4 %a, -8
%div = sdiv i4 %add5, %add4
ret i4 %div
}
```
https://github.com/llvm/llvm-project/pull/73204
More information about the llvm-commits
mailing list