> -----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