Wilco Dijkstra <[email protected]> writes:
> Add support for SVE xor immediate when generating AdvSIMD code and SVE is
> available.
>
> Passes bootstrap & regress, OK for commit?
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64.cc (enum simd_immediate_check): Add
> AARCH64_CHECK_XOR.
> (aarch64_simd_valid_xor_imm): New function.
> (aarch64_output_simd_imm): Add AARCH64_CHECK_XOR support.
> (aarch64_output_simd_xor_imm): New function.
> * config/aarch64/aarch64-protos.h (aarch64_output_simd_xor_imm): New
> prototype.
> (aarch64_simd_valid_xor_imm): New prototype.
> * config/aarch64/aarch64-simd.md (xor<mode>3<vczle><vczbe>):
> Use aarch64_reg_or_xor_imm predicate and add an immediate alternative.
> * config/aarch64/predicates.md (aarch64_reg_or_xor_imm): Add new
> predicate.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/sve/simd_imm.c: New test.
OK, thanks.
Richard
> ---
>
> diff --git a/gcc/config/aarch64/aarch64-protos.h
> b/gcc/config/aarch64/aarch64-protos.h
> index
> 3f2d40603426a590a0a14ba4792fe9b325d1e585..16ab79c02da62c1a8aa03309708dfe401d1ffb7e
> 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -827,6 +827,7 @@ char *aarch64_output_scalar_simd_mov_immediate (rtx,
> scalar_int_mode);
> char *aarch64_output_simd_mov_imm (rtx, unsigned);
> char *aarch64_output_simd_orr_imm (rtx, unsigned);
> char *aarch64_output_simd_and_imm (rtx, unsigned);
> +char *aarch64_output_simd_xor_imm (rtx, unsigned);
>
> char *aarch64_output_sve_mov_immediate (rtx);
> char *aarch64_output_sve_ptrues (rtx);
> @@ -844,6 +845,7 @@ bool aarch64_sve_ptrue_svpattern_p (rtx, struct
> simd_immediate_info *);
> bool aarch64_simd_valid_and_imm (rtx);
> bool aarch64_simd_valid_mov_imm (rtx);
> bool aarch64_simd_valid_orr_imm (rtx);
> +bool aarch64_simd_valid_xor_imm (rtx);
> bool aarch64_valid_sysreg_name_p (const char *);
> const char *aarch64_retrieve_sysreg (const char *, bool, bool);
> rtx aarch64_check_zero_based_sve_index_immediate (rtx);
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index
> 5c1de57ce6c3f2064d8be25f903a6a8d949685ef..18795a08b61da874a9e811822ed82e7eb9350bb4
> 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -1144,12 +1144,16 @@ (define_insn "ior<mode>3<vczle><vczbe>"
> [(set_attr "type" "neon_logic<q>")]
> )
>
> +;; For EOR (vector, register) and SVE EOR (vector, immediate)
> (define_insn "xor<mode>3<vczle><vczbe>"
> - [(set (match_operand:VDQ_I 0 "register_operand" "=w")
> - (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
> - (match_operand:VDQ_I 2 "register_operand" "w")))]
> + [(set (match_operand:VDQ_I 0 "register_operand")
> + (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand")
> + (match_operand:VDQ_I 2 "aarch64_reg_or_xor_imm")))]
> "TARGET_SIMD"
> - "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
> + {@ [ cons: =0 , 1 , 2 ]
> + [ w , w , w ] eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
> + [ w , 0 , Do ] << aarch64_output_simd_xor_imm (operands[2],
> <bitsize>);
> + }
> [(set_attr "type" "neon_logic<q>")]
> )
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index
> 1a228147e6f945772edbd5540c44167e3a876a74..c019f21e39d9773746792d5885fa0f6805f9bb44
> 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -134,7 +134,8 @@ constexpr auto AARCH64_STATE_OUT = 1U << 2;
> enum simd_immediate_check {
> AARCH64_CHECK_MOV,
> AARCH64_CHECK_ORR,
> - AARCH64_CHECK_AND
> + AARCH64_CHECK_AND,
> + AARCH64_CHECK_XOR
> };
>
> /* Information about a legitimate vector immediate operand. */
> @@ -23320,6 +23321,13 @@ aarch64_simd_valid_and_imm (rtx op)
> return aarch64_simd_valid_imm (op, NULL, AARCH64_CHECK_AND);
> }
>
> +/* Return true if OP is a valid SIMD xor immediate for SVE. */
> +bool
> +aarch64_simd_valid_xor_imm (rtx op)
> +{
> + return aarch64_simd_valid_imm (op, NULL, AARCH64_CHECK_XOR);
> +}
> +
> /* Check whether X is a VEC_SERIES-like constant that starts at 0 and
> has a step in the range of INDEX. Return the index expression if so,
> otherwise return null. */
> @@ -25503,10 +25511,12 @@ aarch64_output_simd_imm (rtx const_vector, unsigned
> width,
> }
> else
> {
> - /* AARCH64_CHECK_ORR or AARCH64_CHECK_AND. */
> + /* AARCH64_CHECK_ORR, AARCH64_CHECK_AND or AARCH64_CHECK_XOR. */
> mnemonic = "orr";
> if (which == AARCH64_CHECK_AND)
> mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "and";
> + else if (which == AARCH64_CHECK_XOR)
> + mnemonic = "eor";
>
> if (info.insn == simd_immediate_info::SVE_MOV)
> {
> @@ -25544,6 +25554,14 @@ aarch64_output_simd_and_imm (rtx const_vector,
> unsigned width)
> return aarch64_output_simd_imm (const_vector, width, AARCH64_CHECK_AND);
> }
>
> +/* Returns the string with the EOR instruction for the SIMD immediate
> + CONST_VECTOR of WIDTH bits. */
> +char*
> +aarch64_output_simd_xor_imm (rtx const_vector, unsigned width)
> +{
> + return aarch64_output_simd_imm (const_vector, width, AARCH64_CHECK_XOR);
> +}
> +
> /* Returns the string with the MOV instruction for the SIMD immediate
> CONST_VECTOR of WIDTH bits. */
> char*
> diff --git a/gcc/config/aarch64/predicates.md
> b/gcc/config/aarch64/predicates.md
> index
> 2c18af94b8eca7a7985a238a4de8c5d0b3766acb..6ad9a4bd8b92fcbe10260093abf1331c909a474a
> 100644
> --- a/gcc/config/aarch64/predicates.md
> +++ b/gcc/config/aarch64/predicates.md
> @@ -125,6 +125,11 @@ (define_predicate "aarch64_reg_or_and_imm"
> (and (match_code "const_vector")
> (match_test "aarch64_simd_valid_and_imm (op)"))))
>
> +(define_predicate "aarch64_reg_or_xor_imm"
> + (ior (match_operand 0 "register_operand")
> + (and (match_code "const_vector")
> + (match_test "aarch64_simd_valid_xor_imm (op)"))))
> +
> (define_predicate "aarch64_fp_compare_operand"
> (ior (match_operand 0 "register_operand")
> (and (match_code "const_double")
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c
> b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..69ece074eed03c1b1779eea979318343b8bd7b61
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c
> @@ -0,0 +1,35 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +#include <arm_neon.h>
> +
> +/*
> +** t1:
> +** and z[0-9]+.s, z[0-9]+.s, #?3
> +** ret
> +*/
> +uint32x2_t t1 (uint32x2_t a)
> +{
> + return vand_u32 (a, vdup_n_u32 (3));
> +}
> +
> +/*
> +** t2:
> +** orr z[0-9]+.s, z[0-9]+.s, #?-3
> +** ret
> +*/
> +uint32x2_t t2 (uint32x2_t a)
> +{
> + return vorr_u32 (a, vdup_n_u32 (~2));
> +}
> +
> +/*
> +** t3:
> +** eor z[0-9]+.s, z[0-9]+.s, #?3
> +** ret
> +*/
> +uint32x2_t t3 (uint32x2_t a)
> +{
> + return veor_u32 (a, vdup_n_u32 (3));
> +}