[AArch64] Add SVE mul_highpart patterns
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 13 Mar 2018 15:12:14 +0000 (15:12 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 13 Mar 2018 15:12:14 +0000 (15:12 +0000)
One advantage of the new permute handling compared to the old way is
that we can now easily take advantage of the vectoriser's divmod patterns
for SVE.

2018-03-13  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* config/aarch64/iterators.md (UNSPEC_SMUL_HIGHPART)
(UNSPEC_UMUL_HIGHPART): New constants.
(MUL_HIGHPART): New int iteraor.
(su): Handle UNSPEC_SMUL_HIGHPART and UNSPEC_UMUL_HIGHPART.
* config/aarch64/aarch64-sve.md (<su>mul<mode>3_highpart): New
define_expand.
(*<su>mul<mode>3_highpart): New define_insn.

gcc/testsuite/
* gcc.target/aarch64/sve/mul_highpart_1.c: New test.
* gcc.target/aarch64/sve/mul_highpart_1_run.c: Likewise.

From-SVN: r258487

gcc/ChangeLog
gcc/config/aarch64/aarch64-sve.md
gcc/config/aarch64/iterators.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1_run.c [new file with mode: 0644]

index 0937241a0584bf6691f96701dc58d13e559fa7a1..2dbe441db5642a0ef6ed0912ddbbd4148971fb2a 100644 (file)
@@ -1,3 +1,13 @@
+2018-03-13  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * config/aarch64/iterators.md (UNSPEC_SMUL_HIGHPART)
+       (UNSPEC_UMUL_HIGHPART): New constants.
+       (MUL_HIGHPART): New int iteraor.
+       (su): Handle UNSPEC_SMUL_HIGHPART and UNSPEC_UMUL_HIGHPART.
+       * config/aarch64/aarch64-sve.md (<su>mul<mode>3_highpart): New
+       define_expand.
+       (*<su>mul<mode>3_highpart): New define_insn.
+
 2018-03-13  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR lto/84805
index 9140862d7473f88ac2fa6cd3de57e66ee3c7d3f9..2e7f0a45f793081d80e43a68929a07abc3b44117 100644 (file)
    mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
 )
 
+;; Unpredicated highpart multiplication.
+(define_expand "<su>mul<mode>3_highpart"
+  [(set (match_operand:SVE_I 0 "register_operand")
+       (unspec:SVE_I
+         [(match_dup 3)
+          (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
+                         (match_operand:SVE_I 2 "register_operand")]
+                        MUL_HIGHPART)]
+         UNSPEC_MERGE_PTRUE))]
+  "TARGET_SVE"
+  {
+    operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
+  }
+)
+
+;; Predicated highpart multiplication.
+(define_insn "*<su>mul<mode>3_highpart"
+  [(set (match_operand:SVE_I 0 "register_operand" "=w")
+       (unspec:SVE_I
+         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+          (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0")
+                         (match_operand:SVE_I 3 "register_operand" "w")]
+                        MUL_HIGHPART)]
+         UNSPEC_MERGE_PTRUE))]
+  "TARGET_SVE"
+  "<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+)
+
 ;; Unpredicated NEG, NOT and POPCOUNT.
 (define_expand "<optab><mode>2"
   [(set (match_operand:SVE_I 0 "register_operand")
index 9c1c9dabdd9ca50802ffa21efe6d11314f6503d6..a2945a81848b326dcc317c771ca83822bdd64fe5 100644 (file)
     UNSPEC_ANDF                ; Used in aarch64-sve.md.
     UNSPEC_IORF                ; Used in aarch64-sve.md.
     UNSPEC_XORF                ; Used in aarch64-sve.md.
+    UNSPEC_SMUL_HIGHPART ; Used in aarch64-sve.md.
+    UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md.
     UNSPEC_COND_ADD    ; Used in aarch64-sve.md.
     UNSPEC_COND_SUB    ; Used in aarch64-sve.md.
     UNSPEC_COND_SMAX   ; Used in aarch64-sve.md.
 
 (define_int_iterator UNPACK_UNSIGNED [UNSPEC_UNPACKULO UNSPEC_UNPACKUHI])
 
+(define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART])
+
 (define_int_iterator SVE_COND_INT_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB
                                      UNSPEC_COND_SMAX UNSPEC_COND_UMAX
                                      UNSPEC_COND_SMIN UNSPEC_COND_UMIN
 (define_int_attr su [(UNSPEC_UNPACKSHI "s")
                     (UNSPEC_UNPACKUHI "u")
                     (UNSPEC_UNPACKSLO "s")
-                    (UNSPEC_UNPACKULO "u")])
+                    (UNSPEC_UNPACKULO "u")
+                    (UNSPEC_SMUL_HIGHPART "s")
+                    (UNSPEC_UMUL_HIGHPART "u")])
 
 (define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
                      (UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")
index 1f26d4bfaa639075e28f883d423618f07fe36022..1257912b4387ffcfee8e8528ebe29f9934f419d0 100644 (file)
@@ -1,3 +1,8 @@
+2018-03-13  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gcc.target/aarch64/sve/mul_highpart_1.c: New test.
+       * gcc.target/aarch64/sve/mul_highpart_1_run.c: Likewise.
+
 2018-03-13  Martin Liska  <mliska@suse.cz>
 
        PR ipa/84658.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1.c b/gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1.c
new file mode 100644 (file)
index 0000000..4354c1c
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model --save-temps" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE)                         \
+void __attribute__ ((noipa))                   \
+mod_##TYPE (TYPE *dst, TYPE *src, int count)   \
+{                                              \
+  for (int i = 0; i < count; ++i)              \
+    dst[i] = src[i] % 17;                      \
+}
+
+#define TEST_ALL(T) \
+  T (int32_t) \
+  T (uint32_t) \
+  T (int64_t) \
+  T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsmulh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumulh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmulh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumulh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/mul_highpart_1_run.c
new file mode 100644 (file)
index 0000000..4eb173b
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model --save-temps" } */
+
+#include "mul_highpart_1.c"
+
+#define N 79
+
+#define TEST_LOOP(TYPE)                                \
+  {                                            \
+    TYPE dst[N], src[N];                       \
+    for (int i = 0; i < N; ++i)                        \
+      {                                                \
+       src[i] = i * 7 + i % 3;                 \
+       if (i % 11 > 7)                         \
+         src[i] = -src[i];                     \
+       asm volatile ("" ::: "memory");         \
+      }                                                \
+    mod_##TYPE (dst, src, N);                  \
+    for (int i = 0; i < N; ++i)                        \
+      if (dst[i] != src[i] % 17)               \
+       __builtin_abort ();                     \
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP);
+  return 0;
+}