Hi all,

This is the second take on the vec_init improvements series with Tamar's
feedback addressed; v1 can be found at [0].  Even though approved, 4/4 was
broken so I've reworked it and am now reposting the whole patchset for
convenience.

This patch series addresses the original motivating example:

svfloat32_t foo(float x, float y) {
    return svdupq_n_f32(x, y, x, y);
}

which is currently compiled to:

foo:
        dup     v0.4s, v0.s[0]
        ins     v0.s[1], v1.s[0]
        ins     v0.s[3], v1.s[0]
        dup     z0.q, z0.q[0]
        ret

instead of something like:

foo:
        uzp1    v0.2s, v0.2s, v1.2s
        dup     z0.d, d0
        ret

Since the same inefficiency exists when initializing AdvSIMD registers,
the first three patches tackle that first.  Ideally, we want to detect a
repeating subsequence in the constructor element list, then instantiate
that intermediate quantity, and then use vec_duplicate to fill out the
entire target register.  Since vec_duplicate requires the same inner mode for
both source and target modes, for full flexibility we first need to define
missing sub-word vector modes and add some supporting code, which is done
in patch 1.

Patch 2 adds necessary vec_duplicate patterns and implements the starting
subsequence detection logic to aarch64_vector_init_fallback ().  Patch 3
further improves codegen by implementing vec_concat patterns for the new
modes.  Some costing hooks are adjusted throughout to nudge
aarch64_vector_init () into choosing a better sequence.

The final patch extends this logic to SVE registers.  Currently, we can only
duplicate 128-bit quantities into a full SVE register, which leads to
always having the last "dup" instruction with Q operands, as in the
example above.  As long as we already have the smaller quantity available,
we can use a smaller "dup" to fill the entire register, which is achieved
by combining two vec_duplicates into a new insn.

Changes since v1[0]:
        - In patch 1, drop the changes to
          aarch64_ira_change_pseudo_allocno_class ().
        - In patch 1, add the aarch64_advsimd_sub_dword_mode_p () helper
          and use it instead of aarch64_classify_mode () / GET_MODE_SIZE ().
        - In patch 1, classify partial AdvSIMD modes as VEC_ADVSIMD rather
          than VEC_ADVSIMD | VEC_PARTIAL.
        - In patch 2, rewrite the new *aarch64_simd_dup_subvector patterns
          to use 1 iterator instead of 3 to produce only valid RTL; this
          required extending / creating new iterators and attributes.
        - In patch 2, add a Utv alternative to the @aarch64_simd_vec_set
          pattern for VSUB64 modes.
        - In patch 2, drop the aarch64_choose_vector_init_constant () hunk.
        - In patch 3, use specific mode class checks rather than
          !VOIDmode.
        - In patch 4, similarly to patch 2, add necessary mode attributes
          and use them to restrict the *aarch64_vec_duplicate_subvector
          pattern to valid mode combinations.
        - Readjust expected test output throughout the series.
        - Rebase the series onto trunk.

Each individual patch bootstrapped and regtested on aarch64-linux-gnu.

Thanks,
Artemiy

[0] https://gcc.gnu.org/pipermail/gcc-patches/2026-April/714889.html

Artemiy Volkov (4):
  aarch64: introduce partial AdvSIMD vector modes
  aarch64: initialize vectors from starting subsequence
  aarch64: implement vec_concat support for sub-64-bit types
  aarch64/sve: combine AdvSIMD and SVE vec_duplicates

 gcc/config/aarch64/aarch64-modes.def          |   4 +-
 gcc/config/aarch64/aarch64-protos.h           |   1 +
 gcc/config/aarch64/aarch64-simd.md            | 229 +++++++++-
 gcc/config/aarch64/aarch64-sve.md             |  14 +
 gcc/config/aarch64/aarch64.cc                 |  82 +++-
 gcc/config/aarch64/constraints.md             |   5 +
 gcc/config/aarch64/iterators.md               | 183 +++++++-
 .../complex/bb-slp-complex-add-half-float.c   |   2 +
 .../complex/bb-slp-complex-mla-half-float.c   |   4 +-
 .../complex/bb-slp-complex-mul-half-float.c   |   6 +-
 gcc/testsuite/gcc.target/aarch64/ldp_stp_16.c |   5 +-
 .../gcc.target/aarch64/sve/gather_load_10.c   |   3 +-
 gcc/testsuite/gcc.target/aarch64/sve/slp_1.c  |  10 +-
 .../gcc.target/aarch64/sve/vec_init_5.c       | 382 ++++++++++++++++
 .../gcc.target/aarch64/vec-init-18.c          |   6 +-
 .../gcc.target/aarch64/vec-init-23.c          | 426 ++++++++++++++++++
 .../aarch64/vec-init-single-const.c           |   4 +-
 17 files changed, 1324 insertions(+), 42 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/vec_init_5.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vec-init-23.c

-- 
2.43.0

Reply via email to