re PR middle-end/65048 (ICE in add_phi_args_after_copy_edge, at tree-cfg.c)
authorSebastian Pop <s.pop@samsung.com>
Thu, 26 Feb 2015 13:56:39 +0000 (13:56 +0000)
committerJeff Law <law@gcc.gnu.org>
Thu, 26 Feb 2015 13:56:39 +0000 (06:56 -0700)
PR tree-optimization/65048
* tree-ssa-threadupdate.c (valid_jump_thread_path): New.
(thread_through_all_blocks): Call valid_jump_thread_path.
Remove invalid FSM jump-thread paths.

PR tree-optimization/65048
* gcc.dg/tree-ssa/ssa-dom-thread-9.c: New.

From-SVN: r221007

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c [new file with mode: 0644]
gcc/tree-ssa-threadupdate.c

index 98a0d24f03193fc5d57b2aa6ca8350ba98e7daa9..73ef79d4ea484bcf27ba4b836701dbcaf7655e4f 100644 (file)
@@ -1,3 +1,10 @@
+2015-02-26  Sebastian Pop  <s.pop@samsung.com>
+
+       PR tree-optimization/65048
+       * tree-ssa-threadupdate.c (valid_jump_thread_path): New.
+       (thread_through_all_blocks): Call valid_jump_thread_path.
+       Remove invalid FSM jump-thread paths.
+
 2015-02-26  Jakub Jelinek  <jakub@redhat.com>
 
        * passes.c (ipa_write_summaries_1): Call lto_output_init_mode_table.
index b1efb2b5bca1a2deb96395e15978e9f75aa211ce..f7854082264f8e4e240f85f2d82c5b16d16e0c86 100644 (file)
@@ -1,3 +1,8 @@
+2015-02-26  Sebastian Pop  <s.pop@samsung.com>
+
+       PR tree-optimization/65048
+       * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New.
+
 2015-02-26  Uros Bizjak  <ubizjak@gmail.com>
 
        * lib/gcc-dg.exp (cleanup-final-insns-dump): New procedure.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
new file mode 100644 (file)
index 0000000..6be4203
--- /dev/null
@@ -0,0 +1,50 @@
+/* PR 65048 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d;
+void fn (void);
+
+int
+foo (x)
+{
+  switch (x)
+    {
+    case 'A':
+      return 'T';
+    case 'U':
+      return 'A';
+    }
+}
+
+void
+bar (int x, int y)
+{
+  switch (c)
+    {
+    case 'U':
+      switch (x)
+       {
+       default:
+         fn ();
+       case 'G':
+         switch (y)
+           {
+           case 'A':
+             d = 7;
+           }
+       }
+    }
+}
+
+void
+baz (void)
+{
+  while (1)
+    {
+      a = foo ();
+      b = foo ();
+      bar (a, b);
+    }
+}
+
index 3326144fe75ce552bc11feb601b38cd895f96ab3..7a41ab247b649c6b135355635ad10e8c7c73ae16 100644 (file)
@@ -2473,6 +2473,21 @@ duplicate_seme_region (edge entry, edge exit,
   return true;
 }
 
+/* Return true when PATH is a valid jump-thread path.  */
+
+static bool
+valid_jump_thread_path (vec<jump_thread_edge *> *path)
+{
+  unsigned len = path->length ();
+
+  /* Check that the path is connected.  */
+  for (unsigned int j = 0; j < len - 1; j++)
+    if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
+      return false;
+
+  return true;
+}
+
 /* Walk through all blocks and thread incoming edges to the appropriate
    outgoing edge for each edge pair recorded in THREADED_EDGES.
 
@@ -2505,12 +2520,25 @@ thread_through_all_blocks (bool may_peel_loop_headers)
       vec<jump_thread_edge *> *path = paths[i];
       edge entry = (*path)[0]->e;
 
-      if ((*path)[0]->type != EDGE_FSM_THREAD
-         /* Do not jump-thread twice from the same block.  */
-         || bitmap_bit_p (threaded_blocks, entry->src->index)) {
-       i++;
-       continue;
-      }
+      /* Only code-generate FSM jump-threads in this loop.  */
+      if ((*path)[0]->type != EDGE_FSM_THREAD)
+       {
+         i++;
+         continue;
+       }
+
+      /* Do not jump-thread twice from the same block.  */
+      if (bitmap_bit_p (threaded_blocks, entry->src->index)
+         /* Verify that the jump thread path is still valid: a
+            previous jump-thread may have changed the CFG, and
+            invalidated the current path.  */
+         || !valid_jump_thread_path (path))
+       {
+         /* Remove invalid FSM jump-thread paths.  */
+         delete_jump_thread_path (path);
+         paths.unordered_remove (i);
+         continue;
+       }
 
       unsigned len = path->length ();
       edge exit = (*path)[len - 1]->e;