[PATCH] expr: Optimize noop copies [PR96539]

Richard Biener rguenther@suse.de
Tue Aug 11 11:33:09 GMT 2020


On August 11, 2020 11:00:14 AM GMT+02:00, Jakub Jelinek <jakub@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  <jakub@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



More information about the Gcc-patches mailing list