[AArch64] Add SVE mul_highpart patterns

One advantage of the new permute handling compared to the old way is
that we can now easily take advantage of the vectoriser's divmod patterns
for SVE.

2018-03-13  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* config/aarch64/iterators.md (UNSPEC_SMUL_HIGHPART)
	(UNSPEC_UMUL_HIGHPART): New constants.
	(MUL_HIGHPART): New int iteraor.
	(su): Handle UNSPEC_SMUL_HIGHPART and UNSPEC_UMUL_HIGHPART.
	* config/aarch64/aarch64-sve.md (<su>mul<mode>3_highpart): New
	define_expand.
	(*<su>mul<mode>3_highpart): New define_insn.

gcc/testsuite/
	* gcc.target/aarch64/sve/mul_highpart_1.c: New test.
	* gcc.target/aarch64/sve/mul_highpart_1_run.c: Likewise.

From-SVN: r258487
This commit is contained in:
Richard Sandiford 2018-03-13 15:12:14 +00:00 committed by Richard Sandiford
parent c9b39302ef
commit 11e9443f49
6 changed files with 104 additions and 1 deletions

View File

@ -1,3 +1,13 @@
2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
* config/aarch64/iterators.md (UNSPEC_SMUL_HIGHPART)
(UNSPEC_UMUL_HIGHPART): New constants.
(MUL_HIGHPART): New int iteraor.
(su): Handle UNSPEC_SMUL_HIGHPART and UNSPEC_UMUL_HIGHPART.
* config/aarch64/aarch64-sve.md (<su>mul<mode>3_highpart): New
define_expand.
(*<su>mul<mode>3_highpart): New define_insn.
2018-03-13 Eric Botcazou <ebotcazou@adacore.com>
PR lto/84805

View File

@ -980,6 +980,34 @@
mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
)
;; Unpredicated highpart multiplication.
(define_expand "<su>mul<mode>3_highpart"
[(set (match_operand:SVE_I 0 "register_operand")
(unspec:SVE_I
[(match_dup 3)
(unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
(match_operand:SVE_I 2 "register_operand")]
MUL_HIGHPART)]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
{
operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
}
)
;; Predicated highpart multiplication.
(define_insn "*<su>mul<mode>3_highpart"
[(set (match_operand:SVE_I 0 "register_operand" "=w")
(unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl")
(unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0")
(match_operand:SVE_I 3 "register_operand" "w")]
MUL_HIGHPART)]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
)
;; Unpredicated NEG, NOT and POPCOUNT.
(define_expand "<optab><mode>2"
[(set (match_operand:SVE_I 0 "register_operand")

View File

@ -438,6 +438,8 @@
UNSPEC_ANDF ; Used in aarch64-sve.md.
UNSPEC_IORF ; Used in aarch64-sve.md.
UNSPEC_XORF ; Used in aarch64-sve.md.
UNSPEC_SMUL_HIGHPART ; Used in aarch64-sve.md.
UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md.
UNSPEC_COND_ADD ; Used in aarch64-sve.md.
UNSPEC_COND_SUB ; Used in aarch64-sve.md.
UNSPEC_COND_SMAX ; Used in aarch64-sve.md.
@ -1467,6 +1469,8 @@
(define_int_iterator UNPACK_UNSIGNED [UNSPEC_UNPACKULO UNSPEC_UNPACKUHI])
(define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART])
(define_int_iterator SVE_COND_INT_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB
UNSPEC_COND_SMAX UNSPEC_COND_UMAX
UNSPEC_COND_SMIN UNSPEC_COND_UMIN
@ -1558,7 +1562,9 @@
(define_int_attr su [(UNSPEC_UNPACKSHI "s")
(UNSPEC_UNPACKUHI "u")
(UNSPEC_UNPACKSLO "s")
(UNSPEC_UNPACKULO "u")])
(UNSPEC_UNPACKULO "u")
(UNSPEC_SMUL_HIGHPART "s")
(UNSPEC_UMUL_HIGHPART "u")])
(define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
(UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")

View File

@ -1,3 +1,8 @@
2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
* gcc.target/aarch64/sve/mul_highpart_1.c: New test.
* gcc.target/aarch64/sve/mul_highpart_1_run.c: Likewise.
2018-03-13 Martin Liska <mliska@suse.cz>
PR ipa/84658.

View File

@ -0,0 +1,25 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model --save-temps" } */
#include <stdint.h>
#define DEF_LOOP(TYPE) \
void __attribute__ ((noipa)) \
mod_##TYPE (TYPE *dst, TYPE *src, int count) \
{ \
for (int i = 0; i < count; ++i) \
dst[i] = src[i] % 17; \
}
#define TEST_ALL(T) \
T (int32_t) \
T (uint32_t) \
T (int64_t) \
T (uint64_t)
TEST_ALL (DEF_LOOP)
/* { dg-final { scan-assembler-times {\tsmulh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
/* { dg-final { scan-assembler-times {\tumulh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
/* { dg-final { scan-assembler-times {\tsmulh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
/* { dg-final { scan-assembler-times {\tumulh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */

View File

@ -0,0 +1,29 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model --save-temps" } */
#include "mul_highpart_1.c"
#define N 79
#define TEST_LOOP(TYPE) \
{ \
TYPE dst[N], src[N]; \
for (int i = 0; i < N; ++i) \
{ \
src[i] = i * 7 + i % 3; \
if (i % 11 > 7) \
src[i] = -src[i]; \
asm volatile ("" ::: "memory"); \
} \
mod_##TYPE (dst, src, N); \
for (int i = 0; i < N; ++i) \
if (dst[i] != src[i] % 17) \
__builtin_abort (); \
}
int
main (void)
{
TEST_ALL (TEST_LOOP);
return 0;
}