aarch64: Add support for unpacked SVE ADR
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 11 Jan 2021 18:03:23 +0000 (18:03 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 11 Jan 2021 18:03:23 +0000 (18:03 +0000)
This patch extends the ADR patterns to handle unpacked vectors.
They would work with both elements and containers, but since
the instructions only support .s and .d, we get more coverage
by using containers.

gcc/
* config/aarch64/iterators.md (SVE_24I): New iterator.
* config/aarch64/aarch64-sve.md (*aarch64_adr<mode>_shift): Extend from
SVE_FULL_SDI to SVE_24I.  Use containers rather than elements.

gcc/testsuite/
* gcc.target/aarch64/sve/adr_6.c: New test.

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

index 547f34134a17b5297efde4a1536983ebe971654c..27b7fd0fccde1715f0cfde16cb574432e18289fa 100644 (file)
 )
 
 (define_insn_and_rewrite "*aarch64_adr<mode>_shift"
-  [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w")
-       (plus:SVE_FULL_SDI
-         (unspec:SVE_FULL_SDI
+  [(set (match_operand:SVE_24I 0 "register_operand" "=w")
+       (plus:SVE_24I
+         (unspec:SVE_24I
            [(match_operand 4)
-            (ashift:SVE_FULL_SDI
-              (match_operand:SVE_FULL_SDI 2 "register_operand" "w")
-              (match_operand:SVE_FULL_SDI 3 "const_1_to_3_operand"))]
+            (ashift:SVE_24I
+              (match_operand:SVE_24I 2 "register_operand" "w")
+              (match_operand:SVE_24I 3 "const_1_to_3_operand"))]
            UNSPEC_PRED_X)
-         (match_operand:SVE_FULL_SDI 1 "register_operand" "w")))]
+         (match_operand:SVE_24I 1 "register_operand" "w")))]
   "TARGET_SVE"
-  "adr\t%0.<Vetype>, [%1.<Vetype>, %2.<Vetype>, lsl %3]"
+  "adr\t%0.<Vctype>, [%1.<Vctype>, %2.<Vctype>, lsl %3]"
   "&& !CONSTANT_P (operands[4])"
   {
     operands[4] = CONSTM1_RTX (<VPRED>mode);
index 5a82d9395f96bf426f3b293b5586247ec08edb59..54a99d441b831b983f1c15f8387eba314f675d83 100644 (file)
                              VNx2DI VNx2DF
                              VNx4QI VNx4HI VNx4HF VNx4BF VNx4SI VNx4SF])
 
+;; SVE integer modes with 2 or 4 elements.
+(define_mode_iterator SVE_24I [VNx2QI VNx2HI VNx2SI VNx2DI
+                              VNx4QI VNx4HI VNx4SI])
+
 ;; SVE modes with 2 elements.
 (define_mode_iterator SVE_2 [VNx2QI VNx2HI VNx2HF VNx2BF
                             VNx2SI VNx2SF VNx2DI VNx2DF])
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_6.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_6.c
new file mode 100644 (file)
index 0000000..1f92749
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */
+
+#include <stdint.h>
+
+#define TEST_OP_IMM(TYPE, AMT) \
+  TYPE test##_##TYPE##_##AMT (TYPE a, TYPE b) { return a + b * AMT; }
+
+#define TEST_OP(TYPE) \
+  TEST_OP_IMM (TYPE, 2) \
+  TEST_OP_IMM (TYPE, 4) \
+  TEST_OP_IMM (TYPE, 8)
+
+#define TEST_TYPE(TYPE, SIZE) \
+  typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \
+  TEST_OP (TYPE##SIZE)
+
+TEST_TYPE (int8_t, 32)
+TEST_TYPE (uint8_t, 32)
+
+TEST_TYPE (int8_t, 64)
+TEST_TYPE (uint8_t, 64)
+TEST_TYPE (int16_t, 64)
+TEST_TYPE (uint16_t, 64)
+
+/* These two can't use ADR.  */
+TEST_TYPE (int8_t, 128)
+TEST_TYPE (uint8_t, 128)
+TEST_TYPE (int16_t, 128)
+TEST_TYPE (uint16_t, 128)
+TEST_TYPE (int32_t, 128)
+TEST_TYPE (uint32_t, 128)
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.b,} 6 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b,} 6 } } */
+
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.s, \[z[0-9]+\.s, z[0-9]+\.s, lsl #?1\]\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.s, \[z[0-9]+\.s, z[0-9]+\.s, lsl #?2\]\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.s, \[z[0-9]+\.s, z[0-9]+\.s, lsl #?3\]\n} 4 } } */
+
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.d, \[z[0-9]+\.d, z[0-9]+\.d, lsl #?1\]\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.d, \[z[0-9]+\.d, z[0-9]+\.d, lsl #?2\]\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]+\.d, \[z[0-9]+\.d, z[0-9]+\.d, lsl #?3\]\n} 6 } } */