The expansions of the svprf[bhwd] instructions weren't taking
advantage of the immediate addressing mode.

Tested on aarch64-linux-gnu and aarch64_be-elf.  Pushed to trunk so far.
Will backport to GCC 10 “soon”.

Richard


gcc/
        * config/aarch64/aarch64.c (offset_6bit_signed_scaled_p): New function.
        (offset_6bit_unsigned_scaled_p): Fix typo in comment.
        (aarch64_sve_prefetch_operand_p): Accept MUL VLs in the range
        [-32, 31].

gcc/testsuite/
        * gcc.target/aarch64/sve/acle/asm/prfb.c: Test for a MUL VL range of
        [-32, 31].
        * gcc.target/aarch64/sve/acle/asm/prfh.c: Likewise.
        * gcc.target/aarch64/sve/acle/asm/prfw.c: Likewise.
        * gcc.target/aarch64/sve/acle/asm/prfd.c: Likewise.
---
 gcc/config/aarch64/aarch64.c                  | 17 +++++--
 .../gcc.target/aarch64/sve/acle/asm/prfb.c    | 47 +++++++++++++------
 .../gcc.target/aarch64/sve/acle/asm/prfd.c    | 47 +++++++++++++------
 .../gcc.target/aarch64/sve/acle/asm/prfh.c    | 47 +++++++++++++------
 .../gcc.target/aarch64/sve/acle/asm/prfw.c    | 47 +++++++++++++------
 5 files changed, 146 insertions(+), 59 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 5dbb9aa8924..a96b84cd927 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7436,7 +7436,18 @@ offset_4bit_signed_scaled_p (machine_mode mode, 
poly_int64 offset)
          && IN_RANGE (multiple, -8, 7));
 }
 
-/* Return true if OFFSET is a unsigned 6-bit value multiplied by the size
+/* Return true if OFFSET is a signed 6-bit value multiplied by the size
+   of MODE.  */
+
+static inline bool
+offset_6bit_signed_scaled_p (machine_mode mode, poly_int64 offset)
+{
+  HOST_WIDE_INT multiple;
+  return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple)
+         && IN_RANGE (multiple, -32, 31));
+}
+
+/* Return true if OFFSET is an unsigned 6-bit value multiplied by the size
    of MODE.  */
 
 static inline bool
