diff mbox series

[i386] : Fix PR 62055, recognize fnabs (FP negative absolute value)

Message ID CAFULd4ZGpvgJ++hYan0i43_jAhRVGAbfL+nQKNEL+kDhLBSsgA@mail.gmail.com
State New
Headers show
Series [i386] : Fix PR 62055, recognize fnabs (FP negative absolute value) | expand

Commit Message

Uros Bizjak June 17, 2019, 6:42 p.m. UTC
2019-06-17  Uroš Bizjak  <ubizjak@gmail.com>

    PR target/62055
    * config/i386/i386.md (*nabstf2_1): New insn pattern.
    (*nabs<mode>2_1): Ditto.
    (nabs sse-reg splitter): New splitter.
    * config/i386/sse.md (*nabs<mode>2): New insn_and_split pattern.

testsuite/ChangeLog:

2019-06-17  Uroš Bizjak  <ubizjak@gmail.com>

    PR target/62055
    * gcc.target/i386/fnabs.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
diff mbox series

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 272386)
+++ config/i386/i386.md	(working copy)
@@ -9452,6 +9452,16 @@ 
   "#"
   [(set_attr "isa" "noavx,noavx,avx,avx")])
 
+(define_insn "*nabstf2_1"
+  [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
+	(neg:TF
+	  (abs:TF
+	    (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
+   (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
+  "TARGET_SSE"
+  "#"
+  [(set_attr "isa" "noavx,noavx,avx,avx")])
+
 (define_expand "<code><mode>2"
   [(set (match_operand:X87MODEF 0 "register_operand")
 	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
@@ -9553,6 +9563,48 @@ 
   [(const_int 0)]
   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
 
+(define_insn "*nabs<mode>2_1"
+  [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
+	(neg:MODEF
+	  (abs:MODEF
+	    (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
+   (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
+  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
+  "#"
+  [(set_attr "isa" "noavx,noavx,avx")])
+
+(define_split
+  [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
+	(neg:SSEMODEF
+	  (abs:SSEMODEF
+	    (match_operand:SSEMODEF 1 "vector_operand"))))
+   (use (match_operand:<ssevecmodef> 2 "vector_operand"))]
+  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+    || (TARGET_SSE && (<MODE>mode == TFmode)))
+   && reload_completed"
+  [(set (match_dup 0) (match_dup 3))]
+{
+  machine_mode mode = <MODE>mode;
+  machine_mode vmode = <ssevecmodef>mode;
+
+  operands[0] = lowpart_subreg (vmode, operands[0], mode);
+  operands[1] = lowpart_subreg (vmode, operands[1], mode);
+
+  if (TARGET_AVX)
+    {
+      if (MEM_P (operands[1]))
+        std::swap (operands[1], operands[2]);
+    }
+  else
+   {
+     if (operands_match_p (operands[0], operands[2]))
+       std::swap (operands[1], operands[2]);
+   }
+
+  operands[3]
+    = gen_rtx_fmt_ee (IOR, vmode, operands[1], operands[2]);
+})
+
 ;; Conditionalize these after reload. If they match before reload, we
 ;; lose the clobber and ability to use integer instructions.
 
Index: config/i386/sse.md
===================================================================
--- config/i386/sse.md	(revision 272386)
+++ config/i386/sse.md	(working copy)
@@ -1748,6 +1748,33 @@ 
 }
   [(set_attr "isa" "noavx,noavx,avx,avx")])
 
+(define_insn_and_split "*nabs<mode>2"
+  [(set (match_operand:VF 0 "register_operand" "=x,x,v,v")
+	(neg:VF
+	  (abs:VF
+	    (match_operand:VF 1 "vector_operand" "0,xBm,v,m"))))
+   (use (match_operand:VF 2 "vector_operand"    "xBm,0,vm,v"))]
+  "TARGET_SSE"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 3))]
+{
+  if (TARGET_AVX)
+    {
+      if (MEM_P (operands[1]))
+        std::swap (operands[1], operands[2]);
+    }
+  else
+   {
+     if (operands_match_p (operands[0], operands[2]))
+       std::swap (operands[1], operands[2]);
+   }
+
+  operands[3]
+    = gen_rtx_fmt_ee (IOR, <MODE>mode, operands[1], operands[2]);
+}
+  [(set_attr "isa" "noavx,noavx,avx,avx")])
+
 (define_expand "<plusminus_insn><mode>3<mask_name><round_name>"
   [(set (match_operand:VF 0 "register_operand")
 	(plusminus:VF
Index: testsuite/gcc.target/i386/fnabs.c
===================================================================
--- testsuite/gcc.target/i386/fnabs.c	(nonexistent)
+++ testsuite/gcc.target/i386/fnabs.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* PR target/62055 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
+
+float testf (float a)
+{
+  return -__builtin_fabsf (a);
+}
+
+double test (double a)
+{
+   return -__builtin_fabs (a);
+}
+
+__float128 testq (__float128 a)
+{
+   return -__builtin_fabsq (a);
+}
+
+/* { dg-final { scan-assembler-times "\tv?orp\[sd\]\[ \t\]" 2 } } */
+/* { dg-final { scan-assembler-times "\tv?por\[ \t\]" 1 } } */