aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-08-11 13:47:29 +0200
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 15:07:58 -0300
commit58b741b1bf1127946a0590d909302023c2350bb5 (patch)
tree9442d37b1a2b0a24e31bc19a46b2857416124752
parentb76a9e0d9e1a2240c1c955461e58297aea066cca (diff)
expr: Optimize noop copies [PR96539]
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. 2020-08-11 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.
-rw-r--r--gcc/expr.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr96539.c16
2 files changed, 22 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index ebf0c9e4797..2406f9039ea 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1637,6 +1637,12 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
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;
diff --git a/gcc/testsuite/gcc.target/i386/pr96539.c b/gcc/testsuite/gcc.target/i386/pr96539.c
new file mode 100644
index 00000000000..fc164f8b889
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr96539.c
@@ -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);
+}