[AArch64] Add support for SVE F{MAX,MIN}NM immediate
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 14 Aug 2019 09:14:31 +0000 (09:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 14 Aug 2019 09:14:31 +0000 (09:14 +0000)
This patch uses the immediate forms of FMAXNM and FMINNM for
unconditional arithmetic.

The same rules apply to FMAX and FMIN, but we only generate those
via the ACLE.

2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* config/aarch64/predicates.md (aarch64_sve_float_maxmin_immediate)
(aarch64_sve_float_maxmin_operand): New predicates.
* config/aarch64/constraints.md (vsB): New constraint.
(vsM): Fix typo.
* config/aarch64/iterators.md (sve_pred_fp_rhs2_operand): Use
aarch64_sve_float_maxmin_operand for UNSPEC_COND_FMAXNM and
UNSPEC_COND_FMINNM.
* config/aarch64/aarch64-sve.md (<maxmin_uns><SVE_F:mode>3):
Use aarch64_sve_float_maxmin_operand for operand 2.
(*<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3): Likewise.
Add alternatives for the constant forms.

gcc/testsuite/
* gcc.target/aarch64/sve/fmaxnm_1.c: New test.
* gcc.target/aarch64/sve/fminnm_1.c: Likewise.

From-SVN: r274440

gcc/ChangeLog
gcc/config/aarch64/aarch64-sve.md
gcc/config/aarch64/constraints.md
gcc/config/aarch64/iterators.md
gcc/config/aarch64/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c [new file with mode: 0644]

index 5f030861b840fa03727078416757c078c081449d..b597ad59d4c071827f971c54299a4b47caa38e1a 100644 (file)
@@ -1,3 +1,17 @@
+2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/aarch64/predicates.md (aarch64_sve_float_maxmin_immediate)
+       (aarch64_sve_float_maxmin_operand): New predicates.
+       * config/aarch64/constraints.md (vsB): New constraint.
+       (vsM): Fix typo.
+       * config/aarch64/iterators.md (sve_pred_fp_rhs2_operand): Use
+       aarch64_sve_float_maxmin_operand for UNSPEC_COND_FMAXNM and
+       UNSPEC_COND_FMINNM.
+       * config/aarch64/aarch64-sve.md (<maxmin_uns><SVE_F:mode>3):
+       Use aarch64_sve_float_maxmin_operand for operand 2.
+       (*<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3): Likewise.
+       Add alternatives for the constant forms.
+
 2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/aarch64/constraints.md (vsb): New constraint.
index 68c5700fdb1c5ae390b1fa9cb29e71f292a89676..851b459cc483904541e50117f64dc9e78c2d48c1 100644 (file)
          [(match_dup 3)
           (const_int SVE_RELAXED_GP)
           (match_operand:SVE_F 1 "register_operand")
-          (match_operand:SVE_F 2 "register_operand")]
+          (match_operand:SVE_F 2 "aarch64_sve_float_maxmin_operand")]
          SVE_COND_FP_MAXMIN_PUBLIC))]
   "TARGET_SVE"
   {
 
 ;; Predicated floating-point maximum/minimum.
 (define_insn "*<optab><mode>3"
-  [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+  [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w, ?&w")
        (unspec:SVE_F
-         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
           (match_operand:SI 4 "aarch64_sve_gp_strictness")
-          (match_operand:SVE_F 2 "register_operand" "%0, w")
-          (match_operand:SVE_F 3 "register_operand" "w, w")]
+          (match_operand:SVE_F 2 "register_operand" "%0, 0, w, w")
+          (match_operand:SVE_F 3 "aarch64_sve_float_maxmin_operand" "vsB, w, vsB, w")]
          SVE_COND_FP_MAXMIN_PUBLIC))]
   "TARGET_SVE"
   "@
+   <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
    <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
    movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
-  [(set_attr "movprfx" "*,yes")]
+  [(set_attr "movprfx" "*,*,yes,yes")]
 )
 
 ;; Merging forms are handled through SVE_COND_FP_BINARY.
index 1b154901d27e18976f6f7d7e81d8c205b9fdc054..61547e5ee08f0c196b10ce6bb8448209edf45145 100644 (file)
    and FSUB operations."
  (match_operand 0 "aarch64_sve_float_arith_immediate"))
 
+;; "B" for "bound".
+(define_constraint "vsB"
+  "@internal
+   A constraint that matches an immediate operand valid for SVE FMAX
+   and FMIN operations."
+ (match_operand 0 "aarch64_sve_float_maxmin_immediate"))
+
 (define_constraint "vsM"
   "@internal
-   A constraint that matches an imediate operand valid for SVE FMUL
+   A constraint that matches an immediate operand valid for SVE FMUL
    operations."
  (match_operand 0 "aarch64_sve_float_mul_immediate"))
 
index d52eaa57d3b419e91f0df388d71a83063e756d1c..1654ffb63f84e9934fa1b514f435670fe0d71206 100644 (file)
 (define_int_attr sve_pred_fp_rhs2_operand
   [(UNSPEC_COND_FADD "aarch64_sve_float_arith_with_sub_operand")
    (UNSPEC_COND_FDIV "register_operand")
-   (UNSPEC_COND_FMAXNM "register_operand")
-   (UNSPEC_COND_FMINNM "register_operand")
+   (UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_operand")
+   (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_operand")
    (UNSPEC_COND_FMUL "aarch64_sve_float_mul_operand")
    (UNSPEC_COND_FSUB "register_operand")])
index 0f20d89764868daa7735cbd9c5b0723311580ccb..b456cfffeb22801ce81bf951df76a56281ee0040 100644 (file)
   (and (match_code "const,const_vector")
        (match_test "aarch64_sve_float_mul_immediate_p (op)")))
 
+(define_predicate "aarch64_sve_float_maxmin_immediate"
+  (and (match_code "const_vector")
+       (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
+           (match_test "op == CONST1_RTX (GET_MODE (op))"))))
+
 (define_predicate "aarch64_sve_arith_operand"
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_sve_arith_immediate")))
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_sve_float_mul_immediate")))
 
+(define_predicate "aarch64_sve_float_maxmin_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_float_maxmin_immediate")))
+
 (define_predicate "aarch64_sve_vec_perm_operand"
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_constant_vector_operand")))
index 8fb83602a3aac8c83eed57d463e55f707cc92a20..0edfe1a20fecdeecc869d41f3b73873966352d8f 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * gcc.target/aarch64/sve/fmaxnm_1.c: New test.
+       * gcc.target/aarch64/sve/fminnm_1.c: Likewise.
+
 2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>
 
        * gcc.target/aarch64/sve/smax_1.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c
new file mode 100644 (file)
index 0000000..2f0d64b
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST)                        \
+  void __attribute__ ((noipa))                         \
+  test_##TYPE##_##NAME (TYPE *__restrict x,            \
+                       TYPE *__restrict y, int n)      \
+  {                                                    \
+    for (int i = 0; i < n; ++i)                                \
+      x[i] = FN (y[i], CONST);                         \
+  }
+
+#define TEST_TYPE(T, FN, TYPE) \
+  T (FN, TYPE, zero, 0) \
+  T (FN, TYPE, one, 1) \
+  T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, FN (f16), _Float16) \
+  TEST_TYPE (T, FN (f32), float) \
+  TEST_TYPE (T, FN (f64), double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c
new file mode 100644 (file)
index 0000000..547772e
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */