[llvm] e2f56de - InstCombine: Fold fabs (copysign x, y) -> fabs x
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 6 05:29:27 PST 2022
Author: Matt Arsenault
Date: 2022-12-06T08:29:14-05:00
New Revision: e2f56debb3def1dc61552660ee5dd612ff269e47
URL: https://github.com/llvm/llvm-project/commit/e2f56debb3def1dc61552660ee5dd612ff269e47
DIFF: https://github.com/llvm/llvm-project/commit/e2f56debb3def1dc61552660ee5dd612ff269e47.diff
LOG: InstCombine: Fold fabs (copysign x, y) -> fabs x
Added:
Modified:
llvm/include/llvm/IR/PatternMatch.h
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 6d80c37cc34f0..efb50a6b58c21 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -2206,6 +2206,12 @@ inline typename m_Intrinsic_Ty<Opnd0>::Ty m_Sqrt(const Opnd0 &Op0) {
return m_Intrinsic<Intrinsic::sqrt>(Op0);
}
+template <typename Opnd0, typename Opnd1>
+inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_CopySign(const Opnd0 &Op0,
+ const Opnd1 &Op1) {
+ return m_Intrinsic<Intrinsic::copysign>(Op0, Op1);
+}
+
template <typename Opnd0>
inline typename m_Intrinsic_Ty<Opnd0>::Ty m_VecReverse(const Opnd0 &Op0) {
return m_Intrinsic<Intrinsic::experimental_vector_reverse>(Op0);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 1c3fd8666af45..bdcf087efe4c4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2008,6 +2008,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return replaceOperand(*II, 0, TVal);
}
+ Value *Magnitude, *Sign;
+ if (match(II->getArgOperand(0),
+ m_CopySign(m_Value(Magnitude), m_Value(Sign)))) {
+ // fabs (copysign x, y) -> (fabs x)
+ CallInst *AbsSign =
+ Builder.CreateCall(II->getCalledFunction(), {Magnitude});
+ AbsSign->copyFastMathFlags(II);
+ return replaceInstUsesWith(*II, AbsSign);
+ }
+
[[fallthrough]];
}
case Intrinsic::ceil:
diff --git a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
index 31846c5f45cfb..b8512e628ee16 100644
--- a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
+++ b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll
@@ -79,9 +79,8 @@ define half @fneg_copysign(half %x, half %y) {
define half @fneg_fabs_copysign(half %x, half %y) {
; CHECK-LABEL: @fneg_fabs_copysign(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg half [[TMP1]]
; CHECK-NEXT: ret half [[FNEG_FABS_COPYSIGN]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
@@ -93,9 +92,8 @@ define half @fneg_fabs_copysign(half %x, half %y) {
; https://alive2.llvm.org/ce/z/Ft-7ea
define half @fabs_copysign(half %x, half %y) {
; CHECK-LABEL: @fabs_copysign(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
%fabs.copysign = call half @llvm.fabs.f16(half %copysign)
@@ -115,9 +113,8 @@ define <2 x half> @fneg_copysign_vector(<2 x half> %x, <2 x half> %y) {
define <2 x half> @fneg_fabs_copysign_vector(<2 x half> %x, <2 x half> %y) {
; CHECK-LABEL: @fneg_fabs_copysign_vector(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call <2 x half> @llvm.copysign.v2f16(<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[COPYSIGN]])
-; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg <2 x half> [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
+; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg <2 x half> [[TMP1]]
; CHECK-NEXT: ret <2 x half> [[FNEG_FABS_COPYSIGN]]
;
%copysign = call <2 x half> @llvm.copysign.v2f16(<2 x half> %x, <2 x half> %y)
@@ -128,9 +125,8 @@ define <2 x half> @fneg_fabs_copysign_vector(<2 x half> %x, <2 x half> %y) {
define <2 x half> @fabs_copysign_vector(<2 x half> %x, <2 x half> %y) {
; CHECK-LABEL: @fabs_copysign_vector(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call <2 x half> @llvm.copysign.v2f16(<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[COPYSIGN]])
-; CHECK-NEXT: ret <2 x half> [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
+; CHECK-NEXT: ret <2 x half> [[TMP1]]
;
%copysign = call <2 x half> @llvm.copysign.v2f16(<2 x half> %x, <2 x half> %y)
%fabs.copysign = call <2 x half> @llvm.fabs.v2f16(<2 x half> %copysign)
@@ -150,9 +146,8 @@ define half @fneg_copysign_flags(half %x, half %y) {
define half @fneg_fabs_copysign_flags(half %x, half %y) {
; CHECK-LABEL: @fneg_fabs_copysign_flags(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nnan ninf nsz half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call nnan ninf afn half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg reassoc ninf half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf afn half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg reassoc ninf half [[TMP1]]
; CHECK-NEXT: ret half [[FNEG_FABS_COPYSIGN]]
;
%copysign = call nnan nsz ninf half @llvm.copysign.f16(half %x, half %y)
@@ -175,9 +170,8 @@ define half @fneg_nsz_copysign(half %x, half %y) {
define half @fneg_fabs_copysign_flags_none_fabs(half %x, half %y) {
; CHECK-LABEL: @fneg_fabs_copysign_flags_none_fabs(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nnan ninf nsz half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg fast half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg fast half [[TMP1]]
; CHECK-NEXT: ret half [[FNEG_FABS_COPYSIGN]]
;
%copysign = call nnan nsz ninf half @llvm.copysign.f16(half %x, half %y)
@@ -188,9 +182,8 @@ define half @fneg_fabs_copysign_flags_none_fabs(half %x, half %y) {
define half @fabs_copysign_flags(half %x, half %y) {
; CHECK-LABEL: @fabs_copysign_flags(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nnan half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call nnan nsz half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call nnan half @llvm.copysign.f16(half %x, half %y)
%fabs.copysign = call nsz nnan half @llvm.fabs.f16(half %copysign)
@@ -199,9 +192,8 @@ define half @fabs_copysign_flags(half %x, half %y) {
define half @fabs_copysign_all_flags(half %x, half %y) {
; CHECK-LABEL: @fabs_copysign_all_flags(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call fast half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call fast half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call fast half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call fast half @llvm.copysign.f16(half %x, half %y)
%fabs.copysign = call fast half @llvm.fabs.f16(half %copysign)
@@ -212,8 +204,8 @@ define half @fabs_copysign_no_flags_copysign_user(half %x, half %y, ptr %ptr) {
; CHECK-LABEL: @fabs_copysign_no_flags_copysign_user(
; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
; CHECK-NEXT: store half [[COPYSIGN]], ptr [[PTR:%.*]], align 2
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call fast half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call fast half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
store half %copysign, ptr %ptr
@@ -223,9 +215,8 @@ define half @fabs_copysign_no_flags_copysign_user(half %x, half %y, ptr %ptr) {
define half @fneg_fabs_copysign_drop_flags(half %x, half %y) {
; CHECK-LABEL: @fneg_fabs_copysign_drop_flags(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nnan half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call ninf half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg nsz half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call ninf half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[FNEG_FABS_COPYSIGN:%.*]] = fneg nsz half [[TMP1]]
; CHECK-NEXT: ret half [[FNEG_FABS_COPYSIGN]]
;
%copysign = call nnan half @llvm.copysign.f16(half %x, half %y)
@@ -251,8 +242,8 @@ define half @fabs_copysign_multi_use(half %x, half %y, ptr %ptr) {
; CHECK-LABEL: @fabs_copysign_multi_use(
; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
; CHECK-NEXT: store half [[COPYSIGN]], ptr [[PTR:%.*]], align 2
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
store half %copysign, ptr %ptr
@@ -264,8 +255,8 @@ define half @fabs_flags_copysign_multi_use(half %x, half %y, ptr %ptr) {
; CHECK-LABEL: @fabs_flags_copysign_multi_use(
; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
; CHECK-NEXT: store half [[COPYSIGN]], ptr [[PTR:%.*]], align 2
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call nnan ninf half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
store half %copysign, ptr %ptr
@@ -275,10 +266,9 @@ define half @fabs_flags_copysign_multi_use(half %x, half %y, ptr %ptr) {
define half @fneg_fabs_copysign_multi_use_fabs(half %x, half %y, ptr %ptr) {
; CHECK-LABEL: @fneg_fabs_copysign_multi_use_fabs(
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT: [[FABS_COPYSIGN:%.*]] = call half @llvm.fabs.f16(half [[COPYSIGN]])
-; CHECK-NEXT: store half [[FABS_COPYSIGN]], ptr [[PTR:%.*]], align 2
-; CHECK-NEXT: ret half [[FABS_COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: store half [[TMP1]], ptr [[PTR:%.*]], align 2
+; CHECK-NEXT: ret half [[TMP1]]
;
%copysign = call half @llvm.copysign.f16(half %x, half %y)
%fabs.copysign = call half @llvm.fabs.f16(half %copysign)
More information about the llvm-commits
mailing list