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

Reply via email to