From 0a18c19f75973520e87a08191554ec3cb8f850a6 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 23 Dec 2015 10:28:18 +0000 Subject: [PATCH] iterators.md (VMAXMINFNM): New int iterator. 2015-12-23 David Sherwood 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 | 10 ++++ gcc/config/arm/iterators.md | 9 ++++ gcc/config/arm/neon.md | 11 +++++ gcc/config/arm/unspecs.md | 2 + gcc/config/arm/vfp.md | 12 +++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.target/arm/fmaxmin.c | 13 +++++ gcc/testsuite/gcc.target/arm/fmaxmin.x | 54 +++++++++++++++++++++ gcc/testsuite/gcc.target/arm/vect-fmaxmin.c | 14 ++++++ 9 files changed, 131 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/fmaxmin.c create mode 100644 gcc/testsuite/gcc.target/arm/fmaxmin.x create mode 100644 gcc/testsuite/gcc.target/arm/vect-fmaxmin.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05c6460466d..aa28d106374 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-12-23 David Sherwood + + * 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 PR target/66232 diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index c7a688044e9..6ff346cd187 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -308,6 +308,8 @@ (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]) @@ -745,6 +747,13 @@ (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") diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 844ef5eb2f3..d8cc686b3c4 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -2366,6 +2366,17 @@ [(set_attr "type" "neon_fp_minmax_s")] ) +;; Vector forms for the IEEE-754 fmax()/fmin() functions +(define_insn "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" + ".\t%0, %1, %2" + [(set_attr "type" "neon_fp_minmax_s")] +) + (define_expand "neon_vpadd" [(match_operand:VD 0 "s_register_operand" "=w") (match_operand:VD 1 "s_register_operand" "w") diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index ffe703c3ee8..9c633c0e887 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -226,8 +226,10 @@ 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 diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index baeac622d29..3c89fe9ba7e 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -1366,6 +1366,18 @@ (set_attr "conds" "unconditional")] ) +;; Scalar forms for the IEEE-754 fmax()/fmin() functions +(define_insn "3" + [(set (match_operand:SDF 0 "s_register_operand" "=") + (unspec:SDF [(match_operand:SDF 1 "s_register_operand" "") + (match_operand:SDF 2 "s_register_operand" "")] + VMAXMINFNM))] + "TARGET_HARD_FLOAT && TARGET_VFP5 " + ".\\t%0, %1, %2" + [(set_attr "type" "f_minmax") + (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)] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 524b9b02e14..0620068bee1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-12-23 David Sherwood + + * 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 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 index 00000000000..945c473ced2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fmaxmin.c @@ -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 index 00000000000..ccf832d9567 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fmaxmin.x @@ -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 index 00000000000..fd01cd95f53 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vect-fmaxmin.c @@ -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 } } */ + -- 2.30.2