Hi Iain,
On 6/28/19 1:56 PM, Iain Apreotesei wrote:
gcc/ChangeLog:
2019-06-28 Iain Apreotesei <iain.apreote...@arm.com>
* config/arm/iterators.md (VRHADD, VHADD): Add, update int_iterators.
(u) new int_attr.
* config/arm/neon.md (<u>avg<mode>3_floor, <u>avg<mode>3_ceil)
(neon_vhadd<sup><mode>, neon_vrhadd<sup><mode>): Add new patterns.
gcc/testsuite/ChangeLog:
2019-06-28 Iain Apreotesei <iain.apreote...@arm.com>
* gcc.target/arm/vect_vhadd_1.c: New test.
* gcc.target/arm/vect_vhadd_1.h: New test.
* gcc.target/arm/vect_vrhadd_1.c: New test.
Thanks for the patch.
Change-Id: Ief4009984ca9974993530b582bd9ba431e42c3ed
---
gcc/config/arm/iterators.md | 9 +++++--
gcc/config/arm/neon.md | 32
+++++++++++++++++++++---
gcc/testsuite/gcc.target/arm/vect_vhadd_1.c | 22 +++++++++++++++++
gcc/testsuite/gcc.target/arm/vect_vhadd_1.h | 37
++++++++++++++++++++++++++++
gcc/testsuite/gcc.target/arm/vect_vrhadd_1.c | 22 +++++++++++++++++
5 files changed, 117 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/arm/vect_vhadd_1.c
create mode 100644 gcc/testsuite/gcc.target/arm/vect_vhadd_1.h
create mode 100644 gcc/testsuite/gcc.target/arm/vect_vrhadd_1.c
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index c33e572..43ecc60 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -308,8 +308,8 @@
(define_int_iterator VADDW [UNSPEC_VADDW_S UNSPEC_VADDW_U])
-(define_int_iterator VHADD [UNSPEC_VRHADD_S UNSPEC_VRHADD_U
- UNSPEC_VHADD_S UNSPEC_VHADD_U])
+(define_int_iterator VHADD[UNSPEC_VHADD_S UNSPEC_VHADD_U])
+(define_int_iterator VRHADD[UNSPEC_VRHADD_S UNSPEC_VRHADD_U])
(define_int_iterator VQADD [UNSPEC_VQADD_S UNSPEC_VQADD_U])
@@ -818,6 +818,11 @@
;; Mapping between vector UNSPEC operations and the signed ('s'),
;; unsigned ('u'), poly ('p') or float ('f') nature of their data type.
+
+(define_int_attr u[
+ (UNSPEC_VHADD_S "") (UNSPEC_VHADD_U "u")
+ (UNSPEC_VRHADD_S "") (UNSPEC_VRHADD_U "u")])
+
(define_int_attr sup [
(UNSPEC_VADDL_S "s") (UNSPEC_VADDL_U "u")
(UNSPEC_VADDW_S "s") (UNSPEC_VADDW_U "u")
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index f9d7ba3..1127bdb 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -2179,15 +2179,41 @@
[(set_attr "type" "neon_add_widen")]
)
+(define_expand "<u>avg<mode>3_floor"
+ [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
+ (unspec:VDQIW[(match_operand:VDQIW 1 "s_register_operand" "w")
+ (match_operand:VDQIW 2 "s_register_operand" "w")]
+ VHADD))]
+ "TARGET_NEON"
+)
+
+(define_expand "<u>avg<mode>3_ceil"
+ [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
+ (unspec:VDQIW[(match_operand:VDQIW 1 "s_register_operand" "w")
+ (match_operand:VDQIW 2 "s_register_operand" "w")]
+ VRHADD))]
+ "TARGET_NEON"
+)
+
; vhadd and vrhadd.
-(define_insn "neon_v<r>hadd<sup><mode>"
+(define_insn "neon_vhadd<sup><mode>"
[(set (match_operand:VDQIW 0 "s_register_operand" "=w")
- (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
+ (unspec:VDQIW[(match_operand:VDQIW 1 "s_register_operand" "w")
(match_operand:VDQIW 2 "s_register_operand" "w")]
VHADD))]
"TARGET_NEON"
- "v<r>hadd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+ "vhadd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+ [(set_attr "type" "neon_add_halve_q")]
+)
+
+(define_insn "neon_vrhadd<sup><mode>"
+ [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
+ (unspec:VDQIW[(match_operand:VDQIW 1 "s_register_operand" "w")
+ (match_operand:VDQIW 2 "s_register_operand" "w")]
+ VRHADD))]
+ "TARGET_NEON"
+ "vrhadd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
[(set_attr "type" "neon_add_halve_q")]
)
Why are you splitting the neon_v<r>hadd<sup><mode> pattern here?
It seems to me that just defining the expanders is enough to get the
codegen we want?
Thanks,
Kyrill
diff --git a/gcc/testsuite/gcc.target/arm/vect_vhadd_1.c
b/gcc/testsuite/gcc.target/arm/vect_vhadd_1.c
new file mode 100644
index 0000000..946171c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/vect_vhadd_1.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+/* { dg-add-options arm_neon } */
+
+#include "vect_vhadd_1.h"
+
+#define BIAS 0
+
+FOR_EACH_SIGNED_TYPE (DEF_FUNC)
+
+int
+main (void)
+{
+ FOR_EACH_SIGNED_TYPE (TEST_FUNC);
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\tvhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler {\tvhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler {\tvhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler-not {\tvrhadd\.s[0-9]+} } } */
diff --git a/gcc/testsuite/gcc.target/arm/vect_vhadd_1.h
b/gcc/testsuite/gcc.target/arm/vect_vhadd_1.h
new file mode 100644
index 0000000..e093b42
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/vect_vhadd_1.h
@@ -0,0 +1,37 @@
+#include <stdint.h>
+
+#define N 100
+
+#define DEF_FUNC(TYPE, B1, B2, C1, C2)\
+void __attribute__ ((noipa)) \
+f_##TYPE (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c)\
+{ \
+ for (int i = 0; i < N; ++i) \
+ a[i] = (b[i] + c[i] + BIAS) >> 1;\
+}
+
+#define TEST_FUNC(TYPE, B1, B2, C1, C2)\
+{ \
+ TYPE a[N], b[N], c[N]; \
+ for (TYPE i = 0; i < N; ++i)\
+ { \
+ b[i] = B1 + i * B2; \
+ c[i] = C1 + i * C2; \
+ } \
+ f_##TYPE (a, b, c); \
+ for (TYPE i = 0; i < N; ++i)\
+ if (a[i] != ((B1 + C1 + BIAS + i * (B2 + C2)) >> 1)) \
+ __builtin_abort (); \
+}
+
+#define FOR_EACH_SIGNED_TYPE(T) \
+ T (int8_t, -124, 2, -40, 1) \
+ T (int16_t, -32000, 510, -10000, 257) \
+ T (int32_t, -2000000000, 131072, -3277000, 65537) \
+ T (int64_t, -44, 100, -10000, 99)
+
+#define FOR_EACH_UNSIGNED_TYPE(T) \
+ T (uint8_t, 4, 2, 40, 1) \
+ T (uint16_t, 12, 510, 10000, 257) \
+ T (uint32_t, 20, 131072, 3277000, 65537) \
+ T (uint64_t, 90, 100, 10000, 99)
diff --git a/gcc/testsuite/gcc.target/arm/vect_vrhadd_1.c
b/gcc/testsuite/gcc.target/arm/vect_vrhadd_1.c
new file mode 100644
index 0000000..f6d67c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/vect_vrhadd_1.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+/* { dg-add-options arm_neon } */
+
+#include "vect_vhadd_1.h"
+
+#define BIAS 1
+
+FOR_EACH_SIGNED_TYPE (DEF_FUNC)
+
+int
+main (void)
+{
+ FOR_EACH_SIGNED_TYPE (TEST_FUNC);
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\tvrhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler {\tvrhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler {\tvrhadd\.s[0-9]+} } } */
+/* { dg-final { scan-assembler-not {\tvhadd\.s[0-9]+} } } */
--
1.8.3