From ba15b0fa0df773a90374f6b06775534ecd9f7b43 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 4 Jan 2021 11:56:19 +0000 Subject: [PATCH] aarch64: Use the MUL VL form of SVE PRF[BHWD] The expansions of the svprf[bhwd] instructions weren't taking advantage of the immediate addressing mode. 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: -- 2.30.2