@@ -18494,11 +18505,11 @@ bool
 aarch64_sve_prefetch_operand_p (rtx op, machine_mode mode)
 {
   struct aarch64_address_info addr;
-  if (!aarch64_classify_address (&addr, op, mode, false))
+  if (!aarch64_classify_address (&addr, op, mode, false, ADDR_QUERY_ANY))
     return false;
 
   if (addr.type == ADDRESS_REG_IMM)
-    return known_eq (addr.const_offset, 0);
+    return offset_6bit_signed_scaled_p (mode, addr.const_offset);
 
   return addr.type == ADDRESS_REG_REG;
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfb.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfb.c
index d2b2777e66f..c90730a037c 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfb.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfb.c
@@ -200,8 +200,7 @@ TEST_PREFETCH (prfb_vnum_0, uint8_t,
 
 /*
 ** prfb_vnum_1:
-**     incb    x0
-**     prfb    pldl1keep, p0, \[x0\]
+**     prfb    pldl1keep, p0, \[x0, #1, mul vl\]
 **     ret
 */
 TEST_PREFETCH (prfb_vnum_1, uint16_t,
@@ -209,24 +208,44 @@ TEST_PREFETCH (prfb_vnum_1, uint16_t,
               svprfb_vnum (p0, x0, 1, SV_PLDL1KEEP))
 
 /*
-** prfb_vnum_2:
-**     incb    x0, all, mul #2
-**     prfb    pldl1keep, p0, \[x0\]
+** prfb_vnum_31:
+**     prfb    pldl1keep, p0, \[x0, #31, mul vl\]
 **     ret
 */
-TEST_PREFETCH (prfb_vnum_2, uint32_t,
-              svprfb_vnum (p0, x0, 2, SV_PLDL1KEEP),
-              svprfb_vnum (p0, x0, 2, SV_PLDL1KEEP))
+TEST_PREFETCH (prfb_vnum_31, uint16_t,
+              svprfb_vnum (p0, x0, 31, SV_PLDL1KEEP),
+              svprfb_vnum (p0, x0, 31, SV_PLDL1KEEP))
 
 /*
-** prfb_vnum_3:
-**     incb    x0, all, mul #3
-**     prfb    pldl1keep, p0, \[x0\]
+** prfb_vnum_32:
+**     cntd    (x[0-9]+)
+**     lsl     (x[0-9]+), \1, #?8
+**     add     (x[0-9]+), (\2, x0|x0, \2)
+**     prfb    pldl1keep, p0, \[\3\]
+**     ret
+*/
+TEST_PREFETCH (prfb_vnum_32, uint16_t,
+              svprfb_vnum (p0, x0, 32, SV_PLDL1KEEP),
+              svprfb_vnum (p0, x0, 32, SV_PLDL1KEEP))
+
+/*
+** prfb_vnum_m32:
+**     prfb    pldl1keep, p0, \[x0, #-32, mul vl\]
+**     ret
+*/
+TEST_PREFETCH (prfb_vnum_m32, uint16_t,
+              svprfb_vnum (p0, x0, -32, SV_PLDL1KEEP),
+              svprfb_vnum (p0, x0, -32, SV_PLDL1KEEP))
+
+/*
+** prfb_vnum_m33:
+**     ...
+**     prfb    pldl1keep, p0, \[x[0-9]+\]
 **     ret
 */
-TEST_PREFETCH (prfb_vnum_3, uint64_t,
-              svprfb_vnum (p0, x0, 3, SV_PLDL1KEEP),
-              svprfb_vnum (p0, x0, 3, SV_PLDL1KEEP))
+TEST_PREFETCH (prfb_vnum_m33, uint16_t,
+              svprfb_vnum (p0, x0, -33, SV_PLDL1KEEP),
+              svprfb_vnum (p0, x0, -33, SV_PLDL1KEEP))
 
 /*
 ** prfb_vnum_x1:
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfd.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfd.c
index 72b2e64154e..869ef3d3eeb 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfd.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfd.c
@@ -200,8 +200,7 @@ TEST_PREFETCH (prfd_vnum_0, uint8_t,
 
 /*
 ** prfd_vnum_1:
-**     incb    x0
-**     prfd    pldl1keep, p0, \[x0\]
+**     prfd    pldl1keep, p0, \[x0, #1, mul vl\]
 **     ret
 */
 TEST_PREFETCH (prfd_vnum_1, uint16_t,
@@ -209,24 +208,44 @@ TEST_PREFETCH (prfd_vnum_1, uint16_t,
               svprfd_vnum (p0, x0, 1, SV_PLDL1KEEP))
 
 /*
-** prfd_vnum_2:
-**     incb    x0, all, mul #2
-**     prfd    pldl1keep, p0, \[x0\]
+** prfd_vnum_31:
+**     prfd    pldl1keep, p0, \[x0, #31, mul vl\]
 **     ret
 */
-TEST_PREFETCH (prfd_vnum_2, uint32_t,
-              svprfd_vnum (p0, x0, 2, SV_PLDL1KEEP),
-              svprfd_vnum (p0, x0, 2, SV_PLDL1KEEP))
+TEST_PREFETCH (prfd_vnum_31, uint16_t,
+              svprfd_vnum (p0, x0, 31, SV_PLDL1KEEP),
+              svprfd_vnum (p0, x0, 31, SV_PLDL1KEEP))
 
 /*
-** prfd_vnum_3:
-**     incb    x0, all, mul #3
-**     prfd    pldl1keep, p0, \[x0\]
+** prfd_vnum_32:
+**     cntd    (x[0-9]+)
+**     lsl     (x[0-9]+), \1, #?8
+**     add     (x[0-9]+), (\2, x0|x0, \2)
+**     prfd    pldl1keep, p0, \[\3\]
+**     ret
+*/
+TEST_PREFETCH (prfd_vnum_32, uint16_t,
+              svprfd_vnum (p0, x0, 32, SV_PLDL1KEEP),
+              svprfd_vnum (p0, x0, 32, SV_PLDL1KEEP))
+
+/*
+** prfd_vnum_m32:
+**     prfd    pldl1keep, p0, \[x0, #-32, mul vl\]
+**     ret
+*/
+TEST_PREFETCH (prfd_vnum_m32, uint16_t,
+              svprfd_vnum (p0, x0, -32, SV_PLDL1KEEP),
+              svprfd_vnum (p0, x0, -32, SV_PLDL1KEEP))
+
+/*
+** prfd_vnum_m33:
+**     ...
+**     prfd    pldl1keep, p0, \[x[0-9]+\]
 **     ret
 */
-TEST_PREFETCH (prfd_vnum_3, uint64_t,
-              svprfd_vnum (p0, x0, 3, SV_PLDL1KEEP),
-              svprfd_vnum (p0, x0, 3, SV_PLDL1KEEP))
+TEST_PREFETCH (prfd_vnum_m33, uint16_t,
+              svprfd_vnum (p0, x0, -33, SV_PLDL1KEEP),
+              svprfd_vnum (p0, x0, -33, SV_PLDL1KEEP))
 
 /*
 ** prfd_vnum_x1:
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfh.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfh.c
index 89069f9b746..45a735eaea0 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfh.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfh.c
@@ -200,8 +200,7 @@ TEST_PREFETCH (prfh_vnum_0, uint8_t,
 
 /*
 ** prfh_vnum_1:
-**     incb    x0
-**     prfh    pldl1keep, p0, \[x0\]
+**     prfh    pldl1keep, p0, \[x0, #1, mul vl\]
 **     ret
 */
 TEST_PREFETCH (prfh_vnum_1, uint16_t,
@@ -209,24 +208,44 @@ TEST_PREFETCH (prfh_vnum_1, uint16_t,
               svprfh_vnum (p0, x0, 1, SV_PLDL1KEEP))
 
 /*
-** prfh_vnum_2:
-**     incb    x0, all, mul #2
-**     prfh    pldl1keep, p0, \[x0\]
+** prfh_vnum_31:
+**     prfh    pldl1keep, p0, \[x0, #31, mul vl\]
 **     ret
 */
-TEST_PREFETCH (prfh_vnum_2, uint32_t,
-              svprfh_vnum (p0, x0, 2, SV_PLDL1KEEP),
-              svprfh_vnum (p0, x0, 2, SV_PLDL1KEEP))
+TEST_PREFETCH (prfh_vnum_31, uint16_t,
+              svprfh_vnum (p0, x0, 31, SV_PLDL1KEEP),
+              svprfh_vnum (p0, x0, 31, SV_PLDL1KEEP))
 
 /*
-** prfh_vnum_3:
-**     incb    x0, all, mul #3
-**     prfh    pldl1keep, p0, \[x0\]
+** prfh_vnum_32:
+**     cntd    (x[0-9]+)
+**     lsl     (x[0-9]+), \1, #?8
+**     add     (x[0-9]+), (\2, x0|x0, \2)
+**     prfh    pldl1keep, p0, \[\3\]
+**     ret
+*/
+TEST_PREFETCH (prfh_vnum_32, uint16_t,
+              svprfh_vnum (p0, x0, 32, SV_PLDL1KEEP),
+              svprfh_vnum (p0, x0, 32, SV_PLDL1KEEP))
+
+/*
+** prfh_vnum_m32:
+**     prfh    pldl1keep, p0, \[x0, #-32, mul vl\]
+**     ret
+*/
+TEST_PREFETCH (prfh_vnum_m32, uint16_t,
+              svprfh_vnum (p0, x0, -32, SV_PLDL1KEEP),
+              svprfh_vnum (p0, x0, -32, SV_PLDL1KEEP))
+
+/*
+** prfh_vnum_m33:
+**     ...
+**     prfh    pldl1keep, p0, \[x[0-9]+\]
 **     ret
 */
-TEST_PREFETCH (prfh_vnum_3, uint64_t,
-              svprfh_vnum (p0, x0, 3, SV_PLDL1KEEP),
-              svprfh_vnum (p0, x0, 3, SV_PLDL1KEEP))
+TEST_PREFETCH (prfh_vnum_m33, uint16_t,
+              svprfh_vnum (p0, x0, -33, SV_PLDL1KEEP),
+              svprfh_vnum (p0, x0, -33, SV_PLDL1KEEP))
 
 /*
 ** prfh_vnum_x1:
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfw.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfw.c
index bbf6a45c97e..444187f45d9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfw.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/prfw.c
@@ -200,8 +200,7 @@ TEST_PREFETCH (prfw_vnum_0, uint8_t,
 
 /*
 ** prfw_vnum_1:
-**     incb    x0
-**     prfw    pldl1keep, p0, \[x0\]
+**     prfw    pldl1keep, p0, \[x0, #1, mul vl\]
 **     ret
 */
 TEST_PREFETCH (prfw_vnum_1, uint16_t,
@@ -209,24 +208,44 @@ TEST_PREFETCH (prfw_vnum_1, uint16_t,
               svprfw_vnum (p0, x0, 1, SV_PLDL1KEEP))
 
 /*
-** prfw_vnum_2:
-**     incb    x0, all, mul #2
-**     prfw    pldl1keep, p0, \[x0\]
+** prfw_vnum_31:
+**     prfw    pldl1keep, p0, \[x0, #31, mul vl\]
 **     ret
 */
-TEST_PREFETCH (prfw_vnum_2, uint32_t,
-              svprfw_vnum (p0, x0, 2, SV_PLDL1KEEP),
-              svprfw_vnum (p0, x0, 2, SV_PLDL1KEEP))
+TEST_PREFETCH (prfw_vnum_31, uint16_t,
+              svprfw_vnum (p0, x0, 31, SV_PLDL1KEEP),
+              svprfw_vnum (p0, x0, 31, SV_PLDL1KEEP))
 
 /*
-** prfw_vnum_3:
-**     incb    x0, all, mul #3
-**     prfw    pldl1keep, p0, \[x0\]
+** prfw_vnum_32:
+**     cntd    (x[0-9]+)
+**     lsl     (x[0-9]+), \1, #?8
+**     add     (x[0-9]+), (\2, x0|x0, \2)
+**     prfw    pldl1keep, p0, \[\3\]
+**     ret
+*/
+TEST_PREFETCH (prfw_vnum_32, uint16_t,
+              svprfw_vnum (p0, x0, 32, SV_PLDL1KEEP),
+              svprfw_vnum (p0, x0, 32, SV_PLDL1KEEP))
+
+/*
+** prfw_vnum_m32:
+**     prfw    pldl1keep, p0, \[x0, #-32, mul vl\]
+**     ret
+*/
+TEST_PREFETCH (prfw_vnum_m32, uint16_t,
+              svprfw_vnum (p0, x0, -32, SV_PLDL1KEEP),
+              svprfw_vnum (p0, x0, -32, SV_PLDL1KEEP))
+
+/*
+** prfw_vnum_m33:
+**     ...
+**     prfw    pldl1keep, p0, \[x[0-9]+\]
 **     ret
 */
-TEST_PREFETCH (prfw_vnum_3, uint64_t,
-              svprfw_vnum (p0, x0, 3, SV_PLDL1KEEP),
-              svprfw_vnum (p0, x0, 3, SV_PLDL1KEEP))
+TEST_PREFETCH (prfw_vnum_m33, uint16_t,
+              svprfw_vnum (p0, x0, -33, SV_PLDL1KEEP),
+              svprfw_vnum (p0, x0, -33, SV_PLDL1KEEP))
 
 /*
 ** prfw_vnum_x1:

Reply via email to