On Mon, Jun 1, 2026 at 7:35 AM Dylan Rees <[email protected]> wrote: > > The current helper function folding calls to lowpart builtins into > highpart builtins calls does not handle cases where we have a 64b > wide uniform vector, which can be extended to 128b, used for > high part operations requiring 128b vector inputs. This change > adds an additional check on the statement arguments and widens > uniform vectors before adding to the 'call_args' of the new call > to the equivalent highpart builtin. Relevant function comments were > also updated. > > gcc/ChangeLog: > > * config/aarch64/aarch64-builtins.cc (aarch64_fold_lo_call_to_hi): > New branch to check for uniform vectors, extend and then add > them to the new highpart builtin call. > > gcc/testsuite/ChangeLog: > > * gcc.target/aarch64/simd/fold_to_highpart_7.c: New test. > --- > gcc/config/aarch64/aarch64-builtins.cc | 17 ++++++++++++++++- > .../aarch64/simd/fold_to_highpart_7.c | 18 ++++++++++++++++++ > 2 files changed, 34 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_7.c > > diff --git a/gcc/config/aarch64/aarch64-builtins.cc > b/gcc/config/aarch64/aarch64-builtins.cc > index 611f6dc45e0..cc93cf00638 100644 > --- a/gcc/config/aarch64/aarch64-builtins.cc > +++ b/gcc/config/aarch64/aarch64-builtins.cc > @@ -5306,9 +5306,11 @@ aarch64_fold_lo_call_to_hi (unsigned int fcode, gcall > *stmt, > > /* Prefer to use the highpart builtin when at least one vector > argument is a reference to the high half of a 128b vector, and > - all others are VECTOR_CSTs that we can extend to 128b. */ > + all others are VECTOR_CSTs or uniform vectors that we can extend > + to 128b. */ > auto_vec<unsigned int, 2> vec_constants; > auto_vec<unsigned int, 2> vec_highparts; > + auto_vec<unsigned int, 2> vec_uniforms; > /* The arguments and signature of the new call. */ > auto_vec<tree, 4> call_args; > auto_vec<tree, 4> call_types; > @@ -5337,6 +5339,8 @@ aarch64_fold_lo_call_to_hi (unsigned int fcode, gcall > *stmt, > } > else if (TREE_CODE (arg) == VECTOR_CST) > vec_constants.safe_push (argno); > + else if (ssa_uniform_vector_p (arg)) > + vec_uniforms.safe_push (argno); > else > return nullptr; > } > @@ -5367,6 +5371,17 @@ aarch64_fold_lo_call_to_hi (unsigned int fcode, gcall > *stmt, > call_args[i] = vce_ssa; > } > > + location_t loc = gimple_location (stmt); > + for (auto i : vec_uniforms) > + { > + tree elt = ssa_uniform_vector_p (call_args[i]); > + gimple_seq seq = NULL; > + tree vec_dup = gimple_build_vector_from_val (&seq, loc, call_types[i], > + elt); > + gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT); > + call_args[i] = vec_dup; > + } > + > gcall *new_call = gimple_build_call_vec (builtin_hi, call_args); > gimple_call_set_lhs (new_call, gimple_call_lhs (stmt)); > return new_call; > diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_7.c > b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_7.c > new file mode 100644 > index 00000000000..941dab3e9b9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_7.c > @@ -0,0 +1,18 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O3" } */ > + > +#include <arm_neon.h> > + > +/* We should fold to the highpart builtin when the multiplying the highpart > of a > + 128b vector with a uniform vector which can be widened. > + > + Use vdup_n_u8 to create an 8x8 splat vector. */ > + > +uint16x8_t foo(uint8_t *a, uint8_t *b) { > + const uint8x8_t uniform_vec = vdup_n_u8(*a); > + const uint8x16_t hipart_vec = vld1q_u8(b); > + return vmull_u8(vget_high_u8(hipart_vec), uniform_vec); > +} > + > +/* { dg-final { scan-assembler {mull2\t} } } */ > +/* { dg-final { scan-assembler-not {mull\t} } } */ > \ No newline at end of file
Make sure all files have a newline at the end of the file. Can you use check-function-bodies here? I am think I understand what the code should look like and why scan for mull2 but I want to make sure the correct operands happen for the mull2. Otherwise ok. Thanks, Andrea > -- > 2.43.0 >
