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
+     [ 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