Hi Artemiy,
> -----Original Message-----
> From: Artemiy Volkov <[email protected]>
> Sent: 08 September 2026 10:20
> To: [email protected]
> Cc: Tamar Christina <[email protected]>; [email protected];
> Richard Earnshaw <[email protected]>;
> [email protected]; Artemiy Volkov
> <[email protected]>
> Subject: [PATCH v2] aarch64: fix combinez patterns for FP16 types
> [PR126983]
>
> The following is the second take on [0] with feedback from Tamar addressed.
>
> Changes since v1:
> - Simplify the VS32_I_SUB64_F iterator instead of removing it.
> - Add a single VS32_I_SUB64_F_CONDFP16 iterator instead of multiple ones.
> - Split VS32_I_SUB64_F variants of aarch64_combinez patterns into all
> modes (incl. FP16 types if there is ISA support), and HFBF specifically
> if FP16 is not available.
> - Fix those patterns to use uxt<extsize> instead of uxtw.
>
> [0] https://gcc.gnu.org/pipermail/gcc-patches/2026-August/729125.html
>
> ---------- 8< ----------
>
> The combinez patterns for scalar and partial vector operands added in
> r17-898-g920eeb67a3537b use the FMOV instruction indiscriminately,
> including for scalar FP16 modes in absence of the fp16 extension, causing
> assembly failure reported in PR126983. Fix this by specializing the
> patterns for HF and BF modes and using the indexed INS instruction as
> fallback.
>
> This patch also adds the new vec-init-23-nofp16.c test, which simply tries
> to assemble the testcases from vec-init-23.c without the fp16 extension
> (including test_float16_6 that triggers the problem).
>
> Bootstrapped and regtested on aarch64-linux-gnu.
>
> PR target/126983
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-simd.md (*aarch64_combinez<mode>):
> Split into VS32_I_SUB64_F_CONDFP16 and HFBF variants. Change
> uxtw to uxt<extsize>.
> (*aarch64_combinez_be<mode>): Likewise.
> * config/aarch64/iterators.md (VSSUB64_F): Remove iterator.
> (VS32_I_SUB64_F): Amend by explicitly listing all modes.
> (VS32_I_SUB64_F_CONDFP16): New iterator.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/vec-init-23-nofp16.c: New test.
> ---
> gcc/config/aarch64/aarch64-simd.md | 37 ++++++++++++++++---
> gcc/config/aarch64/iterators.md | 11 ++++--
> .../gcc.target/aarch64/vec-init-23-nofp16.c | 4 ++
> 3 files changed, 42 insertions(+), 10 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/vec-init-23-nofp16.c
>
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index 12dcabb7a15..731eb5c03ca 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -5107,18 +5107,30 @@
> (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")))]
> + (match_operand:VS32_I_SUB64_F_CONDFP16 1
> "nonimmediate_operand")
> + (match_operand:VS32_I_SUB64_F_CONDFP16 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 , r ; mov_reg ] uxt<extsize>\t%<single_dwx>0, %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:HFBF 1 "nonimmediate_operand")
> + (match_operand:HFBF 2 "aarch64_simd_or_scalar_imm_zero")))]
> + "TARGET_SIMD && !BYTES_BIG_ENDIAN && !TARGET_SIMD_F16INST"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ w , 0 ; neon_move ] ins\t%0.<single_type>[1], wzr
> + [ w , m ; neon_load1_1reg ] ldr\t%<single_type>0, %1
> + }
> +)
> +
> (define_insn "*aarch64_combinez_be<mode>"
> [(set (match_operand:<VDBL> 0 "register_operand")
> (vec_concat:<VDBL>
> @@ -5147,18 +5159,31 @@
> (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")))]
> + (match_operand:VS32_I_SUB64_F_CONDFP16 2
> "aarch64_simd_or_scalar_imm_zero")
> + (match_operand:VS32_I_SUB64_F_CONDFP16 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 , r ; mov_reg ] uxt<extsize>\t%<single_dwx>0, %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:HFBF 2 "aarch64_simd_or_scalar_imm_zero")
> + (match_operand:HFBF 1 "nonimmediate_operand")))]
> + "TARGET_SIMD && BYTES_BIG_ENDIAN && !TARGET_SIMD_F16INST"
> + {@ [ cons: =0 , 1 ; attrs: type ]
> + [ w , 0 ; neon_move ] ins\t%0.<single_type>[1], wzr
Is this supposed to be ins\t%0.<single_type>[0], wzr?
OK with that change.
Thanks,
Tamar
> + [ w , m ; neon_load1_1reg ] ldr\t%<single_type>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.
> diff --git a/gcc/config/aarch64/iterators.md
> b/gcc/config/aarch64/iterators.md
> index a56edb8ebf4..59c61e2bd32 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -253,11 +253,14 @@
> ;; 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])
> +(define_mode_iterator VS32_I_SUB64_F [V4QI V2HI V2HF V2BF HF BF])
> +
> +;; All 32-bit integer and sub-64-bit floating point modes, excluding BF
> +;; and HF when there's no FP16 ISA support.
> +(define_mode_iterator VS32_I_SUB64_F_CONDFP16 [V4QI V2HI V2HF V2BF
> + (HF "TARGET_SIMD_F16INST")
> + (BF "TARGET_SIMD_F16INST")])
>
> ;; All Advanced SIMD modes suitable for moving, loading, and storing.
> (define_mode_iterator VALL_F16 [V8QI V16QI V4HI V8HI V2SI V4SI V2DI
> diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-23-nofp16.c
> b/gcc/testsuite/gcc.target/aarch64/vec-init-23-nofp16.c
> new file mode 100644
> index 00000000000..636f4758c19
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-23-nofp16.c
> @@ -0,0 +1,4 @@
> +/* { dg-do assemble } */
> +/* { dg-options "-O2 -march=armv8-a" } */
> +
> +#include "vec-init-23.c"
> --
> 2.43.0