SVE generates superflous rev instructions that can be replaced by single mov instruction or a pair of (rev, mov) instructions
gcc/ * config/aarch64/aarch64-sve.md: New peephole2. * testsuite/gcc.target/aarch64/sve/revrev.c: New dg test. Signed-off-by: Serval Martinot-Lagarde <serval.martinot-laga...@sipearl.com> --- gcc/config/aarch64/aarch64-sve.md | 21 +++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/revrev.c | 13 ++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/revrev.c diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index da5534c3e32..e5e0c7ddfc5 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -8836,6 +8836,27 @@ "TARGET_SVE" "rev\t%0.<Vctype>, %1.<Vctype>") +(define_peephole2 + [(set (match_operand:SVE_ALL 0 "register_operand" "") + (unspec:SVE_ALL + [(match_operand:SVE_ALL 1 "register_operand" "")] UNSPEC_REV)) + (set (match_operand:SVE_ALL 2 "register_operand" "") + (unspec:SVE_ALL + [(match_dup 0)] UNSPEC_REV))] + "TARGET_SVE" + [(const_int 0)] + { + if (REGNO (operands[2]) != REGNO (operands[0])) + { + emit_insn (gen_rtx_SET (operands[2], operands[1])); + rtx rev = gen_rtx_UNSPEC (<MODE>mode, gen_rtvec (1, operands[1]), UNSPEC_REV); + emit_insn (gen_rtx_SET (operands[0], rev)); + } + else + emit_insn (gen_rtx_SET (operands[0], operands[1])); + DONE; + }) + ;; ------------------------------------------------------------------------- ;; ---- [INT,FP] Special-purpose binary permutes ;; ------------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revrev.c b/gcc/testsuite/gcc.target/aarch64/sve/revrev.c new file mode 100644 index 00000000000..04af6eed291 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/revrev.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +#include <stdint.h> + +void +test (uint8_t a[], uint8_t b[], uint64_t N) +{ + for (uint64_t i = N; i > 0; i--) + a[i - 1] = b[i - 1]; +} + +/* { dg-final { scan-assembler-not {\trev\t(z[0-9]+\.h), \1\n\trev\t\1, \1\n} } } */ -- 2.21.0