diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 3 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/mixed_size_9.c | 18 |
5 files changed, 51 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9126ec1..308774d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-12-19 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.c (aarch64_simd_valid_immediate): When + handling partial SVE vectors, use the container mode rather than + the element mode if the constant isn't a single-element duplicate. + * config/aarch64/aarch64-sve.md (@aarch64_sve_reinterpret<mode>): + Check targetm.can_change_mode_class instead of BYTES_BIG_ENDIAN. + 2019-12-19 Andrew Stubbs <ams@codesourcery.com> * config/gcn/gcn-valu.md (addv64si3<exec_clobber>): Rename to ... diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 1d9cdad..feb7559 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -694,7 +694,8 @@ UNSPEC_REINTERPRET))] "TARGET_SVE" { - if (!BYTES_BIG_ENDIAN) + machine_mode src_mode = GET_MODE (operands[1]); + if (targetm.can_change_mode_class (<MODE>mode, src_mode, FP_REGS)) { emit_move_insn (operands[0], gen_lowpart (<MODE>mode, operands[1])); DONE; diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 88baf96..a85f8b0 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -16826,12 +16826,28 @@ aarch64_simd_valid_immediate (rtx op, simd_immediate_info *info, } } - unsigned int elt_size = GET_MODE_SIZE (elt_mode); + /* If all elements in an SVE vector have the same value, we have a free + choice between using the element mode and using the container mode. + Using the element mode means that unused parts of the vector are + duplicates of the used elements, while using the container mode means + that the unused parts are an extension of the used elements. Using the + element mode is better for (say) VNx4HI 0x101, since 0x01010101 is valid + for its container mode VNx4SI while 0x00000101 isn't. + + If not all elements in an SVE vector have the same value, we need the + transition from one element to the next to occur at container boundaries. + E.g. a fixed-length VNx4HI containing { 1, 2, 3, 4 } should be treated + in the same way as a VNx4SI containing { 1, 2, 3, 4 }. */ + scalar_int_mode elt_int_mode; + if ((vec_flags & VEC_SVE_DATA) && n_elts > 1) + elt_int_mode = aarch64_sve_container_int_mode (mode); + else + elt_int_mode = int_mode_for_mode (elt_mode).require (); + + unsigned int elt_size = GET_MODE_SIZE (elt_int_mode); if (elt_size > 8) return false; - scalar_int_mode elt_int_mode = int_mode_for_mode (elt_mode).require (); - /* Expand the vector constant out into a byte vector, with the least significant byte of the register first. */ auto_vec<unsigned char, 16> bytes; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d47488..bbca1aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-12-19 Richard Sandiford <richard.sandiford@arm.com> + * gcc.target/aarch64/sve/mixed_size_9.c: New test. + +2019-12-19 Richard Sandiford <richard.sandiford@arm.com> + * gcc.target/aarch64/sve/mixed_size_8.c: New test. 2019-12-19 Richard Sandiford <richard.sandiford@arm.com> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mixed_size_9.c b/gcc/testsuite/gcc.target/aarch64/sve/mixed_size_9.c new file mode 100644 index 0000000..5f78150 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/mixed_size_9.c @@ -0,0 +1,18 @@ +/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model -msve-vector-bits=256" } */ +/* Originally from gcc.dg/vect/pr88598-4.c. */ + +#define N 4 + +int a[N]; + +int __attribute__ ((noipa)) +f2 (void) +{ + int b[N] = { 0, 31, 0, 31 }, res = 0; + for (int i = 0; i < N; ++i) + res += a[i] & b[i]; + return res; +} + +/* { dg-final { scan-assembler-not {\tmov\tz[0-9]\.d, #} } } */ +/* { dg-final { scan-assembler-not {\tstr\tz[0-9],} } } */ |