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));
+    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