From: Dylan Rees Date: Mon, 13 Jul 2026 09:57:17 +0000 (+0000) Subject: aarch64: Improve simd highpart builtin folding X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee27c516c7b6f0ee364b165aed0c35101da8e77a;p=thirdparty%2Fgcc.git 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 --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 4622b42afa6..60a57839ff5 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 vec_constants; auto_vec vec_highparts; + auto_vec vec_uniforms; /* The arguments and signature of the new call. */ auto_vec call_args; auto_vec 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 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 + +/* 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); +}