> -----Original Message-----
> From: Alfie Richards <[email protected]>
> Sent: 03 July 2026 16:41
> To: [email protected]
> Cc: Alfie Richards <[email protected]>; Alex Coplan
> <[email protected]>; Alice Carlotti <[email protected]>;
> [email protected]; [email protected]; Richard Earnshaw
> <[email protected]>; Tamar Christina <[email protected]>;
> Wilco Dijkstra <[email protected]>
> Subject: [PATCH] aarch64: Add optimization for ADD (ABS (A), B) intrinsics
> 
> Hi all,
> 
> Small patch for an intrinsics optimization.
> 
> Boostrapped and regr tested on aarch64-linux-gnu
> 
> KR,
> 
> Alfie
> 
> -- >8 --
> 
> gcc/ChangeLog:
> 
>       * config/aarch64/aarch64-simd.md (*aarch64_abs_plus<mode>):
> New
>       define_insn_and_split.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.target/aarch64/add_abs.c: New test.
> ---
>  gcc/config/aarch64/aarch64-simd.md         |  20 ++++
>  gcc/testsuite/gcc.target/aarch64/add_abs.c | 129
> +++++++++++++++++++++
>  2 files changed, 149 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/add_abs.c
> 
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index 94fb49a338b..733860d7854 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -1252,6 +1252,26 @@ (define_insn
> "aarch64_<su>aba<mode><vczle><vczbe>"
>    [(set_attr "type" "neon_arith_acc<q>")]
>  )
> 
> +;; C = ADD (ABS (A), B) -> C = ABA (A, B, 0)
> +(define_insn_and_split "*aarch64_abs_plus<mode>"
> +  [(set (match_operand:VDQ_BHSI 0 "register_operand" "=&w")
> +     (plus:VDQ_BHSI
> +       (unspec:VDQ_BHSI
> +         [(match_operand:VDQ_BHSI 1 "register_operand" "w")]
> +         UNSPEC_ABS)
> +       (match_operand:VDQ_BHSI 2 "register_operand" "w")))]
> +  "TARGET_SIMD && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +  {
> +    rtx zero = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));

Use aarch64_gen_shareable_zero here.

OK with that change.

Thanks,
Tamar

> +    emit_insn (gen_aarch64_saba<mode> (operands[0], operands[2],
> +                                    operands[1], zero));
> +    DONE;
> +  }
> +)
> +
>  (define_insn "fabd<mode>3<vczle><vczbe>"
>    [(set (match_operand:VHSDF_HSDF 0 "register_operand" "=w")
>       (abs:VHSDF_HSDF
> diff --git a/gcc/testsuite/gcc.target/aarch64/add_abs.c
> b/gcc/testsuite/gcc.target/aarch64/add_abs.c
> new file mode 100644
> index 00000000000..70c62a51bb7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/add_abs.c
> @@ -0,0 +1,129 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O2 -fno-schedule-insns -fno-schedule-insns2" }
> */
> +/* { dg-final { check-function-bodies "**" "" {} } } */
> +#include <arm_neon.h>
> +
> +/*
> +** add_abs_q_s32:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v0.4s, v1.4s, v[0-9]+.4s
> +**   ret
> +*/
> +int32x4_t add_abs_q_s32 (int32x4_t a, int32x4_t b) {
> +  return vaddq_s32( a, vabsq_s32( b ) );
> +}
> +
> +/*
> +** add_abs_q_s16:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v0.8h, v1.8h, v[0-9]+.8h
> +**   ret
> +*/
> +int16x8_t add_abs_q_s16 (int16x8_t a, int16x8_t b) {
> +  return vaddq_s16( a, vabsq_s16( b ) );
> +}
> +
> +/*
> +** add_abs_q_s8:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v0.16b, v1.16b, v[0-9]+.16b
> +**   ret
> +*/
> +int8x16_t add_abs_q_s8 (int8x16_t a, int8x16_t b) {
> +  return vaddq_s8( a, vabsq_s8( b ) );
> +}
> +
> +/*
> +** add_abs_s32:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v0.2s, v1.2s, v[0-9]+.2s
> +**   ret
> +*/
> +int32x2_t add_abs_s32 (int32x2_t a, int32x2_t b) {
> +  return vadd_s32( a, vabs_s32( b ) );
> +}
> +
> +/*
> +** add_abs_s16:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v0.4h, v1.4h, v[0-9]+.4h
> +**   ret
> +*/
> +int16x4_t add_abs_s16 (int16x4_t a, int16x4_t b) {
> +  return vadd_s16( a, vabs_s16( b ) );
> +}
> +
> +/*
> +** add_abs_s8:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v0.8b, v1.8b, v[0-9]+.8b
> +**   ret
> +*/
> +int8x8_t add_abs_s8 (int8x8_t a, int8x8_t b) {
> +  return vadd_s8( a, vabs_s8( b ) );
> +}
> +/*
> +** abs_add_q_s32:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v1.4s, v0.4s, v[0-9]+.4s
> +**   mov     v0.16b, v1.16b
> +**   ret
> +*/
> +int32x4_t abs_add_q_s32 (int32x4_t a, int32x4_t b) {
> +  return vaddq_s32( b, vabsq_s32( a ) );
> +}
> +
> +/*
> +** abs_add_q_s16:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v1.8h, v0.8h, v[0-9]+.8h
> +**   mov     v0.16b, v1.16b
> +**   ret
> +*/
> +int16x8_t abs_add_q_s16 (int16x8_t a, int16x8_t b) {
> +  return vaddq_s16( b, vabsq_s16( a ) );
> +}
> +
> +/*
> +** abs_add_q_s8:
> +**   movi    v[0-9]+.4s, 0
> +**   saba    v1.16b, v0.16b, v[0-9]+.16b
> +**   mov     v0.16b, v1.16b
> +**   ret
> +*/
> +int8x16_t abs_add_q_s8 (int8x16_t a, int8x16_t b) {
> +  return vaddq_s8( b, vabsq_s8( a ) );
> +}
> +
> +/*
> +** abs_add_s32:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v1.2s, v0.2s, v[0-9]+.2s
> +**   mov     v0.8b, v1.8b
> +**   ret
> +*/
> +int32x2_t abs_add_s32 (int32x2_t a, int32x2_t b) {
> +  return vadd_s32( b, vabs_s32( a ) );
> +}
> +
> +/*
> +** abs_add_s16:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v1.4h, v0.4h, v[0-9]+.4h
> +**   mov     v0.8b, v1.8b
> +**   ret
> +*/
> +int16x4_t abs_add_s16 (int16x4_t a, int16x4_t b) {
> +  return vadd_s16( b, vabs_s16( a ) );
> +}
> +
> +/*
> +** abs_add_s8:
> +**   movi    v[0-9]+.2s, 0
> +**   saba    v1.8b, v0.8b, v[0-9]+.8b
> +**   mov     v0.8b, v1.8b
> +**   ret
> +*/
> +int8x8_t abs_add_s8 (int8x8_t a, int8x8_t b) {
> +  return vadd_s8( b, vabs_s8( a ) );
> +}
> --
> 2.34.1

Reply via email to