On Tue, 18 Jul 2023 at 15:20, Serval Martinot-Lagarde via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > SVE generates superflous rev instructions that can be replaced > by single mov instruction or a pair of (rev, mov) instructions Hi Serval, I had added a similar transform to remove pair of rev instructions in: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=f0eabc52c9a2d3da0bfc201da7a5c1658b76e9a4
which seems to be removing the superfluous VEC_PERM_EXPR for your test: For example, following pair of VEC_PERM_EXPR is input to forwprop4: vect__4.9_58 = VEC_PERM_EXPR <vect__4.8_57, vect__4.8_57, { POLY_INT_CST [15, 16], POLY_INT_CST [30, 32], POLY_INT_CST [45, 48], ... }>; vect__4.12_63 = VEC_PERM_EXPR <vect__4.9_58, vect__4.9_58, { POLY_INT_CST [15, 16], POLY_INT_CST [30, 32], POLY_INT_CST [45, 48], ... }>; and forwprop4 dump shows: Removing dead stmt vect__4.12_63 = vect__4.8_57; Which shows that forwprop replaced the VEC_PERM_EXPR pair with assignment vect__4.12_63 = vect__4.8_57 (which turned out to be eventually dead). Sorry if this sounds silly to ask but could you let me know how to reproduce this issue on trunk ? I tried using -O3 -mcpu=generic+sve for your test but grepping for rev didn't return any results in code-gen. Thanks, Prathamesh > > 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