[aarch64]: add usra and ssra combine patterns
authorSylvia Taylor <sylvia.taylor@arm.com>
Mon, 22 Jul 2019 16:21:17 +0000 (16:21 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Mon, 22 Jul 2019 16:21:17 +0000 (16:21 +0000)
This patch adds support to combine:

1) ushr and add into usra, example:

ushr    v0.16b, v0.16b, 2
add     v0.16b, v0.16b, v2.16b
---
usra    v2.16b, v0.16b, 2

2) sshr and add into ssra, example:

sshr    v1.16b, v1.16b, 2
add     v1.16b, v1.16b, v3.16b
---
ssra    v3.16b, v1.16b, 2

Committed on behalf of Sylvia Taylor <sylvia.taylor@arm.com>.
Reviewed-by: <James.greenhalgh@arm.com>
gcc/ChangeLog:

        * config/aarch64/aarch64-simd.md
        (*aarch64_simd_sra<mode>): New.
        * config/aarch64/iterators.md
        (SHIFTRT): New iterator.
        (sra_op): New attribute.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/simd/ssra.c: New test.
        * gcc.target/aarch64/simd/usra.c: New test.

From-SVN: r273703

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/iterators.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/simd/ssra.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/simd/usra.c [new file with mode: 0644]

index 687ae89cdc815a1dc234d64e7357527bde227ed0..faa3bde229565bf7a83e6cf902166619cac1c6ce 100644 (file)
@@ -1,3 +1,11 @@
+2019-07-22  Sylvia Taylor  <sylvia.taylor@arm.com>
+
+       * config/aarch64/aarch64-simd.md
+       (*aarch64_simd_sra<mode>): New.
+       * config/aarch64/iterators.md
+       (SHIFTRT): New iterator.
+       (sra_op): New attribute.
+
 2019-07-22  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        * config/msp430/msp430.c (msp430_preserve_reg_p): Don't save
index d480e430f251d6c948085a8c0571c3e3ac47ac75..c6ccc99a2aa673102dc756cb7b5de1f859390240 100644 (file)
   [(set_attr "type" "neon_shift_imm<q>")]
 )
 
+(define_insn "*aarch64_simd_sra<mode>"
+ [(set (match_operand:VDQ_I 0 "register_operand" "=w")
+       (plus:VDQ_I
+          (SHIFTRT:VDQ_I
+               (match_operand:VDQ_I 1 "register_operand" "w")
+               (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr"))
+          (match_operand:VDQ_I 3 "register_operand" "0")))]
+  "TARGET_SIMD"
+  "<sra_op>sra\t%0.<Vtype>, %1.<Vtype>, %2"
+  [(set_attr "type" "neon_shift_acc<q>")]
+)
+
 (define_insn "aarch64_simd_imm_shl<mode>"
  [(set (match_operand:VDQ_I 0 "register_operand" "=w")
        (ashift:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
index 410423bb13807638786bce4c5ead072029e9a392..198fc5dda3f14ca20e88a4e7c9527be34d04542c 100644 (file)
 ;; This code iterator allows the shifts supported in arithmetic instructions
 (define_code_iterator ASHIFT [ashift ashiftrt lshiftrt])
 
+(define_code_iterator SHIFTRT [ashiftrt lshiftrt])
+
 ;; Code iterator for logical operations
 (define_code_iterator LOGICAL [and ior xor])
 
 (define_code_attr shift [(ashift "lsl") (ashiftrt "asr")
                         (lshiftrt "lsr") (rotatert "ror")])
 
+;; Op prefix for shift right and accumulate.
+(define_code_attr sra_op [(ashiftrt "s") (lshiftrt "u")])
+
 ;; Map shift operators onto underlying bit-field instructions
 (define_code_attr bfshift [(ashift "ubfiz") (ashiftrt "sbfx")
                           (lshiftrt "ubfx") (rotatert "extr")])
index ecd2a9e5554c94ccc6b7cc7b225f4c61c0860115..2b3e4770fb7de796d243e24a8a3f74d9b4bf6f33 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-22  Sylvia Taylor  <sylvia.taylor@arm.com>
+
+       * gcc.target/aarch64/simd/ssra.c: New test.
+       * gcc.target/aarch64/simd/usra.c: New test.
+
 2019-07-22  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        * gcc.target/msp430/isr-push-pop-main.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/ssra.c b/gcc/testsuite/gcc.target/aarch64/simd/ssra.c
new file mode 100644 (file)
index 0000000..e9c2e04
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O3" } */
+/* { dg-skip-if "" { *-*-* } {"*sve*"} {""} } */
+
+#include <stdint.h>
+
+#define SSRA(func, vtype, n)                           \
+       void func ()                                    \
+       {                                               \
+           int i;                                      \
+           for (i = 0; i < n; i++)                     \
+           {                                           \
+               s1##vtype[i] += s2##vtype[i] >> 2;      \
+           }                                           \
+       }
+
+#define TEST_VDQ_I_MODES(FUNC)                         \
+       FUNC (test_v8qi_v16qi, _char, 16)               \
+       FUNC (test_v4hi_v8h1, _short, 8)                \
+       FUNC (test_v2si_v4si, _int, 4)                  \
+       FUNC (test_v2di, _ll, 2)                        \
+
+int8_t s1_char[16], s2_char[16];
+int16_t s1_short[8], s2_short[8];
+int32_t s1_int[4], s2_int[4];
+int64_t s1_ll[2], s2_ll[2];
+
+TEST_VDQ_I_MODES(SSRA)
+
+/* { dg-final { scan-assembler "ssra" } } */
+/* { dg-final { scan-assembler-not "sshr" } } */
+
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.16b, v[0-9]+\.16b, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.8h, v[0-9]+\.8h, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.4s, v[0-9]+\.4s, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.2d, v[0-9]+\.2d, [0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/usra.c b/gcc/testsuite/gcc.target/aarch64/simd/usra.c
new file mode 100644 (file)
index 0000000..4e7446d
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O3" } */
+/* { dg-skip-if "" { *-*-* } {"*sve*"} {""} } */
+
+#include <stdint.h>
+
+#define USRA(func, vtype, n)                           \
+       void func ()                                    \
+       {                                               \
+           int i;                                      \
+           for (i = 0; i < n; i++)                     \
+           {                                           \
+               u1##vtype[i] += u2##vtype[i] >> 2;      \
+           }                                           \
+       }
+
+#define TEST_VDQ_I_MODES(FUNC)                         \
+       FUNC (test_v8qi_v16qi, _char, 16)               \
+       FUNC (test_v4hi_v8h1, _short, 8)                \
+       FUNC (test_v2si_v4si, _int, 4)                  \
+       FUNC (test_v2di, _ll, 2)                        \
+
+uint8_t u1_char[16], u2_char[16];
+uint16_t u1_short[8], u2_short[8];
+uint32_t u1_int[4], u2_int[4];
+uint64_t u1_ll[2], u2_ll[2];
+
+TEST_VDQ_I_MODES(USRA)
+
+/* { dg-final { scan-assembler "usra" } } */
+/* { dg-final { scan-assembler-not "ushr" } } */
+
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.16b, v[0-9]+\.16b, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.8h, v[0-9]+\.8h, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.4s, v[0-9]+\.4s, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.2d, v[0-9]+\.2d, [0-9]+} 1 } } */