[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
This commit is contained in:
Richard Sandiford 2019-08-14 09:14:31 +00:00 committed by Richard Sandiford
parent f8c22a8bba
commit 75079ddf9c
8 changed files with 112 additions and 9 deletions

View 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.

View File

@ -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.

View File

@ -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"))

View File

@ -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")])

View File

@ -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")))

View 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.

View File

@ -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 } } */

View File

@ -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 } } */