> -----Original Message-----
> From: Dylan Rees <[email protected]>
> Sent: 08 June 2026 17:34
> To: [email protected]
> Cc: Dylan Rees <[email protected]>; [email protected];
> [email protected]; [email protected]; Tamar Christina
> <[email protected]>
> Subject: [PATCH v2 1/2] aarch64: Improve simd highpart builtin folding
> 
> 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         | 22 +++++++++++++++++++
>  2 files changed, 38 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 b9cc2bf404f..b547ddf29ee 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;
> +    }

There's a gimple_build_vector_from_val overload that takes a gsi directly,
use that instead since you're only emitting one statement at a time anyway.

OK with that change.

Thanks,
Tamar

> +
>    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..d945566b043
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_7.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O3" } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#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.  */
> +
> +/*
> +** foo:
> +**   ...
> +**   umull2  v([0-9]+).8h, v([0-9]+).16b, v([0-9]+).16b
> +**   ...
> +*/
> +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);
> +}
> --
> 2.43.0

Reply via email to