[gcc r17-1372] aarch64: define duplication into sub-64-bit AdvSIMD vectors [PR125538]

Artemiy Volkov artemiyv@gcc.gnu.org
Fri Jun 5 12:40:15 GMT 2026


https://gcc.gnu.org/g:80b78b2504fba037c4edf7172712210b323dcf32

commit r17-1372-g80b78b2504fba037c4edf7172712210b323dcf32
Author: Artemiy Volkov <artemiy.volkov@arm.com>
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\]


More information about the Gcc-cvs mailing list