re PR tree-optimization/46130 (ICE: SIGSEGV in walk_stmt_load_store_addr_ops (gimple...
authorJakub Jelinek <jakub@redhat.com>
Thu, 20 Jan 2011 12:02:33 +0000 (13:02 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 20 Jan 2011 12:02:33 +0000 (13:02 +0100)
PR tree-optimization/46130
* ipa-split.c (consider_split): If return_bb contains non-virtual
PHIs other than for retval or if split_function would not adjust it,
refuse to split.

* gcc.dg/pr46130-1.c: New test.
* gcc.dg/pr46130-2.c: New test.

From-SVN: r169052

gcc/ChangeLog
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr46130-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr46130-2.c [new file with mode: 0644]

index ff8645e610601a79bdde519ad95b62e77c878390..466579a1792e8cbca850255e468e236cad4f842d 100644 (file)
@@ -1,3 +1,10 @@
+2011-01-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/46130
+       * ipa-split.c (consider_split): If return_bb contains non-virtual
+       PHIs other than for retval or if split_function would not adjust it,
+       refuse to split.
+
 2011-01-20  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/47167
index c72a36d67ee872febfc2a9afd1c62db250010b5a..30060440fe273b66c5248b50798064abb7f9c1fa 100644 (file)
@@ -411,9 +411,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
                 "  Refused: split part has non-ssa uses\n");
       return;
     }
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    fprintf (dump_file, "  Accepted!\n");
-
   /* See if retval used by return bb is computed by header or split part.
      When it is computed by split part, we need to produce return statement
      in the split part and add code to header to pass it around.
@@ -451,6 +448,30 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
   else
     current->split_part_set_retval = true;
 
+  /* split_function fixes up at most one PHI non-virtual PHI node in return_bb,
+     for the return value.  If there are other PHIs, give up.  */
+  if (return_bb != EXIT_BLOCK_PTR)
+    {
+      gimple_stmt_iterator psi;
+
+      for (psi = gsi_start_phis (return_bb); !gsi_end_p (psi); gsi_next (&psi))
+       if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi)))
+           && !(retval
+                && current->split_part_set_retval
+                && TREE_CODE (retval) == SSA_NAME
+                && !DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
+                && SSA_NAME_DEF_STMT (retval) == gsi_stmt (psi)))
+         {
+           if (dump_file && (dump_flags & TDF_DETAILS))
+             fprintf (dump_file,
+                      "  Refused: return bb has extra PHIs\n");
+           return;
+         }
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "  Accepted!\n");
+
   /* At the moment chose split point with lowest frequency and that leaves
      out smallest size of header.
      In future we might re-consider this heuristics.  */
index 07b41c8299edf40b5a247ddf286a107695dad908..c4880506aec48e3e4f8be7dcbce562780b78154f 100644 (file)
@@ -1,3 +1,9 @@
+2011-01-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/46130
+       * gcc.dg/pr46130-1.c: New test.
+       * gcc.dg/pr46130-2.c: New test.
+
 2011-01-19  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/47291
diff --git a/gcc/testsuite/gcc.dg/pr46130-1.c b/gcc/testsuite/gcc.dg/pr46130-1.c
new file mode 100644 (file)
index 0000000..a0a582d
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR tree-optimization/46130 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce" } */
+
+#include <stdarg.h>
+
+static void
+foo (va_list ap)
+{
+  va_arg (ap, char *)[0];
+}
+
+void
+bar (va_list ap)
+{
+  foo (ap);
+}
+
+void
+baz (va_list ap)
+{
+  foo (ap);
+}
diff --git a/gcc/testsuite/gcc.dg/pr46130-2.c b/gcc/testsuite/gcc.dg/pr46130-2.c
new file mode 100644 (file)
index 0000000..991e5dd
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR tree-optimization/46130 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce" } */
+
+extern int bar (int);
+
+static int foo (int x)
+{
+  int z, w;
+  if (x <= 1024)
+    {
+      z = 16;
+      w = 17;
+    }
+  else
+    {
+      bar (bar (bar (bar (bar (bar (bar (bar (bar (16)))))))));
+      if (x > 131072)
+       w = 19;
+      else
+       w = 21;
+      z = 32;
+    }
+  w = w + 121;
+  return z;
+}
+
+int
+baz (int x)
+{
+  return foo (x + 6) + foo (x + 15) + foo (x + 24);
+}