re PR tree-optimization/43784 (-Os -fkeep-inline-functions causes FAIL: gcc.c-torture...
authorRichard Guenther <rguenther@suse.de>
Mon, 26 Jul 2010 16:01:55 +0000 (16:01 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 26 Jul 2010 16:01:55 +0000 (16:01 +0000)
2010-07-26  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/43784
* tree-nrv.c (dest_safe_for_nrv_p): It's not safe to NRV
if the destination is used by the call.

* gcc.c-torture/execute/pr43784.c: New testcase.
* g++.dg/torture/pr43784.C: Likewise.

From-SVN: r162539

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr43784.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr43784.c [new file with mode: 0644]
gcc/tree-nrv.c

index 66a86e5c73127128214c9734ba49533f10340c7d..93d0c7ea0913a7f1ff473059034181801e1a9094 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43784
+       * tree-nrv.c (dest_safe_for_nrv_p): It's not safe to NRV
+       if the destination is used by the call.
+
 2010-07-26  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/45073
index 52d94d2166df11336d06bfddd2ae905cc66aa430..cd7de607c77ac7fc5f809b89ba9de4649cd85bae 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43784
+       * gcc.c-torture/execute/pr43784.c: New testcase.
+       * g++.dg/torture/pr43784.C: Likewise.
+
 2010-07-26  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/45056
diff --git a/gcc/testsuite/g++.dg/torture/pr43784.C b/gcc/testsuite/g++.dg/torture/pr43784.C
new file mode 100644 (file)
index 0000000..a83a6f3
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+struct S {int x, y, makemelarge[5];};
+S __attribute__((noinline)) f (S &s) {
+    S r;
+    r.x = s.y;
+    r.y = s.x;
+    return r;
+}
+int __attribute__((noinline)) glob (int a, int b)
+{
+  S local = { a, b };
+  local = f (local);
+  return local.y;
+}
+extern "C" void abort (void);
+int main (void)
+{
+  if (glob (1, 3) != 1)
+    abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr43784.c b/gcc/testsuite/gcc.c-torture/execute/pr43784.c
new file mode 100644 (file)
index 0000000..6222327
--- /dev/null
@@ -0,0 +1,33 @@
+struct s {
+  unsigned char a[256];
+};
+union u {
+  struct { struct s b; int c; } d;
+  struct { int c; struct s b; } e;
+};
+
+static union u v;
+static struct s *p = &v.d.b;
+static struct s *q = &v.e.b;
+
+static struct s __attribute__((noinline)) rp(void)
+{
+  return *p;
+}
+
+static void qp(void)
+{
+  *q = rp();
+}
+
+int main()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    p->a[i] = i;
+  qp();
+  for (i = 0; i < 256; i++)
+    if (q->a[i] != i)
+      __builtin_abort();
+  return 0;
+}
index 2f40d563d33b90522d33500e3b4ad4596bcb1bd8..8ee3b8b0a4ba440066099ba7620afdb651bbd64b 100644 (file)
@@ -296,7 +296,7 @@ struct gimple_opt_pass pass_nrv =
    optimization, where DEST is expected to be the LHS of a modify
    expression where the RHS is a function returning an aggregate.
 
-   DEST is available if it is not clobbered by the call.  */
+   DEST is available if it is not clobbered or used by the call.  */
 
 static bool
 dest_safe_for_nrv_p (gimple call)
@@ -310,7 +310,8 @@ dest_safe_for_nrv_p (gimple call)
   if (TREE_CODE (dest) == SSA_NAME)
     return true;
 
-  if (call_may_clobber_ref_p (call, dest))
+  if (call_may_clobber_ref_p (call, dest)
+      || ref_maybe_used_by_stmt_p (call, dest))
     return false;
 
   return true;
@@ -345,8 +346,7 @@ execute_return_slot_opt (void)
              && gimple_call_lhs (stmt)
              && !gimple_call_return_slot_opt_p (stmt)
              && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
-                                   gimple_call_fndecl (stmt))
-            )
+                                   gimple_call_fndecl (stmt)))
            {
              /* Check if the location being assigned to is
                 clobbered by the call.  */