re PR tree-optimization/71520 (Missing cross-jumping of switch cases)
authorJakub Jelinek <jakub@redhat.com>
Tue, 14 Jun 2016 10:20:04 +0000 (12:20 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 14 Jun 2016 10:20:04 +0000 (12:20 +0200)
PR tree-optimization/71520
* tree-ssa-tail-merge.c (find_duplicate): Handle labels.
(replace_block_by): Move user labels from bb1 to bb2.

* gcc.dg/tree-ssa/pr71520.c: New test.

From-SVN: r237427

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr71520.c [new file with mode: 0644]
gcc/tree-ssa-tail-merge.c

index 40e60a3db344d652b74e8d58125939a9f470e078..1a3e5fdd907b5256e9c9787126e309ec30c37818 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/71520
+       * tree-ssa-tail-merge.c (find_duplicate): Handle labels.
+       (replace_block_by): Move user labels from bb1 to bb2.
+
 2016-06-14  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/71310
index 8763aad7556b12edaa1710564d5cf6bd08f1b179..a61661455e363b3ab959a6df3ee391e93aef40f3 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/71520
+       * gcc.dg/tree-ssa/pr71520.c: New test.
+
 2016-06-14  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/71521
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71520.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71520.c
new file mode 100644 (file)
index 0000000..f647a5b
--- /dev/null
@@ -0,0 +1,90 @@
+/* PR tree-optimization/71520 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar (int);
+
+void
+foo (int x)
+{
+  switch (x)
+    {
+    case 1:
+    case 12:
+    case 28:
+    case 174:
+      bar (1);
+      bar (2);
+      break;
+    case 3:
+    case 7:
+    case 78:
+    case 96:
+    case 121:
+    default:
+      bar (3);
+      bar (4);
+      bar (5);
+      bar (6);
+      break;
+    case 8:
+    case 13:
+    case 27:
+    case 19:
+    case 118:
+      bar (3);
+      bar (4);
+      bar (5);
+      bar (6);
+      break;
+    case 4:
+      bar (7);
+      break;
+    }
+}
+
+void
+baz (int x)
+{
+  switch (x)
+    {
+    case 1:
+    case 12:
+    case 28:
+    case 174:
+      bar (8);
+      bar (9);
+      break;
+    case 3:
+    case 7:
+    case 78:
+    case 96:
+    case 121:
+    default:
+    lab1:
+    lab2:
+      bar (10);
+      bar (11);
+      bar (12);
+      bar (13);
+      break;
+    case 8:
+    case 13:
+    case 27:
+    case 19:
+    case 118:
+    lab3:
+    lab4:
+      bar (10);
+      bar (11);
+      bar (12);
+      bar (13);
+      break;
+    case 4:
+      bar (14);
+      break;
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "bar \\\(3\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bar \\\(10\\\);" 1 "optimized" } } */
index 3df41fd08fcb9610138a5ef6d1483ebf93fb57a9..042d9646b74f4afd5fe72ccb6d81893f4e4960c7 100644 (file)
@@ -1265,6 +1265,10 @@ find_duplicate (same_succ *same_succ, basic_block bb1, basic_block bb2)
       gimple *stmt1 = gsi_stmt (gsi1);
       gimple *stmt2 = gsi_stmt (gsi2);
 
+      if (gimple_code (stmt1) == GIMPLE_LABEL
+         && gimple_code (stmt2) == GIMPLE_LABEL)
+       break;
+
       if (!gimple_equal_p (same_succ, stmt1, stmt2))
        return;
 
@@ -1277,6 +1281,20 @@ find_duplicate (same_succ *same_succ, basic_block bb1, basic_block bb2)
       gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
     }
 
+  while (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+    {
+      tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
+      if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+       return;
+      gsi_prev (&gsi1);
+    }
+  while (!gsi_end_p (gsi2) && gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL)
+    {
+      tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)));
+      if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+       return;
+      gsi_prev (&gsi2);
+    }
   if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
     return;
 
@@ -1555,6 +1573,23 @@ replace_block_by (basic_block bb1, basic_block bb2)
       e2->probability = GCOV_COMPUTE_SCALE (e2->count, out_sum);
     }
 
+  /* Move over any user labels from bb1 after the bb2 labels.  */
+  gimple_stmt_iterator gsi1 = gsi_start_bb (bb1);
+  if (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+    {
+      gimple_stmt_iterator gsi2 = gsi_after_labels (bb2);
+      while (!gsi_end_p (gsi1)
+            && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+       {
+         tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
+         gcc_assert (!DECL_NONLOCAL (label) && !FORCED_LABEL (label));
+         if (DECL_ARTIFICIAL (label))
+           gsi_next (&gsi1);
+         else
+           gsi_move_before (&gsi1, &gsi2);
+       }
+    }
+
   /* Clear range info from all stmts in BB2 -- this transformation
      could make them out of date.  */
   reset_flow_sensitive_info_in_bb (bb2);