[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