https://gcc.gnu.org/g:ee27c516c7b6f0ee364b165aed0c35101da8e77a
commit r17-2353-gee27c516c7b6f0ee364b165aed0c35101da8e77a Author: Dylan Rees <[email protected]> Date: Mon Jul 13 09:57:17 2026 +0000 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. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 16 +++++++++++++++- .../gcc.target/aarch64/simd/fold_to_highpart_7.c | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 4622b42afa68..60a57839ff5e 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -4904,9 +4904,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; @@ -4935,6 +4937,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; } @@ -4965,6 +4969,16 @@ 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]); + tree vec_dup = gimple_build_vector_from_val (gsi, true, + GSI_SAME_STMT, loc, + call_types[i], elt); + 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 000000000000..d945566b0431 --- /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); +}
