re PR middle-end/81564 (ICE in group_case_labels_stmt())
authorPeter Bergner <bergner@vnet.ibm.com>
Thu, 27 Jul 2017 14:05:14 +0000 (09:05 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Thu, 27 Jul 2017 14:05:14 +0000 (09:05 -0500)
gcc/
PR middle-end/81564
* tree-cfg.c (group_case_labels_stmt): Handle already deleted blocks.

gcc/testsuite/
PR middle-end/81564
* gcc.dg/pr81564.c: New test.

From-SVN: r250628

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

index 77a77ebca7f5507483679bd8017bdc2f74ffcbb1..05107fd93fcbc91fc936da6e01aed83539412e49 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-27  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR middle-end/81564
+       * tree-cfg.c (group_case_labels_stmt): Handle already deleted blocks.
+
 2017-07-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81573
index fe0b88c84fed7cfc05eccc9f255d498e0f78e34e..a57caaa65cb39dc45dba67e0455cf7abf4fb22db 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-27  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR middle-end/81564
+       * gcc.dg/pr81564.c: New test.
+
 2017-07-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81573
diff --git a/gcc/testsuite/gcc.dg/pr81564.c b/gcc/testsuite/gcc.dg/pr81564.c
new file mode 100644 (file)
index 0000000..1351999
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR middle-end/81564 ICE in group_case_labels_stmt().  */
+/* { dg-do compile }  */
+/* { dg-options "-O2" }  */
+
+struct a {
+    int b;
+    int c;
+};
+
+void
+foo (void)
+{
+  struct a *e;
+  switch (e->c)
+  {
+    case 7:
+    case 3:
+      if (__builtin_expect(!0, 0))
+       __builtin_unreachable();
+  }
+}
index 83e4ee60e9f24b23f35cf0e339a5330aaa12a81e..f664ffe119a222a988a55b592639629bfe4dd2ba 100644 (file)
@@ -1701,8 +1701,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.  */
-      if (base_bb == default_bb)
+      /* Discard cases that have the same destination as the default case or
+        whose destiniation blocks have already been removed as unreachable.  */
+      if (base_bb == NULL || base_bb == default_bb)
        {
          i++;
          continue;