[llvm] [InstCombine] Fold abs(a * abs(b)) --> abs(a * b) (PR #78110)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 14 11:00:25 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: None (elhewaty)
<details>
<summary>Changes</summary>
- [InstCombine] Add test coverage for abs(b * abs(a)) --> abs(a * b) (NFC)
- [InstCombine] Fold abs(b * abs(a)) --> abs(a * b)
- alive2: https://alive2.llvm.org/ce/z/cXQqGd
- Fixes: https://github.com/llvm/llvm-project/issues/73211
---
Full diff: https://github.com/llvm/llvm-project/pull/78110.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+8)
- (modified) llvm/test/Transforms/InstCombine/abs-intrinsic.ll (+49)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 64fbd5543a9e203..978a7c1e256cef6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1601,6 +1601,14 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return CastInst::Create(Instruction::ZExt, NarrowAbs, II->getType());
}
+ // abs(a * abs(b)) --> abs(a * b)
+ Value *A, *B;
+ if (match(IIOperand,
+ m_c_Mul(m_Value(A), m_Intrinsic<Intrinsic::abs>(m_Value(B))))) {
+ Value *New = Builder.CreateMul(A, B);
+ return replaceOperand(*II, 0, New);
+ }
+
// Match a complicated way to check if a number is odd/even:
// abs (srem X, 2) --> and X, 1
const APInt *C;
diff --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
index 7fe34d923764857..8f31cb58dc8f14b 100644
--- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
@@ -5,8 +5,57 @@ declare i8 @llvm.abs.i8(i8, i1)
declare i32 @llvm.abs.i32(i32, i1)
declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
declare <3 x i82> @llvm.abs.v3i82(<3 x i82>, i1)
+declare <2 x i8> @llvm.abs.v2i8(<2 x i8>, i1)
declare void @llvm.assume(i1)
+define i8 @test_abs_abs_a_mul_b_i8(i8 %a, i8 %b) {
+; CHECK-LABEL: @test_abs_abs_a_mul_b_i8(
+; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)
+; CHECK-NEXT: ret i8 [[ABS2]]
+;
+ %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 true)
+ %mul = mul i8 %abs1, %b
+ %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)
+ ret i8 %abs2
+}
+
+define i8 @test_abs_a_mul_abs_b_i8(i8 %a, i8 %b) {
+; CHECK-LABEL: @test_abs_a_mul_abs_b_i8(
+; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)
+; CHECK-NEXT: ret i8 [[ABS2]]
+;
+ %abs1 = call i8 @llvm.abs.i8(i8 %b, i1 true)
+ %mul = mul i8 %abs1, %a
+ %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)
+ ret i8 %abs2
+}
+
+define i32 @test_abs_abs_a_mul_b_i16(i32 %a, i32 %b) {
+; CHECK-LABEL: @test_abs_abs_a_mul_b_i16(
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)
+; CHECK-NEXT: ret i32 [[ABS2]]
+;
+ %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)
+ %mul = mul i32 %abs1, %b
+ %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 true)
+ ret i32 %abs2
+}
+
+define <2 x i8> @test_abs_abs_a_mul_b_vector_i8(<2 x i8> %a, <2 x i8> %b) {
+; CHECK-LABEL: @test_abs_abs_a_mul_b_vector_i8(
+; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[ABS2:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[TMP1]], i1 true)
+; CHECK-NEXT: ret <2 x i8> [[ABS2]]
+;
+ %abs = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %a, i1 true)
+ %mul = mul <2 x i8> %abs, %b
+ %abs2 = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %mul, i1 true)
+ ret <2 x i8> %abs2
+}
+
; abs preserves trailing zeros so the second and is unneeded
define i32 @abs_trailing_zeros(i32 %x) {
; CHECK-LABEL: @abs_trailing_zeros(
``````````
</details>
https://github.com/llvm/llvm-project/pull/78110
More information about the llvm-commits
mailing list