aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-08-14 09:14:31 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-08-14 09:14:31 +0000
commit75079ddf9cb867576bbef66f3e8370d9fdeea3b8 (patch)
tree9fd5984d3d9057fefa484370ff0d627d1f18bca5
parentf8c22a8bbaf3ef4260f7d8beea22ed151ca4b726 (diff)
downloadgcc-75079ddf9cb867576bbef66f3e8370d9fdeea3b8.zip
gcc-75079ddf9cb867576bbef66f3e8370d9fdeea3b8.tar.gz
gcc-75079ddf9cb867576bbef66f3e8370d9fdeea3b8.tar.bz2
[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 <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
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/aarch64/aarch64-sve.md14
-rw-r--r--gcc/config/aarch64/constraints.md9
-rw-r--r--gcc/config/aarch64/iterators.md4
-rw-r--r--gcc/config/aarch64/predicates.md9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c45
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c21
8 files changed, 112 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5f03086..b597ad5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,19 @@
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.
(vsm): Generalize description.
* config/aarch64/iterators.md (SVE_INT_BINARY_IMM): New code
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 68c5700..851b459 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 "*<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.
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 1b15490..61547e5 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 d52eaa5..1654ffb 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 0f20d89..b456cff 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 8fb8360..0edfe1a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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.
* gcc.target/aarch64/sve/smin_1.c: Likewise.
* gcc.target/aarch64/sve/umax_1.c: Likewise.
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 0000000..2f0d64b
--- /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 <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
index 0000000..547772e
--- /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 } } */