This adds an AARCH64_VALID_SIMD_DREG_MODE exactly paralleling the existing ...QREG... macro, and as a driveby fixes mode->(MODE) in the latter.
The new test now compiles (at -O3) to: test_1: add v1.2s, v1.2s, v5.2s add v2.2s, v2.2s, v6.2s add v3.2s, v3.2s, v7.2s add v0.2s, v0.2s, v4.2s ret Whereas prior to this patch we got: test_1: add v0.2s, v0.2s, v4.2s sub sp, sp, #160 add v1.2s, v1.2s, v5.2s add v2.2s, v2.2s, v6.2s add v3.2s, v3.2s, v7.2s str d0, [sp, 96] str d1, [sp, 104] str d2, [sp, 112] str d3, [sp, 120] ldp x2, x3, [sp, 96] stp x2, x3, [sp, 128] ldp x0, x1, [sp, 112] stp x0, x1, [sp, 144] ldr d1, [sp, 136] ldr d0, [sp, 128] ldr d2, [sp, 144] ldr d3, [sp, 152] add sp, sp, 160 ret I've tried to look for (the absence of) this extra code in a number of ways, all 3 scan...not's were previously failing (i.e. regex's were matching) but now pass. bootstrapped and check-gcc on aarch64-none-linux-gnu. gcc/ChangeLog: * config/aarch64/aarch64.h (AARCH64_VALID_SIMD_DREG_MODE): New. (AARCH64_VALID_SIMD_QREG_MODE): Correct mode->MODE. * config/aarch64/aarch64.c (aarch64_array_mode_supported_p): Add AARCH64_VALID_SIMD_DREG_MODE. gcc/testsuite/ChangeLog: * gcc.target/aarch64/vect-int32x2x4_1.c: New. --- gcc/config/aarch64/aarch64.c | 3 ++- gcc/config/aarch64/aarch64.h | 7 ++++++- .../gcc.target/aarch64/vect-int32x2x4_1.c | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/vect-int32x2x4_1.c diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index a923b55..d2ea7f6 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -650,7 +650,8 @@ aarch64_array_mode_supported_p (machine_mode mode, unsigned HOST_WIDE_INT nelems) { if (TARGET_SIMD - && AARCH64_VALID_SIMD_QREG_MODE (mode) + && (AARCH64_VALID_SIMD_QREG_MODE (mode) + || AARCH64_VALID_SIMD_DREG_MODE (mode)) && (nelems >= 2 && nelems <= 4)) return true; diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 3851564..d1ba00b 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -915,10 +915,15 @@ extern enum aarch64_code_model aarch64_cmodel; (aarch64_cmodel == AARCH64_CMODEL_TINY \ || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC) +/* Modes valid for AdvSIMD D registers, i.e. that fit in half a Q register. */ +#define AARCH64_VALID_SIMD_DREG_MODE(MODE) \ + ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode \ + || (MODE) == V2SFmode || (MODE) == DImode || (MODE) == DFmode) + /* Modes valid for AdvSIMD Q registers. */ #define AARCH64_VALID_SIMD_QREG_MODE(MODE) \ ((MODE) == V4SImode || (MODE) == V8HImode || (MODE) == V16QImode \ - || (MODE) == V4SFmode || (MODE) == V2DImode || mode == V2DFmode) + || (MODE) == V4SFmode || (MODE) == V2DImode || (MODE) == V2DFmode) #define ENDIAN_LANE_N(mode, n) \ (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n) diff --git a/gcc/testsuite/gcc.target/aarch64/vect-int32x2x4_1.c b/gcc/testsuite/gcc.target/aarch64/vect-int32x2x4_1.c new file mode 100644 index 0000000..734cfd6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vect-int32x2x4_1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-rtl-expand" } */ + +#include <arm_neon.h> + +uint32x2x4_t +test_1 (uint32x2x4_t a, uint32x2x4_t b) +{ + uint32x2x4_t result; + + for (unsigned index = 0; index < 4; ++index) + result.val[index] = a.val[index] + b.val[index]; + + return result; +} + +/* Should not use the stack in expand. */ +/* { dg-final { scan-rtl-dump-not "virtual-stack-vars" "expand" } } */ +/* Should not have to modify the stack pointer. */ +/* { dg-final { scan-assembler-not "\t(add|sub).*sp" } } */ +/* Should not have to store or load anything. */ +/* { dg-final { scan-assembler-not "\t(ld|st)\[rp\]" } } */ -- 1.8.3