[llvm] Perf/canonicalize copysign magc (PR #85787)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 06:49:21 PDT 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/85787
None
>From d7683a8668f9d5949bf873d3af79d36a5efd7da8 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 19 Mar 2024 21:36:45 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
.../InstCombine/copysign-fneg-fabs.ll | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
index af939cf74399ab..f00d3db7f21576 100644
--- a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
+++ b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
@@ -275,6 +275,52 @@ define half @fneg_fabs_copysign_multi_use_fabs(half %x, half %y, ptr %ptr) {
ret half %fabs.copysign
}
+define half @copysign_pos(half %a) {
+; CHECK-LABEL: @copysign_pos(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH3C00, half [[A:%.*]])
+; CHECK-NEXT: ret half [[RET]]
+;
+entry:
+ %ret = call half @llvm.copysign.f16(half 0xH3C00, half %a)
+ ret half %ret
+}
+
+define half @copysign_neg(half %a) {
+; CHECK-LABEL: @copysign_neg(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xHBC00, half [[A:%.*]])
+; CHECK-NEXT: ret half [[RET]]
+;
+entry:
+ %ret = call half @llvm.copysign.f16(half 0xHBC00, half %a)
+ ret half %ret
+}
+
+define <4 x half> @copysign_splat(<4 x half> %a) {
+; CHECK-LABEL: @copysign_splat(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xHBC00, half 0xHBC00, half 0xHBC00, half 0xHBC00>, <4 x half> [[A:%.*]])
+; CHECK-NEXT: ret <4 x half> [[RET]]
+;
+entry:
+ %ret = call <4 x half> @llvm.copysign.v4f16(<4 x half> splat(half 0xHBC00), <4 x half> %a)
+ ret <4 x half> %ret
+}
+
+; TODO: Support constant folding of fabs
+
+define <4 x half> @copysign_vec4(<4 x half> %a) {
+; CHECK-LABEL: @copysign_vec4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xHBC00, half undef, half poison>, <4 x half> [[A:%.*]])
+; CHECK-NEXT: ret <4 x half> [[RET]]
+;
+entry:
+ %ret = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xHBC00, half undef, half poison>, <4 x half> %a)
+ ret <4 x half> %ret
+}
+
declare half @llvm.fabs.f16(half)
declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
declare half @llvm.copysign.f16(half, half)
>From 859dd5b270e84a8ffcc331ac0f3542b5920c71c6 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 19 Mar 2024 21:38:20 +0800
Subject: [PATCH 2/2] [InstCombine] Clear sign-bit of the constant magnitude in
copysign
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 10 ++++++++++
llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll | 4 ++--
llvm/test/Transforms/InstCombine/fcmp.ll | 10 +++++-----
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 8537dbc6fe531b..3eafcb03644ecd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2473,6 +2473,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X))))
return replaceOperand(*II, 1, X);
+ // Clear sign-bit of constant magnitude:
+ // copysign -MagC, X --> copysign MagC, X
+ // TODO: Support constant folding for fabs
+ const APFloat *MagC;
+ if (match(Mag, m_APFloat(MagC)) && MagC->isNegative()) {
+ APFloat PosMagC = *MagC;
+ PosMagC.clearSign();
+ return replaceOperand(*II, 0, ConstantFP::get(Mag->getType(), PosMagC));
+ }
+
// Peek through changes of magnitude's sign-bit. This call rewrites those:
// copysign (fabs X), Sign --> copysign X, Sign
// copysign (fneg X), Sign --> copysign X, Sign
diff --git a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
index f00d3db7f21576..84cb252a150d7a 100644
--- a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
+++ b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
@@ -289,7 +289,7 @@ entry:
define half @copysign_neg(half %a) {
; CHECK-LABEL: @copysign_neg(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xHBC00, half [[A:%.*]])
+; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH3C00, half [[A:%.*]])
; CHECK-NEXT: ret half [[RET]]
;
entry:
@@ -300,7 +300,7 @@ entry:
define <4 x half> @copysign_splat(<4 x half> %a) {
; CHECK-LABEL: @copysign_splat(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xHBC00, half 0xHBC00, half 0xHBC00, half 0xHBC00>, <4 x half> [[A:%.*]])
+; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00, half 0xH3C00>, <4 x half> [[A:%.*]])
; CHECK-NEXT: ret <4 x half> [[RET]]
;
entry:
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 159c84d0dd8aa9..f2701d16d0f3d1 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -644,7 +644,7 @@ define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) {
define i1 @is_signbit_clear(double %x) {
; CHECK-LABEL: @is_signbit_clear(
-; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
+; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
@@ -655,7 +655,7 @@ define i1 @is_signbit_clear(double %x) {
define i1 @is_signbit_clear_1(double %x) {
; CHECK-LABEL: @is_signbit_clear_1(
-; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
+; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
; CHECK-NEXT: [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
@@ -666,7 +666,7 @@ define i1 @is_signbit_clear_1(double %x) {
define i1 @is_signbit_clear_2(double %x) {
; CHECK-LABEL: @is_signbit_clear_2(
-; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
+; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
@@ -677,7 +677,7 @@ define i1 @is_signbit_clear_2(double %x) {
define i1 @is_signbit_clear_3(double %x) {
; CHECK-LABEL: @is_signbit_clear_3(
-; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
+; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
@@ -705,7 +705,7 @@ define i1 @is_signbit_set_extra_use(double %x, ptr %p) {
define i1 @is_signbit_clear_nonzero(double %x) {
; CHECK-LABEL: @is_signbit_clear_nonzero(
-; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
+; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
More information about the llvm-commits
mailing list