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\]

Reply via email to