On August 11, 2020 11:00:14 AM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >At GIMPLE e.g. for __builtin_memmove we optimize away (to just the >return >value) noop copies where src == dest, but at the RTL we don't, and as >the >testcase shows, in some cases such copies can appear only at the RTL >level >e.g. from trying to copy an aggregate by value argument to the same >location >as it already has. If the block move is expanded e.g. piecewise, we >actually manage to optimize it away, as the individual memory copies >are >seen as noop moves, but if the target optabs are used, often the >sequences >stay until final. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. >2020-08-10 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/96539 > * expr.c (emit_block_move_hints): Don't copy anything if x and y > are the same and neither is MEM_VOLATILE_P. > > * gcc.target/i386/pr96539.c: New test. > >--- gcc/expr.c.jj 2020-07-28 15:39:09.886757905 +0200 >+++ gcc/expr.c 2020-08-10 13:14:47.190328119 +0200 >@@ -1637,6 +1637,12 @@ emit_block_move_hints (rtx x, rtx y, rtx > x = adjust_address (x, BLKmode, 0); > y = adjust_address (y, BLKmode, 0); > >+ /* If source and destination are the same, no need to copy anything. > */ >+ if (rtx_equal_p (x, y) >+ && !MEM_VOLATILE_P (x) >+ && !MEM_VOLATILE_P (y)) >+ return 0; >+ >/* Set MEM_SIZE as appropriate for this block copy. The main place >this > can be incorrect is coming from __builtin_memcpy. */ > poly_int64 const_size; >--- gcc/testsuite/gcc.target/i386/pr96539.c.jj 2020-08-10 >13:37:14.492946062 +0200 >+++ gcc/testsuite/gcc.target/i386/pr96539.c 2020-08-10 >13:36:57.158183171 +0200 >@@ -0,0 +1,16 @@ >+/* PR rtl-optimization/96539 */ >+/* { dg-do compile } * >+/* { dg-options "-Os" } */ >+/* { dg-final { scan-assembler-not "rep\[^\n\r]\*movs" } } */ >+ >+struct A { int a, b, c, d, e, f; void *g, *h, *i, *j, *k, *l, *m; }; >+ >+int bar (int a); >+int baz (int a, int b, int c, void *p, struct A s); >+ >+int >+foo (int a, int b, int c, void *p, struct A s) >+{ >+ bar (a); >+ return baz (a, b, c, p, s); >+} > > Jakub