[llvm] [InstCombine]combine mul(abs(x), abs(y)) to abs(mul(x, y)) (PR #78395)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 16 21:25:57 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Congcong Cai (HerrCai0907)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/78395.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (+17)
- (modified) llvm/test/Transforms/InstCombine/mul.ll (+13)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index e7f983a00e3044..36930f24a542a2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -330,6 +330,23 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
return BinaryOperator::CreateMul(X, X);
}
+ {
+ Value *X, *Y, *Z;
+ // abs(X) * abs(Y) -> abs(X * Y)
+ // nabs(X) * nabs(Y) -> abs(X * Y)
+ SelectPatternFlavor SPF0 = matchSelectPattern(Op0, X, Z).Flavor;
+ SelectPatternFlavor SPF1 = matchSelectPattern(Op1, Y, Z).Flavor;
+ if ((SPF0 == SPF1) && (SPF0 == SPF_ABS || SPF0 == SPF_NABS))
+ return replaceInstUsesWith(
+ I, Builder.CreateBinaryIntrinsic(
+ Intrinsic::abs, Builder.CreateMul(X, Y), Builder.getTrue()));
+ if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))) &&
+ match(Op1, m_Intrinsic<Intrinsic::abs>(m_Value(Y))))
+ return replaceInstUsesWith(
+ I, Builder.CreateBinaryIntrinsic(
+ Intrinsic::abs, Builder.CreateMul(X, Y), Builder.getTrue()));
+ }
+
// -X * C --> X * -C
Value *X, *Y;
Constant *Op1C;
diff --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index b404fcffbf4226..0494091b038243 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -1649,6 +1649,19 @@ define <vscale x 2 x i64> @mul_scalable_splat_zero(<vscale x 2 x i64> %z) {
ret <vscale x 2 x i64> %t3
}
+; fold mul(abs(x),abs(y)) -> abs(mul(x,y))
+define i32 @combine_mul_abs_x_abs_y(i32 %x, i32 %y) {
+; CHECK-LABEL: @combine_mul_abs_x_abs_y(
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[MUL:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)
+; CHECK-NEXT: ret i32 [[MUL]]
+;
+ %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 false)
+ %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 false)
+ %mul = mul i32 %abs_x, %abs_y
+ ret i32 %mul
+}
+
;
; fold mul(sub(x,y),negpow2) -> shl(sub(y,x),log2(pow2))
;
``````````
</details>
https://github.com/llvm/llvm-project/pull/78395
More information about the llvm-commits
mailing list