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