[AArch64] Add MOVPRFX alternatives for SVE EXT patterns
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 15 Aug 2019 08:37:14 +0000 (08:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 15 Aug 2019 08:37:14 +0000 (08:37 +0000)
We use EXT both to implement vec_extract for large indices and as a
permute.  In both cases we can use MOVPRFX to handle the case in which
the first input and output can't be tied.

2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
(*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.

gcc/testsuite/
* gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
* gcc.target/aarch64/sve/ext_3.c: New test.

From-SVN: r274515

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

index 62376a5f43ff303f7afd4d5e3ae035d9ccf8f7ad..cb39212683cbd407b53954e9ab46cbc84e789863 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
+       (*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.
+
 2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/aarch64/aarch64-sve.md (*sub<SVE_F:mode>3): Remove immediate
index fa7f899bd9dc8629b64f4663c5585fe922e8fc3b..9007a79d0e974a260227768555158b1d121c783a 100644 (file)
 ;; Extract an element outside the range of DUP.  This pattern requires the
 ;; source and destination to be the same.
 (define_insn "*vec_extract<mode><Vel>_ext"
-  [(set (match_operand:<VEL> 0 "register_operand" "=w")
+  [(set (match_operand:<VEL> 0 "register_operand" "=w, ?&w")
        (vec_select:<VEL>
-         (match_operand:SVE_ALL 1 "register_operand" "0")
+         (match_operand:SVE_ALL 1 "register_operand" "0, w")
          (parallel [(match_operand:SI 2 "const_int_operand")])))]
   "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
   {
     operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
     operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
-    return "ext\t%0.b, %0.b, %0.b, #%2";
+    return (which_alternative == 0
+           ? "ext\t%0.b, %0.b, %0.b, #%2"
+           : "movprfx\t%0, %1\;ext\t%0.b, %0.b, %1.b, #%2");
   }
+  [(set_attr "movprfx" "*,yes")]
 )
 
 ;; -------------------------------------------------------------------------
 ;; Concatenate two vectors and extract a subvector.  Note that the
 ;; immediate (third) operand is the lane index not the byte index.
 (define_insn "*aarch64_sve_ext<mode>"
-  [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
-       (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0")
-                        (match_operand:SVE_ALL 2 "register_operand" "w")
+  [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
+       (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0, w")
+                        (match_operand:SVE_ALL 2 "register_operand" "w, w")
                         (match_operand:SI 3 "const_int_operand")]
                        UNSPEC_EXT))]
   "TARGET_SVE
    && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
   {
     operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
-    return "ext\\t%0.b, %0.b, %2.b, #%3";
+    return (which_alternative == 0
+           ? "ext\\t%0.b, %0.b, %2.b, #%3"
+           : "movprfx\t%0, %1\;ext\\t%0.b, %0.b, %2.b, #%3");
   }
+  [(set_attr "movprfx" "*,yes")]
 )
 
 ;; -------------------------------------------------------------------------
index 67d356986d830605d4630cf970901d367b266ea7..731249adbdf5963752e42d4d268fd55977affdc1 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
+       * gcc.target/aarch64/sve/ext_3.c: New test.
+
 2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>
            Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
index 0fe7e4c2843292275bf23446a7489777368ae434..5593b070ca77e6c09bdb4a6f0913fea66c752f5d 100644 (file)
@@ -14,5 +14,4 @@ foo (void)
   asm volatile ("" :: "w" (x));
 }
 
-/* { dg-final { scan-assembler {\tmov\tz0\.d, z1\.d\n} } } */
-/* { dg-final { scan-assembler {\text\tz0\.b, z0\.b, z[01]\.b, #4\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #4\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/ext_3.c b/gcc/testsuite/gcc.target/aarch64/sve/ext_3.c
new file mode 100644 (file)
index 0000000..83c04c8
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msve-vector-bits=1024" } */
+
+typedef int vnx4si __attribute__((vector_size (128)));
+
+void
+foo (void)
+{
+  register int x asm ("z0");
+  register vnx4si y asm ("z1");
+
+  asm volatile ("" : "=w" (y));
+  x = y[21];
+  asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #84\n} } } */