Hi Artemiy,
> -----Original Message-----
> From: Artemiy Volkov <[email protected]>
> Sent: 27 April 2026 09:06
> To: [email protected]
> Cc: Tamar Christina <[email protected]>; Wilco Dijkstra
> <[email protected]>; [email protected]; Richard
> Earnshaw <[email protected]>; [email protected]; Alice
> Carlotti <[email protected]>; Alex Coplan <[email protected]>;
> Artemiy Volkov <[email protected]>
> Subject: [PATCH 3/4] aarch64: implement vec_concat support for sub-64-bit
> types
>
> This patch improves handling of 2-element vec_concats in
> aarch64_vector_init_fallback (); where previously the aarch64_vec_concat
> insn was emitted only for pairs of vectors, we now allow scalar operands
> as well. Furthermore, if the two operands are the same, we can now emit a
> vec_duplicate instead of a vec_concat, leading to better code generation.
>
> This is backed by the new combine{z,_internal}{,_be} insn patterns, that
> were each split between integral 16- and 32-bit modes (only involving GPRs
> and memory), and the rest (requiring the "w" alternatives as well).
>
> The effect of the changes is illustrated by the changes to vec-init-23.c,
> introduced in the previous patch (and a handful of other vector-init
> related tests).
Nice!
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-simd.md
> (*aarch64_combine_internal<mode>):
> New insn patterns.
> (*aarch64_combine_internal_be<mode>): Likewise.
> (*aarch64_combinez<mode>): Likewise.
> (*aarch64_combinez_be<mode>): Likewise.
> (@aarch64_vec_concat<mode>): Support smaller vector and scalar
> modes.
> * config/aarch64/aarch64.cc (aarch64_expand_vector_init_fallback):
> Handle the case of two scalar elements.
> * config/aarch64/iterators.md (SSUB64): New mode iterator.
> (VSSUB64): Likewise.
> (VSSUB32_I) : Likewise.
> (VSSUB64_F): Likewise.
> (VS32_I_SUB64_F): Likewise.
> (single_wx): Define attribute for sub-64-bit vector and scalar modes.
> (VDBL): Likewise.
> (single_dwx): New mode attribute.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/sve/gather_load_10.c: Adjust testcase.
> * gcc.target/aarch64/sve/slp_1.c: Likewise.
> * gcc.target/aarch64/vec-init-18.c: Likewise.
> * gcc.target/aarch64/vec-init-23.c: Likewise.
> * gcc.target/aarch64/vec-init-single-const.c: Likewise.
> ---
> gcc/config/aarch64/aarch64-simd.md | 115 +++++++++++++++++-
> gcc/config/aarch64/aarch64.cc | 19 +--
> gcc/config/aarch64/iterators.md | 39 +++++-
> .../gcc.target/aarch64/sve/gather_load_10.c | 3 +-
> gcc/testsuite/gcc.target/aarch64/sve/slp_1.c | 4 +-
> .../gcc.target/aarch64/vec-init-18.c | 7 +-
> .../gcc.target/aarch64/vec-init-23.c | 85 ++++++-------
> .../aarch64/vec-init-single-const.c | 4 +-
> 8 files changed, 209 insertions(+), 67 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index 4bb26621efc..b57d4e29807 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -4814,6 +4814,34 @@
> }
> )
>
> +(define_insn "*aarch64_combine_internal<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VS32_I_SUB64_F 1 "register_operand")
> + (match_operand:VS32_I_SUB64_F 2
> "aarch64_simd_nonimmediate_operand")))]
> + "TARGET_FLOAT
> + && !BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 , 2 ; attrs: type , arch ]
> + [ w , w , w ; neon_permute , simd ]
> uzp1\t%0.<Vdduptype>,
> %1.<Vdduptype>, %2.<Vdduptype>
> + [ w , 0 , w ; neon_move , simd ]
> mov\t%0.<single_type>[1],
> %2.<single_type>[0]
> + [ w , 0 , Utv ; neon_load1_one_lane , simd ]
> ld1\t{%0.<single_type>}[1], %2
> + [ w , 0 , r ; neon_from_gp , simd ]
> ins\t%0.<single_type>[1],
> %<single_wx>2
> + [ ?r , 0 , r ; bfm , * ]
> bfi\t%<single_dwx>0,
> %<single_dwx>2, <bitsize>, <bitsize>
> + }
> +)
> +
> +(define_insn "*aarch64_combine_internal<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VSSUB32_I 1 "register_operand")
> + (match_operand:VSSUB32_I 2
> "aarch64_simd_nonimmediate_operand")))]
> + "TARGET_FLOAT
> + && !BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 , 2 ; attrs: type , arch ]
> + [ r , 0 , r ; bfm , * ]
> bfi\t%<single_dwx>0,
> %<single_dwx>2, <bitsize>, <bitsize>
> + }
> +)
> +
> (define_insn "*aarch64_combine_internal_be<mode>"
> [(set (match_operand:<VDBL> 0 "aarch64_reg_or_mem_pair_operand")
> (vec_concat:<VDBL>
> @@ -4833,6 +4861,35 @@
> }
> )
>
> +(define_insn "*aarch64_combine_internal_be<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VS32_I_SUB64_F 2
> "aarch64_simd_nonimmediate_operand")
> + (match_operand:VS32_I_SUB64_F 1 "register_operand")))]
> + "TARGET_FLOAT
> + && BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 , 2 ; attrs: type , arch ]
> + [ w , w , w ; neon_permute , simd ]
> uzp1\t%0.<Vdduptype>,
> %1.<Vdduptype>, %2.<Vdduptype>
> + [ w , 0 , w ; neon_move , simd ]
> mov\t%0.<single_type>[1],
> %2.<single_type>[0]
> + [ w , 0 , Utv ; neon_load1_one_lane , simd ]
> ld1\t{%0.<single_type>}[1], %2
> + [ w , 0 , r ; neon_from_gp , simd ]
> ins\t%0.<single_type>[1],
> %<single_wx>2
> + [ ?r , 0 , r ; bfm , * ]
> bfi\t%<single_dwx>0,
> %<single_dwx>2, <bitsize>, <bitsize>
> + }
> +)
> +
> +(define_insn "*aarch64_combine_internal_be<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VSSUB32_I 2
> "aarch64_simd_nonimmediate_operand")
> + (match_operand:VSSUB32_I 1 "register_operand")))]
> + "TARGET_FLOAT
> + && BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 , 2 ; attrs: type , arch ]
> + [ r , 0 , r ; bfm , * ]
> bfi\t%<single_dwx>0,
> %<single_dwx>2, <bitsize>, <bitsize>
> + }
> +)
> +
> +
> ;; In this insn, operand 1 should be low, and operand 2 the high part of the
> ;; dest vector.
>
> @@ -4849,6 +4906,33 @@
> }
> )
>
> +(define_insn "*aarch64_combinez<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VSSUB32_I 1 "nonimmediate_operand")
> + (match_operand:VSSUB32_I 2
> "aarch64_simd_or_scalar_imm_zero")))]
> + "TARGET_FLOAT && !BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ r , r ; mov_reg ] uxt<size>\t%w0, %w1
> + [ r , m ; load_4 ] ldr<size>\t%<single_wx>0, %1
> + }
> +)
> +
> +(define_insn "*aarch64_combinez<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VS32_I_SUB64_F 1 "nonimmediate_operand")
> + (match_operand:VS32_I_SUB64_F 2
> "aarch64_simd_or_scalar_imm_zero")))]
> + "TARGET_FLOAT && !BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ w , w ; neon_move ] fmov\t%<single_type>0,
> %<single_type>1
> + [ w , r ; neon_from_gp ] fmov\t%<single_type>0,
> %<single_wx>1
> + [ w , m ; neon_load1_1reg ] ldr\t%<single_type>0, %1
> + [ r , r ; mov_reg ] uxtw\t%x0, %w1
> + [ r , m ; load_4 ] ldr<size>\t%<single_wx>0, %1
> + }
> +)
> +
> (define_insn "*aarch64_combinez_be<mode>"
> [(set (match_operand:<VDBL> 0 "register_operand")
> (vec_concat:<VDBL>
> @@ -4862,14 +4946,41 @@
> }
> )
>
> +(define_insn "*aarch64_combinez_be<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VSSUB32_I 2 "aarch64_simd_or_scalar_imm_zero")
> + (match_operand:VSSUB32_I 1 "nonimmediate_operand")))]
> + "TARGET_FLOAT && BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ r , r ; mov_reg ] uxt<size>\t%w0, %w1
> + [ r , m ; load_4 ] ldr<size>\t%<single_wx>0, %1
> + }
> +)
> +
> +(define_insn "*aarch64_combinez_be<mode>"
> + [(set (match_operand:<VDBL> 0 "register_operand")
> + (vec_concat:<VDBL>
> + (match_operand:VS32_I_SUB64_F 2
> "aarch64_simd_or_scalar_imm_zero")
> + (match_operand:VS32_I_SUB64_F 1 "nonimmediate_operand")))]
> + "TARGET_FLOAT && BYTES_BIG_ENDIAN"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ w , w ; neon_move ] fmov\t%<single_type>0,
> %<single_type>1
> + [ w , r ; neon_from_gp ] fmov\t%<single_type>0,
> %<single_wx>1
> + [ w , m ; neon_load1_1reg ] ldr\t%<single_type>0, %1
> + [ r , r ; mov_reg ] uxtw\t%x0, %w1
> + [ r , m ; load_4 ] ldr<size>\t%<single_wx>0, %1
> + }
> +)
> +
> ;; Form a vector whose first half (in array order) comes from operand 1
> ;; and whose second half (in array order) comes from operand 2.
> ;; This operand order follows the RTL vec_concat operation.
> (define_expand "@aarch64_vec_concat<mode>"
> [(set (match_operand:<VDBL> 0 "register_operand")
> (vec_concat:<VDBL>
> - (match_operand:VDCSIF 1 "general_operand")
> - (match_operand:VDCSIF 2 "general_operand")))]
> + (match_operand:VDUP 1 "general_operand")
> + (match_operand:VDUP 2 "general_operand")))]
> "TARGET_FLOAT"
> {
> int lo = BYTES_BIG_ENDIAN ? 2 : 1;
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 5b1afa50ff8..f08cf032708 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -25502,19 +25502,24 @@ aarch64_expand_vector_init_fallback (rtx
> target, rtx vals)
> rtx v0 = XVECEXP (vals, 0, 0);
> bool all_same = true;
>
> - /* This is a special vec_init<M><N> where N is not an element mode but a
> + /* This is a special vec_init<M><N> where N is either an element mode or a
> vector mode with half the elements of M. We expect to find two entries
> of mode N in VALS and we must put their concatentation into TARGET. */
> - if (XVECLEN (vals, 0) == 2 && VECTOR_MODE_P (GET_MODE (XVECEXP
> (vals, 0, 0))))
> + if (XVECLEN (vals, 0) == 2 && GET_MODE (v0) != VOIDmode)
I don't think we want such a wide relaxation as that would allow things like
COMPLEX_MODE.
So perhaps just VECTOR_MODE_P || SCALAR_INT_MODE_P || SCALAR_FLOAT_MODE_P ?
Patch is OK with that change.
Thanks,
Tamar
> {
> - machine_mode narrow_mode = GET_MODE (XVECEXP (vals, 0, 0));
> + rtx v1 = XVECEXP (vals, 0, 1);
> + machine_mode narrow_mode = GET_MODE (v0);
> gcc_assert (GET_MODE_INNER (narrow_mode) == inner_mode
> && known_eq (GET_MODE_SIZE (mode),
> 2 * GET_MODE_SIZE (narrow_mode)));
> - emit_insn (gen_aarch64_vec_concat (narrow_mode, target,
> - XVECEXP (vals, 0, 0),
> - XVECEXP (vals, 0, 1)));
> - return;
> + if (rtx_equal_p (v0, v1))
> + aarch64_emit_move (target,
> + gen_vec_duplicate (mode,
> + force_reg (narrow_mode, v0)));
> + else
> + emit_insn (gen_aarch64_vec_concat (narrow_mode, target,
> + v0, v1));
> + return;
> }
>
> /* Count the number of variable elements to initialise. */
> diff --git a/gcc/config/aarch64/iterators.md
> b/gcc/config/aarch64/iterators.md
> index 1fc67d95bd4..eafb8f45a1b 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -234,6 +234,21 @@
> ;; All sub-64-bit vector modes.
> (define_mode_iterator VSUB64 [V2QI V4QI V2HI V2HF V2BF])
>
> +;; All sub-64-bit scalar modes.
> +(define_mode_iterator SSUB64 [QI HI HF BF SI SF])
> +
> +;; All sub-64-bit modes.
> +(define_mode_iterator VSSUB64 [VSUB64 SSUB64])
> +
> +;; All sub-32-bit integer modes.
> +(define_mode_iterator VSSUB32_I [V2QI QI HI])
> +
> +;; All sub-64-bit floating-point modes.
> +(define_mode_iterator VSSUB64_F [V2HF V2BF HF BF])
> +
> +;; All 32-bit integer and sub-64-bit floating point modes.
> +(define_mode_iterator VS32_I_SUB64_F [V4QI V2HI VSSUB64_F])
> +
> ;; All Advanced SIMD modes suitable for moving, loading, and storing.
> (define_mode_iterator VALL_F16 [V8QI V16QI V4HI V8HI V2SI V4SI V2DI
> V4HF V8HF V4BF V8BF V2SF V4SF V2DF])
> @@ -1471,7 +1486,13 @@
> (define_mode_attr bitsize [(V8QI "64") (V16QI "128")
> (V4HI "64") (V8HI "128")
> (V2SI "64") (V4SI "128")
> - (V1DI "64") (V2DI "128")])
> + (V1DI "64") (V2DI "128")
> + (QI "8") (V2QI "16")
> + (V4QI "32") (HI "16")
> + (HF "16") (BF "16")
> + (SI "32") (SF "32")
> + (V2HI "32") (V2HF "32")
> + (V2BF "32")])
>
> ;; Map a floating point or integer mode to the appropriate register name
> prefix
> (define_mode_attr s [(HF "h") (SF "s") (DF "d") (SI "s") (DI "d")])
> @@ -1970,10 +1991,16 @@
> (define_mode_attr V1half [(V2DI "v1di") (V2DF "v1df")])
>
> ;; Double modes of vector modes.
> -(define_mode_attr VDBL [(V8QI "V16QI") (V4HI "V8HI")
> +(define_mode_attr VDBL [(V8QI "V16QI") (V4QI "V8QI")
> + (V2QI "V4QI") (V4HI "V8HI")
> (V4HF "V8HF") (V4BF "V8BF")
> + (V2BF "V4BF")
> (V2SI "V4SI") (V2SF "V4SF")
> + (V2HI "V4HI") (V2HF "V4HF")
> + (BF "V2BF")
> (SI "V2SI") (SF "V2SF")
> + (QI "V2QI")
> + (HI "V2HI") (HF "V2HF")
> (DI "V2DI") (DF "V2DF")])
>
> ;; Load/store pair mode.
> @@ -2201,6 +2228,14 @@
> (V2SI "x") (V2SF "x")
> (DI "x") (DF "x")])
>
> +(define_mode_attr single_dwx [(SI "x") (SF "x")
> + (V2QI "w") (V4QI "x")
> + (V2HI "x") (V2HF "x")
> + (HF "w") (QI "w")
> + (V2BF "x") (BF "w")
> + (HI "w")])
> +
> +
> ;; Whether a mode fits in S or D registers (i.e. "s" for 32-bit modes
> ;; and "d" for 64-bit modes).
> (define_mode_attr single_type [(SI "s") (SF "s")
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/gather_load_10.c
> b/gcc/testsuite/gcc.target/aarch64/sve/gather_load_10.c
> index 2a07c0be866..75283d355ae 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/gather_load_10.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/gather_load_10.c
> @@ -11,7 +11,8 @@ foo (uint64_t *restrict x, uint64_t *restrict y, uint64_t
> *restrict index)
> x[i] += y[index[i]];
> }
>
> -/* { dg-final { scan-assembler-times {\tldr\td[0-9]+, \[x[0-9]+, x[0-9]+, lsl
> #?3\]} 2 } } */
> +/* { dg-final { scan-assembler-times {\tldr\td[0-9]+, \[x[0-9]+, x[0-9]+, lsl
> #?3\]} 1 } } */
> +/* { dg-final { scan-assembler-times {\tld1\t{v[0-9]+\.d}\[1\], \[x[0-9]+\]}
> 1 }
> } */
> /* { dg-final { scan-assembler-not {\tshl\tv[0-9]+\.2d,} } } */
> /* { dg-final { scan-assembler-not {\tumov\t} } } */
> /* { dg-final { scan-assembler {\tadd\tv[0-9]+\.2d,} } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
> b/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
> index 2bb2c04fa20..1fbb08c7566 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
> @@ -30,12 +30,12 @@ vec_slp_##TYPE (TYPE *restrict a, TYPE b, TYPE c, int
> n) \
> TEST_ALL (VEC_PERM)
>
> /* We should use one DUP for each of the 8-, 16- and 32-bit types,
> - (for now, insert both elements with ins for _Float16). We should use two
> + (and we now use fmov + ins for _Float16). We should use two
> DUPs for each of the three 64-bit types. */
> /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, [hw]} 2 } } */
> /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, [sw]} 3 } } */
> /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, [dx]} 9 } } */
> -/* { dg-final { scan-assembler-times {\tins\tv[0-9]+\.h\[0\],
> v[0-9]+\.h\[0\]}
> 1 } } */
> +/* { dg-final { scan-assembler-times {\tfmov\th[0-9]+, h} 1 } } */
> /* { dg-final { scan-assembler-times {\tins\tv[0-9]+\.h\[1\],
> v[0-9]+\.h\[0\]}
> 1 } } */
> /* { dg-final { scan-assembler-times {\tzip1\tz[0-9]+\.d, z[0-9]+\.d, z[0-
> 9]+\.d\n} 3 } } */
> /* { dg-final { scan-assembler-not {\tzip2\t} } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-18.c
> b/gcc/testsuite/gcc.target/aarch64/vec-init-18.c
> index feeb181a0b5..394537c80d8 100644
> --- a/gcc/testsuite/gcc.target/aarch64/vec-init-18.c
> +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-18.c
> @@ -15,7 +15,6 @@ int16x8_t foo2(int16_t x)
> return v;
> }
>
> -/* { dg-final { scan-assembler-times {\tdup\tv[0-9]+\.4s, w[0-9]+} 2 } } */
> -/* { dg-final { scan-assembler-times {\tmov\tw[0-9]+, 65537} 1 } } */
> -/* { dg-final { scan-assembler-times {\tbfi\tw[0-9]+, w[0-9]+, 0, 16} 1 } }
> */
> -/* { dg-final { scan-assembler-times {\tbfi\tw[0-9]+, w[0-9]+, 16, 16} 1 } }
> */
> +/* { dg-final { scan-assembler-times {\tmov\tw1, 1} 1 } } */
> +/* { dg-final { scan-assembler-times {\tdup\tv0+\.4s, w0} 2 } } */
> +/* { dg-final { scan-assembler-times {\tbfi\tw0, w1, 16, 16} 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-23.c
> b/gcc/testsuite/gcc.target/aarch64/vec-init-23.c
> index 595470b29fb..217838ea55a 100644
> --- a/gcc/testsuite/gcc.target/aarch64/vec-init-23.c
> +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-23.c
> @@ -111,9 +111,8 @@ TEST_64(int, int64_t, s)
>
> /*
> ** test_int8_5:
> -** mov w1, 0
> -** bfi w1, w0, 0, 8
> -** dup v0\.8h, w1
> +** uxtb w0, w0
> +** dup v0\.8h, w0
> ** ret
> */
>
> @@ -217,7 +216,7 @@ TEST_64(int, int64_t, s)
> ** test_float16_2:
> ** fcvt h1, s1
> ** fcvt h0, s0
> -** ins v0\.h\[1\], v1\.h\[0\]
> +** uzp1 v0\.4h, v0\.4h, v1\.4h
> ** dup v0\.4s, v0\.s\[0\]
> ** ret
> */
> @@ -227,55 +226,51 @@ TEST_64(int, int64_t, s)
> ** uzp1 v2\.2s, v0\.2s, v2\.2s
> ** uzp1 v3\.2s, v1\.2s, v3\.2s
> ** zip1 v3\.4s, v2\.4s, v3\.4s
> -** fcvtn v0\.4h, v3\.4s
> -** uzp1 v0\.2d, v0\.2d, v0\.2d
> +** fcvtn v3\.4h, v3\.4s
> +** dup v0\.2d, v3\.d\[0\]
> ** ret
> */
>
> /*
> ** test_float16_4:
> ** fcvt h0, s0
> -** movi v31\.2d, #0
> -** ins v31\.h\[0\], v0\.h\[0\]
> -** dup v0\.4s, v31\.s\[0\]
> +** fmov h0, h0
> +** dup v0\.4s, v0\.s\[0\]
> ** ret
> */
>
> /*
> ** test_float16_5:
> +** movi v31\.4h, #0
> ** fcvt h0, s0
> -** movi v31\.2d, #0
> -** ins v31\.h\[1\], v0\.h\[0\]
> -** dup v0\.4s, v31\.s\[0\]
> +** uzp1 v0\.4h, v31\.4h, v0\.4h
> +** dup v0\.4s, v0\.s\[0\]
> ** ret
> */
>
> /*
> ** test_float16_6:
> -** fcvt h1, s1
> ** fcvt h0, s0
> -** movi v31\.2d, #0
> -** mov w0, 1006648320
> -** umov w1, v1\.h\[0\]
> -** ins v31\.h\[0\], v0\.h\[0\]
> -** bfi w0, w1, 0, 16
> -** dup v31\.2s, v31\.s\[0\]
> -** dup v0\.2s, w0
> -** zip1 v0\.8h, v31\.8h, v0\.8h
> +** fcvt h1, s1
> +** fmov h31, 1.0e\+0
> +** fmov h0, h0
> +** uzp1 v1\.4h, v1\.4h, v31\.4h
> +** dup v0\.2s, v0\.s\[0\]
> +** dup v1\.2s, v1\.s\[0\]
> +** zip1 v0\.8h, v0\.8h, v1\.8h
> ** ret
> */
>
> /*
> ** test_float16_7:
> -** fcvt h1, s1
> ** fcvt h0, s0
> -** movi v31\.2d, #0
> -** mov w0, 1006648320
> -** umov w1, v1\.h\[0\]
> -** ins v31\.h\[1\], v0\.h\[0\]
> -** bfi w0, w1, 16, 16
> +** movi v31\.4h, #0
> +** fcvt h1, s1
> +** uzp1 v31\.4h, v31\.4h, v0\.4h
> +** fmov h0, 1.0e\+0
> +** uzp1 v0\.4h, v0\.4h, v1\.4h
> ** dup v31\.2s, v31\.s\[0\]
> -** dup v0\.2s, w0
> +** dup v0\.2s, v0\.s\[0\]
> ** zip1 v0\.8h, v31\.8h, v0\.8h
> ** ret
> */
> @@ -285,7 +280,7 @@ TEST_64(int, int64_t, s)
> ** fcvt h1, s1
> ** fcvt h0, s0
> ** movi v31\.2s, 0x3c, lsl 24
> -** ins v0\.h\[1\], v1\.h\[0\]
> +** uzp1 v0\.4h, v0\.4h, v1\.4h
> ** dup v0\.2s, v0\.s\[0\]
> ** zip1 v0\.8h, v31\.8h, v0\.8h
> ** ret
> @@ -316,9 +311,8 @@ TEST_64(int, int64_t, s)
>
> /*
> ** test_int16_4:
> -** mov w1, 0
> -** bfi w1, w0, 0, 16
> -** dup v0\.4s, w1
> +** uxth w0, w0
> +** dup v0\.4s, w0
> ** ret
> */
>
> @@ -332,12 +326,11 @@ TEST_64(int, int64_t, s)
>
> /*
> ** test_int16_6:
> -** mov w2, 0
> -** bfi w2, w0, 0, 16
> -** mov w0, 65537
> -** bfi w0, w1, 0, 16
> -** dup v31\.2s, w2
> -** dup v0\.2s, w0
> +** uxth w0, w0
> +** dup v31\.2s, w0
> +** mov w0, 1
> +** bfi w1, w0, 16, 16
> +** dup v0\.2s, w1
> ** zip1 v0\.8h, v31\.8h, v0\.8h
> ** ret
> */
> @@ -378,17 +371,16 @@ TEST_64(int, int64_t, s)
>
> /*
> ** test_float32_3:
> -** movi v31\.2s, 0
> -** dup v0\.2s, v0\.s\[0\]
> -** zip1 v0\.4s, v0\.4s, v31\.4s
> +** fmov s0, s0
> +** dup v0\.2d, v0\.d\[0\]
> ** ret
> */
>
> /*
> ** test_float32_4:
> -** movi v31\.2s, 0
> -** dup v0\.2s, v0\.s\[0\]
> -** zip1 v0\.4s, v31\.4s, v0\.4s
> +** movi v31\.2s, #0
> +** uzp1 v0\.2s, v31\.2s, v0\.2s
> +** dup v0\.2d, v0\.d\[0\]
> ** ret
> */
>
> @@ -408,9 +400,8 @@ TEST_64(int, int64_t, s)
>
> /*
> ** test_int32_3:
> -** dup v31\.2s, w0
> -** movi v0\.2s, 0
> -** zip1 v0\.4s, v31\.4s, v0\.4s
> +** fmov s0, w0
> +** dup v0\.2d, v0\.d\[0\]
> ** ret
> */
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> b/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> index 587b7ec0e3b..98f75336d86 100644
> --- a/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> @@ -47,8 +47,8 @@ int32x4_t f_s32(int32_t x)
> /*
> ** f_s64:
> ** fmov d0, x0
> -** mov (x[0-9]+), 1
> -** ins v0\.d\[1\], \1
> +** mov x0, 1
> +** ins v0\.d\[1\], x0
> ** ret
> */
>
> --
> 2.43.0