https://gcc.gnu.org/g:931cc97b0ab4690a16ab179af039fef814557e16
commit r17-2195-g931cc97b0ab4690a16ab179af039fef814557e16 Author: Alfie Richards <[email protected]> Date: Fri Jul 3 14:51:55 2026 +0000 aarch64: Add optimization for ADD (ABS (A), B) intrinsics 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. Diff: --- gcc/config/aarch64/aarch64-simd.md | 20 +++++ gcc/testsuite/gcc.target/aarch64/add_abs.c | 129 +++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 23a8a47263ae..ce51e24da36a 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1252,6 +1252,26 @@ [(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 = aarch64_gen_shareable_zero (<MODE>mode); + 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 000000000000..5d8aa0325e44 --- /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]+.4s, 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]+.4s, 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]+.4s, 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]+.4s, 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]+.4s, 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]+.4s, 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 ) ); +}
