2012-01-31 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Jan 2012 09:46:29 +0000 (09:46 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Jan 2012 09:46:29 +0000 (09:46 +0000)
PR tree-optimization/51528
* tree-sra.c (sra_modify_assign): Avoid copy-in/out for aggregate
assigns.

* gcc.dg/torture/pr51528.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183752 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr51528.c [new file with mode: 0644]
gcc/tree-sra.c

index d451dcc..ce93b26 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-31  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/51528
+       * tree-sra.c (sra_modify_assign): Avoid copy-in/out for aggregate
+       assigns.
+
 2012-01-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR bootstrap/52041
index da42f22..77c8639 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-31  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/51528
+       * gcc.dg/torture/pr51528.c: New testcase.
+
 2012-01-30  Uros Bizjak  <ubizjak@gmail.com>
 
        PR go/48501
diff --git a/gcc/testsuite/gcc.dg/torture/pr51528.c b/gcc/testsuite/gcc.dg/torture/pr51528.c
new file mode 100644 (file)
index 0000000..db5f3e0
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-fno-early-inlining" } */
+
+extern void abort (void);
+
+union U
+{
+  int i;
+  _Bool b;
+};
+
+_Bool gb;
+
+void  __attribute__ ((noinline))
+use_bool (union U u)
+{
+  gb = u.b;
+}
+
+union U
+bar (void)
+{
+  union U u;
+  u.i = 0xFFFE;
+  return u;
+}
+
+union U  __attribute__ ((noinline))
+foo (void)
+{
+  union U u,v;
+
+  u.b = 1;
+  use_bool (u);
+  u = bar ();
+
+  return u;
+}
+
+int main (int argc, char **argv)
+{
+  union U u = foo ();
+  if (u.i != 0xFFFE)
+    abort ();
+  return 0;
+}
index ef26894..e3bf382 100644 (file)
@@ -3135,9 +3135,14 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
              sra_stats.deleted++;
              return SRA_AM_REMOVED;
            }
+         /* Restore the aggregate RHS from its components so the
+            prevailing aggregate copy does the right thing.  */
          if (access_has_children_p (racc))
-           generate_subtree_copies (racc->first_child, lhs, racc->offset,
-                                    0, 0, gsi, false, true, loc);
+           generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
+                                    gsi, false, false, loc);
+         /* Re-load the components of the aggregate copy destination.
+            But use the RHS aggregate to load from to expose more
+            optimization opportunities.  */
          if (access_has_children_p (lacc))
            generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
                                     0, 0, gsi, true, true, loc);