https://gcc.gnu.org/g:80b78b2504fba037c4edf7172712210b323dcf32
commit r17-1372-g80b78b2504fba037c4edf7172712210b323dcf32 Author: Artemiy Volkov <[email protected]> Date: Thu Jun 4 14:47:17 2026 +0000 aarch64: define duplication into sub-64-bit AdvSIMD vectors [PR125538] This is a second attempt to deal with the ICE reported in PR125538, triggering when we generate a (vec_duplicate:V4QI (reg:QI)) expression for which we currently lack RTL support. More specifically, this occurs when doing a splat of the most common element in aarch64_expand_vector_init_fallback () at aarch64.cc:25876. This is the alternative approach mentioned in the original commit message at [0], whereby we simply define vec_duplicate patterns for 16-bit and 32-bit destinations. Same tests are added as in [0] (a full test reduced in the comments to the PR, as well as some new vector constructor element combinations in vec_init_5.c and vec-init-23.c). Regtested and bootstrapped on aarch64-linux-gnu. [0] https://gcc.gnu.org/pipermail/gcc-patches/2026-June/719181.html PR target/125538 gcc/ChangeLog: * config/aarch64/aarch64-simd.md (*aarch64_simd_dup_subvector<vcons><mode>): New insn pattern. (*aarch64_simd_dup_subvectorv2qiqi): Likewise. * config/aarch64/iterators.md (VSDUP): New mode iterator. (VCONS): New mode attribute. (vcons): Likewise. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/vec_init_5.c: Add new 8/16-bit testcases. * gcc.target/aarch64/vec-init-23.c: Likewise. * gcc.target/aarch64/pr125538.c: New test. Diff: --- gcc/config/aarch64/aarch64-simd.md | 22 +++++++ gcc/config/aarch64/iterators.md | 13 ++++ gcc/testsuite/gcc.target/aarch64/pr125538.c | 20 +++++++ gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c | 68 +++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/vec-init-23.c | 72 ++++++++++++++++++++++- 5 files changed, 194 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 65b8065a4129..843ad6cb0766 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -159,6 +159,28 @@ } ) +(define_insn "*aarch64_simd_dup_subvector<vcons><mode>" + [(set (match_operand:<VCONS> 0 "register_operand") + (vec_duplicate:<VCONS> + (match_operand:VSDUP 1 "register_operand")))] + "TARGET_SIMD" + {@ [ cons: =0 , 1 ; attrs: type ] + [ w , w ; neon_dup ] dup\t%0.<Vdduptype>, %1.<vstype>[0] + [ w , r ; neon_from_gp ] dup\t%0.<Vdduptype>, %<single_wx>1 + } +) + +(define_insn "*aarch64_simd_dup_subvectorv2qiqi" + [(set (match_operand:V2QI 0 "register_operand") + (vec_duplicate:V2QI + (match_operand:QI 1 "register_operand")))] + "TARGET_SIMD" + {@ [ cons: =0 , 1 ; attrs: type ] + [ w , w ; neon_dup ] dup\t%0.8b, %1.b[0] + [ w , r ; neon_from_gp ] dup\t%0.8b, %w1 + } +) + (define_insn "@aarch64_dup_lane<mode>" [(set (match_operand:VALL_F16 0 "register_operand" "=w") (vec_duplicate:VALL_F16 diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index bc0b9a50ac19..9adbf04c3405 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -139,6 +139,9 @@ ;; VQMOV without 2-element modes. (define_mode_iterator VQMOV_NO2E [V16QI V8HI V4SI V8HF V8BF V4SF]) +;; Modes that can be duplicated into a 32-bit quantity. +(define_mode_iterator VSDUP [V2QI QI HI BF HF]) + ;; Modes that can be duplicated into a 64-bit register. (define_mode_iterator VDDUP [V4QI V2QI QI V2HI HI SI V2BF BF V2HF HF SF]) @@ -1935,6 +1938,16 @@ (define_mode_attr vnx [(V4SI "vnx4si") (V2DI "vnx2di")]) +;; 32-bit container modes the inner or scalar source mode. +(define_mode_attr VCONS [(HI "V2HI") (QI "V4QI") (V2QI "V4QI") + (HF "V2HF") + (BF "V2BF")]) + +;; Same as above, but in lowercase. +(define_mode_attr vcons [(HI "v2hi") (QI "v4qi") (V2QI "v4qi") + (HF "v2hf") + (BF "v2bf")]) + ;; 64-bit container modes the inner or scalar source mode. (define_mode_attr VCOND [(HI "V4HI") (SI "V2SI") (V2HI "V4HI") diff --git a/gcc/testsuite/gcc.target/aarch64/pr125538.c b/gcc/testsuite/gcc.target/aarch64/pr125538.c new file mode 100644 index 000000000000..ac97744efae0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr125538.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv9.5-a" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#define vect16 __attribute__((vector_size(16))) + +vect16 char fff(char _292, char _145, char _231) +{ + return (vect16 char) {_292, _145, _145, _231, _292, _145, _145, _231, _292, _145, _145, _231, _292, _145, _145, _231}; +} + +/* +** fff: +** dup v31\.8b, w1 +** fmov w1, s31 +** bfi w1, w0, 0, 8 +** bfi w1, w2, 24, 8 +** dup v0\.4s, w1 +** ret +*/ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c index 99e04aac2650..2bc9a3aeba5e 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c @@ -152,6 +152,26 @@ ** ret */ +/* +** test_int8_14: +** dup v31\.8b, w1 +** fmov w1, s31 +** bfi w1, w0, 0, 8 +** bfi w1, w2, 24, 8 +** mov z0\.s, w1 +** ret +*/ + +/* +** test_int8_15: +** dup v31\.8b, w1 +** fmov w1, s31 +** bfi w1, w0, 0, 8 +** bfi w1, w2, 16, 8 +** mov z0\.s, w1 +** ret +*/ + /* ** test_float16_1: ** fcvt h0, s0 @@ -236,6 +256,33 @@ ** ret */ +/* +** test_float16_9: +** fcvt h1, s1 +** fcvt h2, s2 +** fcvt h0, s0 +** uzp1 v0\.4h, v0\.4h, v1\.4h +** uzp1 v1\.4h, v1\.4h, v2\.4h +** dup v0\.2s, v0\.s\[0\] +** dup v1\.2s, v1\.s\[0\] +** zip1 v0\.8h, v0\.8h, v1\.8h +** dup z0\.q, z0.q\[0\] +** ret +*/ + +/* +** test_float16_10: +** fcvt h2, s2 +** fcvt h0, s0 +** fcvt h1, s1 +** uzp1 v0\.4h, v0\.4h, v2\.4h +** dup v1\.4h, v1\.h\[0\] +** dup v0\.2s, v0\.s\[0\] +** zip1 v0\.8h, v0\.8h, v1\.8h +** dup z0\.q, z0.q\[0\] +** ret +*/ + /* ** test_int16_1: ** mov z0\.h, w0 @@ -310,6 +357,27 @@ ** ret */ +/* +** test_int16_9: +** bfi w0, w1, 16, 16 +** bfi w1, w2, 16, 16 +** dup v31\.2s, w0 +** dup v30\.2s, w1 +** zip1 v31\.8h, v31\.8h, v30\.8h +** dup z0\.q, z31\.q\[0\] +** ret +*/ + +/* +** test_int16_10: +** bfi w0, w2, 16, 16 +** dup v30\.4h, w1 +** dup v31\.2s, w0 +** zip1 v31\.8h, v31\.8h, v30\.8h +** dup z0\.q, z31\.q\[0\] +** ret +*/ + /* ** test_float32_1: ** mov z0\.s, s0 diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-23.c b/gcc/testsuite/gcc.target/aarch64/vec-init-23.c index 8c154f3680df..2a209509d1ba 100644 --- a/gcc/testsuite/gcc.target/aarch64/vec-init-23.c +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-23.c @@ -41,7 +41,11 @@ TESTCASE (TYPE, ETYPE, T, 8, 12, x16, x0, x1, 0, 1, x2, x3, 2, 3,\ x0, x1, 0, 1, x2, x3, 2, 3)\ TESTCASE (TYPE, ETYPE, T, 8, 13, x16, 0, 1, x0, x1, 2, 3, x2, x3,\ - 0, 1, x0, x1, 2, 3, x2, x3) + 0, 1, x0, x1, 2, 3, x2, x3) \ + TESTCASE (TYPE, ETYPE, T, 8, 14, x16, x0, x1, x1, x2, x0, x1, x1, x2,\ + x0, x1, x1, x2, x0, x1, x1, x2) \ + TESTCASE (TYPE, ETYPE, T, 8, 15, x16, x0, x1, x2, x1, x0, x1, x2, x1,\ + x0, x1, x2, x1, x0, x1, x2, x1) #define TEST_16(TYPE, ETYPE, T)\ TESTCASE (TYPE, ETYPE, T, 16, 1, x8, x0, x0, x0, x0, x0, x0, x0, x0)\ @@ -52,6 +56,8 @@ TESTCASE (TYPE, ETYPE, T, 16, 6, x8, x0, x1, 0, 1, x0, x1, 0, 1)\ TESTCASE (TYPE, ETYPE, T, 16, 7, x8, 0, 1, x0, x1, 0, 1, x0, x1)\ TESTCASE (TYPE, ETYPE, T, 16, 8, x8, 0, x0, 1, x1, 0, x0, 1, x1)\ + TESTCASE (TYPE, ETYPE, T, 16, 9, x8, x0, x1, x1, x2, x0, x1, x1, x2)\ + TESTCASE (TYPE, ETYPE, T, 16, 10, x8, x0, x1, x2, x1, x0, x1, x2, x1) #define TEST_32(TYPE, ETYPE, T)\ TESTCASE (TYPE, ETYPE, T, 32, 1, x4, x0, x0, x0, x0)\ @@ -205,6 +211,26 @@ TEST_64(int, int64_t, s) ** ret */ +/* +** test_int8_14: +** dup v31\.8b, w1 +** fmov w1, s31 +** bfi w1, w0, 0, 8 +** bfi w1, w2, 24, 8 +** dup v0\.4s, w1 +** ret +*/ + +/* +** test_int8_15: +** dup v31\.8b, w1 +** fmov w1, s31 +** bfi w1, w0, 0, 8 +** bfi w1, w2, 16, 8 +** dup v0\.4s, w1 +** ret +*/ + /* ** test_float16_1: ** fcvt h0, s0 @@ -286,6 +312,31 @@ TEST_64(int, int64_t, s) ** ret */ +/* +** test_float16_9: +** fcvt h1, s1 +** fcvt h2, s2 +** fcvt h0, s0 +** uzp1 v0\.4h, v0\.4h, v1\.4h +** uzp1 v1\.4h, v1\.4h, v2\.4h +** dup v0\.2s, v0\.s\[0\] +** dup v1\.2s, v1\.s\[0\] +** zip1 v0\.8h, v0\.8h, v1\.8h +** ret +*/ + +/* +** test_float16_10: +** fcvt h2, s2 +** fcvt h0, s0 +** fcvt h1, s1 +** uzp1 v0\.4h, v0\.4h, v2\.4h +** dup v1\.4h, v1\.h\[0\] +** dup v0\.2s, v0\.s\[0\] +** zip1 v0\.8h, v0\.8h, v1\.8h +** ret +*/ + /* ** test_int16_1: ** dup v0\.8h, w0 @@ -356,6 +407,25 @@ TEST_64(int, int64_t, s) ** ret */ +/* +** test_int16_9: +** bfi w0, w1, 16, 16 +** bfi w1, w2, 16, 16 +** dup v31\.2s, w0 +** dup v0\.2s, w1 +** zip1 v0\.8h, v31\.8h, v0\.8h +** ret +*/ + +/* +** test_int16_10: +** bfi w0, w2, 16, 16 +** dup v0\.4h, w1 +** dup v31\.2s, w0 +** zip1 v0\.8h, v31\.8h, v0\.8h +** ret +*/ + /* ** test_float32_1: ** dup v0\.4s, v0\.s\[0\]
