iterators.md (VMAXMINFNM): New int iterator.
authorDavid Sherwood <david.sherwood@arm.com>
Wed, 23 Dec 2015 10:28:18 +0000 (10:28 +0000)
committerDavid Sherwood <davids@gcc.gnu.org>
Wed, 23 Dec 2015 10:28:18 +0000 (10:28 +0000)
2015-12-23  David Sherwood  <david.sherwood@arm.com>

    gcc/
        * config/arm/iterators.md (VMAXMINFNM): New int iterator.
        (fmaxmin): New int attribute.
        (fmaxmin_op): Likewise.
        * config/arm/unspecs.md (UNSPEC_VMAXNM): New unspec.
        (UNSPEC_VMINNM): Likewise.
        * config/arm/neon.md (fmaxmin): New pattern.
        * config/arm/vfp.md (fmaxmin): Likewise.
    gcc/testsuite
        * gcc.target/arm/fmaxmin.x: New file used by tests below.
        * gcc.target/arm/fmaxmin.c: New test.
        * gcc.target/arm/vect-fmaxmin.c: Likewise.

From-SVN: r231924

gcc/ChangeLog
gcc/config/arm/iterators.md
gcc/config/arm/neon.md
gcc/config/arm/unspecs.md
gcc/config/arm/vfp.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/fmaxmin.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/fmaxmin.x [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vect-fmaxmin.c [new file with mode: 0644]

index 05c6460466d55c27ed75619ec5ad3cbfedc0cb64..aa28d106374fd58ce648b55f3a72eeaefcc5359f 100644 (file)
@@ -1,3 +1,13 @@
+2015-12-23  David Sherwood  <david.sherwood@arm.com>
+
+       * config/arm/iterators.md (VMAXMINFNM): New int iterator.
+       (fmaxmin): New int attribute.
+       (fmaxmin_op): Likewise.
+       * config/arm/unspecs.md (UNSPEC_VMAXNM): New unspec.
+       (UNSPEC_VMINNM): Likewise.
+       * config/arm/neon.md (fmaxmin): New pattern.
+       * config/arm/vfp.md (fmaxmin): Likewise.
+
 2015-12-23  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/66232
index c7a688044e9b7c98c9f49a207141435bf596a43f..6ff346cd18705cd7e578c94a19069a8b74934543 100644 (file)
 
 (define_int_iterator VMAXMINF [UNSPEC_VMAX UNSPEC_VMIN])
 
+(define_int_iterator VMAXMINFNM [UNSPEC_VMAXNM UNSPEC_VMINNM])
+
 (define_int_iterator VPADDL [UNSPEC_VPADDL_S UNSPEC_VPADDL_U])
 
 (define_int_iterator VPADAL [UNSPEC_VPADAL_S UNSPEC_VPADAL_U])
   (UNSPEC_VPMIN "min") (UNSPEC_VPMIN_U "min")
 ])
 
+(define_int_attr fmaxmin [
+  (UNSPEC_VMAXNM "fmax") (UNSPEC_VMINNM "fmin")])
+
+(define_int_attr fmaxmin_op [
+  (UNSPEC_VMAXNM "vmaxnm") (UNSPEC_VMINNM "vminnm")
+])
+
 (define_int_attr shift_op [
   (UNSPEC_VSHL_S "shl") (UNSPEC_VSHL_U "shl")
   (UNSPEC_VRSHL_S "rshl") (UNSPEC_VRSHL_U "rshl")
index 844ef5eb2f3a730b7d01ead1408af02fbf9fc7f9..d8cc686b3c4b34ac0399167380f1d5c3f1a8b2e4 100644 (file)
   [(set_attr "type" "neon_fp_minmax_s<q>")]
 )
 
+;; Vector forms for the IEEE-754 fmax()/fmin() functions
+(define_insn "<fmaxmin><mode>3"
+  [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
+       (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
+                      (match_operand:VCVTF 2 "s_register_operand" "w")]
+                      VMAXMINFNM))]
+  "TARGET_NEON && TARGET_FPU_ARMV8"
+  "<fmaxmin_op>.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+  [(set_attr "type" "neon_fp_minmax_s<q>")]
+)
+
 (define_expand "neon_vpadd<mode>"
   [(match_operand:VD 0 "s_register_operand" "=w")
    (match_operand:VD 1 "s_register_operand" "w")
index ffe703c3ee8ffe67505892a6e983898b5064e1a0..9c633c0e88707b4ba8fd471ac786337cc192af18 100644 (file)
   UNSPEC_VLD4_LANE
   UNSPEC_VMAX
   UNSPEC_VMAX_U
+  UNSPEC_VMAXNM
   UNSPEC_VMIN
   UNSPEC_VMIN_U
+  UNSPEC_VMINNM
   UNSPEC_VMLA
   UNSPEC_VMLA_LANE
   UNSPEC_VMLAL_S
index baeac622d2967a6b96a80f6615403812d76c5658..3c89fe9ba7ec645d62c802a851ec24d660e1177d 100644 (file)
    (set_attr "conds" "unconditional")]
 )
 
