re PR middle-end/80775 (-O3 produces ice in group_case_labels_stmt)
authorPeter Bergner <bergner@vnet.ibm.com>
Wed, 17 May 2017 14:05:21 +0000 (09:05 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Wed, 17 May 2017 14:05:21 +0000 (09:05 -0500)
gcc/
PR middle-end/80775
* tree-cfg.c: Move deletion of unreachable case statements to after
the merging of consecutive case labels.

gcc/testsuite/
PR middle-end/80775
* gcc.dg/pr80775.c: New test.

From-SVN: r248155

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr80775.c [new file with mode: 0644]
gcc/tree-cfg.c

index 4668e35..004c7bb 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-17  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR middle-end/80775
+       * tree-cfg.c: Move deletion of unreachable case statements to after
+       the merging of consecutive case labels.
+
 2017-05-17  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Refer
index 44f5841..8f62adb 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-17  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR middle-end/80775
+       * gcc.dg/pr80775.c: New test.
+
 2017-05-17  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/80659
diff --git a/gcc/testsuite/gcc.dg/pr80775.c b/gcc/testsuite/gcc.dg/pr80775.c
new file mode 100644 (file)
index 0000000..df4d250
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR middle-end/80775 ICE: -O3 produces ice in group_case_labels_stmt.  */
+/* { dg-do compile }  */
+/* { dg-options "-O3" }  */
+
+typedef struct { short a; } b;
+b c[10];
+int d, e, f, g, h;
+int
+i (void)
+{
+  f = 0;
+  for (; f < e; f++) {
+    switch (g) {
+    case 1:
+      d = 1;
+    case 2:
+      c[2 + f].a = 1;
+    }
+    h += c[f].a;
+  }
+}
index e046a13..ba19661 100644 (file)
@@ -1661,7 +1661,7 @@ void
 group_case_labels_stmt (gswitch *stmt)
 {
   int old_size = gimple_switch_num_labels (stmt);
-  int i, j, new_size = old_size;
+  int i, j, base_index, new_size = old_size;
   basic_block default_bb = NULL;
 
   default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
@@ -1678,16 +1678,9 @@ group_case_labels_stmt (gswitch *stmt)
       gcc_assert (base_case);
       base_bb = label_to_block (CASE_LABEL (base_case));
 
-      /* Discard cases that have the same destination as the default case
-        or if their destination block is unreachable.  */
-      if (base_bb == default_bb
-         || (EDGE_COUNT (base_bb->succs) == 0
-             && gimple_seq_unreachable_p (bb_seq (base_bb))))
+      /* Discard cases that have the same destination as the default case.  */
+      if (base_bb == default_bb)
        {
-         edge e;
-         if (base_bb != default_bb
-             && (e = find_edge (gimple_bb (stmt), base_bb)) != NULL)
-           remove_edge_and_dominated_blocks (e);
          gimple_switch_set_label (stmt, i, NULL_TREE);
          i++;
          new_size--;
@@ -1697,7 +1690,7 @@ group_case_labels_stmt (gswitch *stmt)
       base_high = CASE_HIGH (base_case)
          ? CASE_HIGH (base_case)
          : CASE_LOW (base_case);
-      i++;
+      base_index = i++;
 
       /* Try to merge case labels.  Break out when we reach the end
         of the label vector or when we cannot merge the next case
@@ -1723,6 +1716,18 @@ group_case_labels_stmt (gswitch *stmt)
          else
            break;
        }
+
+      /* Discard cases that have an unreachable destination block.  */
+      if (EDGE_COUNT (base_bb->succs) == 0
+         && gimple_seq_unreachable_p (bb_seq (base_bb)))
+       {
+         edge base_edge = find_edge (gimple_bb (stmt), base_bb);
+         if (base_edge != NULL)
+           remove_edge_and_dominated_blocks (base_edge);
+         gimple_switch_set_label (stmt, base_index, NULL_TREE);
+         new_size--;
+         i++;
+       }
     }
 
   /* Compress the case labels in the label vector, and adjust the