re PR target/62055 (missed optimization: recognize fnabs (FP negative absolute value...
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 17 Jun 2019 18:40:22 +0000 (20:40 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 17 Jun 2019 18:40:22 +0000 (20:40 +0200)
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:

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

From-SVN: r272396

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/config/i386/sse.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/fnabs.c [new file with mode: 0644]

index c114a5d..6001d26 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2019-06-17  Jan Hubicka  <hubicka@ucw.cz>
 
        PR bootstrap/90873.
index 8406aed..2b7df20 100644 (file)
   "#"
   [(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")))]
   [(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 d7d5425..5d8ada4 100644 (file)
 }
   [(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 688c6f3..d2ea2f7 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-17  Uroš Bizjak  <ubizjak@gmail.com>
+
+       PR target/62055
+       * gcc.target/i386/fnabs.c: New test.
+
 2019-06-17  Marek Polacek  <polacek@redhat.com>
 
        PR c++/83820 - excessive attribute arguments not detected.
@@ -22,7 +27,7 @@
 
 2019-06-16  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
-       * lib/target-supports.exp: Add check_effective_target_longlong64. 
+       * lib/target-supports.exp: Add check_effective_target_longlong64.
 
 2019-06-16  Jan Hubicka  <hubicka@ucw.cz>
 
diff --git a/gcc/testsuite/gcc.target/i386/fnabs.c b/gcc/testsuite/gcc.target/i386/fnabs.c
new file mode 100644 (file)
index 0000000..817c9a7
--- /dev/null
@@ -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 } } */