+;; Scalar forms for the IEEE-754 fmax()/fmin() functions
+(define_insn "<fmaxmin><mode>3"
+  [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
+       (unspec:SDF [(match_operand:SDF 1 "s_register_operand" "<F_constraint>")
+                    (match_operand:SDF 2 "s_register_operand" "<F_constraint>")]
+                    VMAXMINFNM))]
+  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
+  "<fmaxmin_op>.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+  [(set_attr "type" "f_minmax<vfp_type>")
+   (set_attr "conds" "unconditional")]
+)
+
 ;; Write Floating-point Status and Control Register.
 (define_insn "set_fpscr"
   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR)]
index 524b9b02e14604520c092bd6769fe8110c3361aa..0620068bee1ca2e22822860932e5c38d340f8080 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-23  David Sherwood  <david.sherwood@arm.com>
+
+       * gcc.target/arm/fmaxmin.x: New file used by tests below.
+       * gcc.target/arm/fmaxmin.c: New test.
+       * gcc.target/arm/vect-fmaxmin.c: Likewise.
+
 2015-12-23  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/66232
diff --git a/gcc/testsuite/gcc.target/arm/fmaxmin.c b/gcc/testsuite/gcc.target/arm/fmaxmin.c
new file mode 100644 (file)
index 0000000..945c473
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-O2 -fno-inline -march=armv8-a -save-temps" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "fmaxmin.x"
+
+/* { dg-final { scan-assembler-times "vmaxnm.f32\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vminnm.f32\ts\[0-9\]+, s\[0-9\]+, s\[0-9\]+" 1 } } */
+
+/* { dg-final { scan-assembler-times "vmaxnm.f64\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vminnm.f64\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/fmaxmin.x b/gcc/testsuite/gcc.target/arm/fmaxmin.x
new file mode 100644 (file)
index 0000000..ccf832d
--- /dev/null
@@ -0,0 +1,54 @@
+extern void abort (void);
+double fmax (double, double);
+float fmaxf (float, float);
+double fmin (double, double);
+float fminf (float, float);
+
+#define isnan __builtin_isnan
+#define isinf __builtin_isinf
+
+#define NAN __builtin_nan ("")
+#define INFINITY __builtin_inf ()
+
+#define DEF_MAXMIN(TYPE,FUN)\
+void test_##FUN (TYPE *__restrict__ r, TYPE *__restrict__ a,\
+                TYPE *__restrict__ b)\
+{\
+  int i;\
+  for (i = 0; i < 4; i++)\
+    r[i] = FUN (a[i], b[i]);\
+}\
+
+DEF_MAXMIN (float, fmaxf)
+DEF_MAXMIN (double, fmax)
+
+DEF_MAXMIN (float, fminf)
+DEF_MAXMIN (double, fmin)
+
+int main ()
+{
+  float a_f[4] = { 4, NAN, -3, INFINITY };
+  float b_f[4] = { 1,   7,NAN, 0 };
+  float r_f[4];
+  double a_d[4] = { 4, NAN,  -3,  INFINITY };
+  double b_d[4] = { 1,   7, NAN,  0 };
+  double r_d[4];
+
+  test_fmaxf (r_f, a_f, b_f);
+  if (r_f[0] != 4 || isnan (r_f[1]) || isnan (r_f[2]) || !isinf (r_f[3]))
+    abort ();
+
+  test_fminf (r_f, a_f, b_f);
+  if (r_f[0] != 1 || isnan (r_f[1]) || isnan (r_f[2]) || isinf (r_f[3]))
+    abort ();
+
+  test_fmax (r_d, a_d, b_d);
+  if (r_d[0] != 4 || isnan (r_d[1]) || isnan (r_d[2]) || !isinf (r_d[3]))
+    abort ();
+
+  test_fmin (r_d, a_d, b_d);
+  if (r_d[0] != 1 || isnan (r_d[1]) || isnan (r_d[2]) || isinf (r_d[3]))
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arm/vect-fmaxmin.c b/gcc/testsuite/gcc.target/arm/vect-fmaxmin.c
new file mode 100644 (file)
index 0000000..fd01cd9
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-O2 -ftree-vectorize -fno-inline -march=armv8-a -save-temps" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "fmaxmin.x"
+
+/* { dg-final { scan-assembler-times "vmaxnm.f32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vminnm.f32\tq\[0-9\]+, q\[0-9\]+, q\[0-9\]+" 1 } } */
+
+/* NOTE: There are no double precision vector versions of vmaxnm/vminnm.  */
+/* { dg-final { scan-assembler-times "vmaxnm.f64\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "vminnm.f64\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */
+