From: Richard Sandiford Date: Wed, 14 Aug 2019 09:14:31 +0000 (+0000) Subject: [AArch64] Add support for SVE F{MAX,MIN}NM immediate X-Git-Tag: misc/cutover-git~3423 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75079ddf9cb867576bbef66f3e8370d9fdeea3b8;p=thirdparty%2Fgcc.git [AArch64] Add support for SVE F{MAX,MIN}NM immediate 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 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 (3): Use aarch64_sve_float_maxmin_operand for operand 2. (*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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5f030861b840..b597ad59d4c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2019-08-14 Richard Sandiford + + * 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 (3): + Use aarch64_sve_float_maxmin_operand for operand 2. + (*3): Likewise. + Add alternatives for the constant forms. + 2019-08-14 Richard Sandiford * config/aarch64/constraints.md (vsb): New constraint. diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 68c5700fdb1c..851b459cc483 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -2604,7 +2604,7 @@ [(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" { @@ -2614,18 +2614,20 @@ ;; Predicated floating-point maximum/minimum. (define_insn "*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: 1 "register_operand" "Upl, Upl") + [(match_operand: 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" "@ + \t%0., %1/m, %0., #%3 \t%0., %1/m, %0., %3. + movprfx\t%0, %2\;\t%0., %1/m, %0., #%3 movprfx\t%0, %2\;\t%0., %1/m, %0., %3." - [(set_attr "movprfx" "*,yes")] + [(set_attr "movprfx" "*,*,yes,yes")] ) ;; Merging forms are handled through SVE_COND_FP_BINARY. diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 1b154901d27e..61547e5ee08f 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -436,9 +436,16 @@ 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")) diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index d52eaa57d3b4..1654ffb63f84 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -2075,7 +2075,7 @@ (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")]) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 0f20d8976486..b456cfffeb22 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -655,6 +655,11 @@ (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"))) @@ -708,6 +713,10 @@ (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"))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8fb83602a3aa..0edfe1a20fec 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-14 Richard Sandiford + + * gcc.target/aarch64/sve/fmaxnm_1.c: New test. + * gcc.target/aarch64/sve/fminnm_1.c: Likewise. + 2019-08-14 Richard Sandiford * 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 index 000000000000..2f0d64bd4441 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include + +#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 index 000000000000..547772e29953 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c @@ -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 } } */