From 33ed618d54e7317398c121509e225625f216394c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 31 May 2017 14:37:36 +0000 Subject: Fix SVE REVB, REVH and REVW patterns The instructions should have been predicated. This had slipped through because we only use the instructions for fixed-length SVE, but clearly there isn't enough coverage of that in the testsuite. I'm working to fix that for the SVE submission. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ARM/sve-branch@248745 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/config/aarch64/aarch64-sve.md | 27 ++++++++++++++++++--------- gcc/config/aarch64/aarch64.c | 26 +++++++++++++++++++++----- gcc/testsuite/gcc.target/aarch64/sve_revb_1.c | 10 +++++----- gcc/testsuite/gcc.target/aarch64/sve_revh_1.c | 8 ++++---- gcc/testsuite/gcc.target/aarch64/sve_revw_1.c | 6 +++--- 5 files changed, 51 insertions(+), 26 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 3faa253343c..2f519c8bed0 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -684,26 +684,35 @@ (define_insn "sve_rev64" [(set (match_operand:SVE_BHS 0 "register_operand" "=w") - (unspec:SVE_BHS [(match_operand:SVE_BHS 1 "register_operand" "w")] - UNSPEC_REV64))] + (unspec:SVE_BHS + [(match_operand:V4BI 1 "register_operand" "Upl") + (unspec:SVE_BHS [(match_operand:SVE_BHS 2 "register_operand" "w")] + UNSPEC_REV64)] + UNSPEC_MERGE_PTRUE))] "TARGET_SVE" - "rev\t%0.d, %1.d" + "rev\t%0.d, %1/m, %2.d" ) (define_insn "sve_rev32" [(set (match_operand:SVE_BH 0 "register_operand" "=w") - (unspec:SVE_BH [(match_operand:SVE_BH 1 "register_operand" "w")] - UNSPEC_REV32))] + (unspec:SVE_BH + [(match_operand:V8BI 1 "register_operand" "Upl") + (unspec:SVE_BH [(match_operand:SVE_BH 2 "register_operand" "w")] + UNSPEC_REV32)] + UNSPEC_MERGE_PTRUE))] "TARGET_SVE" - "rev\t%0.s, %1.s" + "rev\t%0.s, %1/m, %2.s" ) (define_insn "sve_rev16v32qi" [(set (match_operand:V32QI 0 "register_operand" "=w") - (unspec:V32QI [(match_operand:V32QI 1 "register_operand" "w")] - UNSPEC_REV16))] + (unspec:V32QI + [(match_operand:V16BI 1 "register_operand" "Upl") + (unspec:V32QI [(match_operand:V32QI 2 "register_operand" "w")] + UNSPEC_REV16)] + UNSPEC_MERGE_PTRUE))] "TARGET_SVE" - "revb\t%0.h, %1.h" + "revb\t%0.h, %1/m, %2.h" ) (define_insn "sve_dup_lane" diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index fe09ce24aba..0e18e43a6e9 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -14618,6 +14618,7 @@ static bool aarch64_evpc_rev (struct expand_vec_perm_d *d) { unsigned int i, j, diff, size, unspec, nelt = d->nelt; + machine_mode pred_mode; if (!d->one_vector_p) return false; @@ -14625,11 +14626,20 @@ aarch64_evpc_rev (struct expand_vec_perm_d *d) diff = d->perm[0]; size = (diff + 1) * GET_MODE_UNIT_SIZE (d->vmode); if (size == 8) - unspec = UNSPEC_REV64; + { + unspec = UNSPEC_REV64; + pred_mode = V4BImode; + } else if (size == 4) - unspec = UNSPEC_REV32; + { + unspec = UNSPEC_REV32; + pred_mode = V8BImode; + } else if (size == 2) - unspec = UNSPEC_REV16; + { + unspec = UNSPEC_REV16; + pred_mode = V16BImode; + } else return false; @@ -14650,8 +14660,14 @@ aarch64_evpc_rev (struct expand_vec_perm_d *d) if (d->testing_p) return true; - emit_set_insn (d->target, gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), - unspec)); + rtx src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), unspec); + if (d->vec_flags == VEC_SVE_DATA) + { + rtx pred = force_reg (pred_mode, CONSTM1_RTX (pred_mode)); + src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (2, pred, src), + UNSPEC_MERGE_PTRUE); + } + emit_set_insn (d->target, src); return true; } diff --git a/gcc/testsuite/gcc.target/aarch64/sve_revb_1.c b/gcc/testsuite/gcc.target/aarch64/sve_revb_1.c index 9800d9285e7..2b8c6e523ca 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve_revb_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve_revb_1.c @@ -1,5 +1,5 @@ -/* { dg-do compile } */ -/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256" } */ +/* { dg-do assemble } */ +/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256 --save-temps" } */ typedef char v32qi __attribute__((vector_size (32))); @@ -28,6 +28,6 @@ TEST_ALL (PERMUTE) /* { dg-final { scan-assembler-not {\ttbl\t} } } */ -/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.d, z[0-9]+\.d} 1 } } */ -/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.s, z[0-9]+\.s} 1 } } */ -/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.h, z[0-9]+\.h} 1 } } */ +/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 1 } } */ +/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s} 1 } } */ +/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve_revh_1.c b/gcc/testsuite/gcc.target/aarch64/sve_revh_1.c index 395963b98ab..aaa08dc03e2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve_revh_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve_revh_1.c @@ -1,5 +1,5 @@ -/* { dg-do compile } */ -/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256" } */ +/* { dg-do assemble } */ +/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256 --save-temps" } */ typedef unsigned short v16hi __attribute__((vector_size (32))); @@ -27,5 +27,5 @@ TEST_ALL (PERMUTE) /* { dg-final { scan-assembler-not {\ttbl\t} } } */ -/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.d, z[0-9]+\.d} 1 } } */ -/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.s, z[0-9]+\.s} 1 } } */ +/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 1 } } */ +/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve_revw_1.c b/gcc/testsuite/gcc.target/aarch64/sve_revw_1.c index c97c4619184..ac7ef0ef267 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve_revw_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve_revw_1.c @@ -1,5 +1,5 @@ -/* { dg-do compile } */ -/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256" } */ +/* { dg-do assemble } */ +/* { dg-options "-O -march=armv8-a+sve -msve-vector-bits=256 --save-temps" } */ typedef unsigned int v8si __attribute__((vector_size (32))); typedef float v8sf __attribute__((vector_size (32))); @@ -26,4 +26,4 @@ TEST_ALL (PERMUTE) /* { dg-final { scan-assembler-not {\ttbl\t} } } */ -/* { dg-final { scan-assembler-times {\trevw\tz[0-9]+\.d, z[0-9]+\.d} 2 } } */ +/* { dg-final { scan-assembler-times {\trevw\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 2 } } */ -- cgit v1.2.3