[17/n] PR85694: AArch64 support for AVG_FLOOR/CEIL
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 3 Jul 2018 14:27:28 +0000 (14:27 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 3 Jul 2018 14:27:28 +0000 (14:27 +0000)
This patch adds AArch64 patterns for the new AVG_FLOOR/CEIL operations.
AVG_FLOOR is [SU]HADD and AVG_CEIL is [SU]RHADD.

2018-07-03  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR tree-optimization/85694
* config/aarch64/iterators.md (HADD, RHADD): New int iterators.
(u): Handle UNSPEC_SHADD, UNSPEC_UHADD, UNSPEC_SRHADD and
UNSPEC_URHADD.
* config/aarch64/aarch64-simd.md (<u>avg<mode>3_floor)
(<u>avg<mode>3_ceil): New patterns.

gcc/testsuite/
PR tree-optimization/85694
* lib/target-supports.exp (check_effective_target_vect_avg_qi):
Return true for AArch64 without SVE.
* gcc.target/aarch64/vect_hadd_1.h: New file.
* gcc.target/aarch64/vect_shadd_1.c: New test.
* gcc.target/aarch64/vect_srhadd_1.c: Likewise.
* gcc.target/aarch64/vect_uhadd_1.c: Likewise.
* gcc.target/aarch64/vect_urhadd_1.c: Likewise.

From-SVN: r262347

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/iterators.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/vect_hadd_1.h [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vect_shadd_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vect_srhadd_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vect_uhadd_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vect_urhadd_1.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index 511c9a657b02ddbc4cc4f1ec35735c2cb01dd9d2..4c550b6f3e415d919381f653626439ad684b1b70 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-03  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/85694
+       * config/aarch64/iterators.md (HADD, RHADD): New int iterators.
+       (u): Handle UNSPEC_SHADD, UNSPEC_UHADD, UNSPEC_SRHADD and
+       UNSPEC_URHADD.
+       * config/aarch64/aarch64-simd.md (<u>avg<mode>3_floor)
+       (<u>avg<mode>3_ceil): New patterns.
+
 2018-07-03  David Malcolm  <dmalcolm@redhat.com>
 
        * gcc.dg/vect/slp-perm-1.c: Remove "note: " prefix from
index 315c8dc4b85a849b2ec8d0bc0befbacda8fc0da3..89e38e65a76d75d13812fbfab49b77e2e04eeb20 100644 (file)
 
 ;; <su><r>h<addsub>.
 
+(define_expand "<u>avg<mode>3_floor"
+  [(set (match_operand:VDQ_BHSI 0 "register_operand")
+       (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")
+                         (match_operand:VDQ_BHSI 2 "register_operand")]
+                        HADD))]
+  "TARGET_SIMD"
+)
+
+(define_expand "<u>avg<mode>3_ceil"
+  [(set (match_operand:VDQ_BHSI 0 "register_operand")
+       (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")
+                         (match_operand:VDQ_BHSI 2 "register_operand")]
+                        RHADD))]
+  "TARGET_SIMD"
+)
+
 (define_insn "aarch64_<sur>h<addsub><mode>"
   [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
         (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand" "w")
index 965dc6bf4f3472a0865fb165b80783b4d6cd29c2..949fd2aa09d96a9b6594132410ce9741a9449328 100644 (file)
                              UNSPEC_SHSUB UNSPEC_UHSUB
                              UNSPEC_SRHSUB UNSPEC_URHSUB])
 
+(define_int_iterator HADD [UNSPEC_SHADD UNSPEC_UHADD])
+
+(define_int_iterator RHADD [UNSPEC_SRHADD UNSPEC_URHADD])
+
 (define_int_iterator DOTPROD [UNSPEC_SDOT UNSPEC_UDOT])
 
 (define_int_iterator ADDSUBHN [UNSPEC_ADDHN UNSPEC_RADDHN
 
 (define_int_attr u [(UNSPEC_SQSHLU "u") (UNSPEC_SQSHL "") (UNSPEC_UQSHL "")
                    (UNSPEC_SQSHRUN "u") (UNSPEC_SQRSHRUN "u")
-                    (UNSPEC_SQSHRN "")  (UNSPEC_UQSHRN "")
-                    (UNSPEC_SQRSHRN "") (UNSPEC_UQRSHRN "")])
+                   (UNSPEC_SQSHRN "")  (UNSPEC_UQSHRN "")
+                   (UNSPEC_SQRSHRN "") (UNSPEC_UQRSHRN "")
+                   (UNSPEC_SHADD "") (UNSPEC_UHADD "u")
+                   (UNSPEC_SRHADD "") (UNSPEC_URHADD "u")])
 
 (define_int_attr addsub [(UNSPEC_SHADD "add")
                         (UNSPEC_UHADD "add")
index a201b7e0251e9532f62a2ab387866c50b9712fda..333096287be835a71934fb23d8c7ca83b613c60e 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-03  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/85694
+       * lib/target-supports.exp (check_effective_target_vect_avg_qi):
+       Return true for AArch64 without SVE.
+       * gcc.target/aarch64/vect_hadd_1.h: New file.
+       * gcc.target/aarch64/vect_shadd_1.c: New test.
+       * gcc.target/aarch64/vect_srhadd_1.c: Likewise.
+       * gcc.target/aarch64/vect_uhadd_1.c: Likewise.
+       * gcc.target/aarch64/vect_urhadd_1.c: Likewise.
+
 2018-07-03  Marek Polacek  <polacek@redhat.com>
 
        PR middle-end/86202
diff --git a/gcc/testsuite/gcc.target/aarch64/vect_hadd_1.h b/gcc/testsuite/gcc.target/aarch64/vect_hadd_1.h
new file mode 100644 (file)
index 0000000..ab25a5d
--- /dev/null
@@ -0,0 +1,39 @@
+#include <stdint.h>
+
+#pragma GCC target "+nosve"
+
+#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] = ((__int128) 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 + (__int128) 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/aarch64/vect_shadd_1.c b/gcc/testsuite/gcc.target/aarch64/vect_shadd_1.c
new file mode 100644 (file)
index 0000000..4f1e2f9
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+
+#include "vect_hadd_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 {\tshadd\tv[0-9]+\.16b,} } } */
+/* { dg-final { scan-assembler {\tshadd\tv[0-9]+\.8h,} } } */
+/* { dg-final { scan-assembler {\tshadd\tv[0-9]+\.4s,} } } */
+/* { dg-final { scan-assembler-not {\tshadd\tv[0-9]+\.2d,} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect_srhadd_1.c b/gcc/testsuite/gcc.target/aarch64/vect_srhadd_1.c
new file mode 100644 (file)
index 0000000..3110a40
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+
+#include "vect_hadd_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 {\tsrhadd\tv[0-9]+\.16b,} } } */
+/* { dg-final { scan-assembler {\tsrhadd\tv[0-9]+\.8h,} } } */
+/* { dg-final { scan-assembler {\tsrhadd\tv[0-9]+\.4s,} } } */
+/* { dg-final { scan-assembler-not {\tsrhadd\tv[0-9]+\.2d,} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect_uhadd_1.c b/gcc/testsuite/gcc.target/aarch64/vect_uhadd_1.c
new file mode 100644 (file)
index 0000000..529c86a
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+
+#include "vect_hadd_1.h"
+
+#define BIAS 0
+
+FOR_EACH_UNSIGNED_TYPE (DEF_FUNC)
+
+int
+main (void)
+{
+  FOR_EACH_UNSIGNED_TYPE (TEST_FUNC);
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\tuhadd\tv[0-9]+\.16b,} } } */
+/* { dg-final { scan-assembler {\tuhadd\tv[0-9]+\.8h,} } } */
+/* { dg-final { scan-assembler {\tuhadd\tv[0-9]+\.4s,} } } */
+/* { dg-final { scan-assembler-not {\tuhadd\tv[0-9]+\.2d,} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect_urhadd_1.c b/gcc/testsuite/gcc.target/aarch64/vect_urhadd_1.c
new file mode 100644 (file)
index 0000000..47f1393
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -ftree-vectorize" } */
+
+#include "vect_hadd_1.h"
+
+#define BIAS 1
+
+FOR_EACH_UNSIGNED_TYPE (DEF_FUNC)
+
+int
+main (void)
+{
+  FOR_EACH_UNSIGNED_TYPE (TEST_FUNC);
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\turhadd\tv[0-9]+\.16b,} } } */
+/* { dg-final { scan-assembler {\turhadd\tv[0-9]+\.8h,} } } */
+/* { dg-final { scan-assembler {\turhadd\tv[0-9]+\.4s,} } } */
+/* { dg-final { scan-assembler-not {\turhadd\tv[0-9]+\.2d,} } } */
index fc189f31b71db56062ac70c200c4cd45b4aa47a7..99613fd26bd47dc5caf12d1938249acadeaf0035 100644 (file)
@@ -6317,7 +6317,8 @@ proc check_effective_target_vect_usad_char { } {
 # and unsigned average operations on vectors of bytes.
 
 proc check_effective_target_vect_avg_qi {} {
-    return 0
+    return [expr { [istarget aarch64*-*-*]
+                  && ![check_effective_target_aarch64_sve] }]
 }
 
 # Return 1 if the target plus current options supports a vector