re PR tree-optimization/71802 (gcc ICE at -O3 on valid code on x86_64-linux-gnu in...
authorRichard Biener <rguenther@suse.de>
Tue, 9 Aug 2016 07:40:50 +0000 (07:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 9 Aug 2016 07:40:50 +0000 (07:40 +0000)
2016-08-09  Richard Biener  <rguenther@suse.de>

PR tree-optimization/71802
* tree-cfgcleanup.c (cleanup_tree_cfg_bb): Make sure to catch
all merge opportunities with the predecessor.

* gcc.dg/torture/pr71802.c: New testcase.

From-SVN: r239274

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr71802.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index eb0dc1d014e8ce6e85541ebeb88941bcefe621ee..2d96f88466a78ba61ebb3dc9bb9db0ea5961f1eb 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-09  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/71802
+       * tree-cfgcleanup.c (cleanup_tree_cfg_bb): Make sure to catch
+       all merge opportunities with the predecessor.
+
 2016-08-09  Richard Biener  <rguenther@suse.de>
 
        PR ipa/68273
index f560fe45433cdb69f4d6a4a184f0bab0b331e317..9ba1052e76806641a34eedb92899073bd30dabc2 100644 (file)
@@ -1,3 +1,8 @@
+2016-08-09  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/71802
+       * gcc.dg/torture/pr71802.c: New testcase.
+
 2016-08-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/72809
diff --git a/gcc/testsuite/gcc.dg/torture/pr71802.c b/gcc/testsuite/gcc.dg/torture/pr71802.c
new file mode 100644 (file)
index 0000000..0dd1467
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+
+int b, c;
+long d, f;
+void fn1()
+{
+  char g;
+  long long h = 0;
+  int *i;
+  if (0) {
+L2:
+      b && (b = f);
+      d = 3;
+      for (; d;) {
+         char *j = &g;
+         c = *j = 0;
+L3:
+         *j %= b;
+         for (; g <= 4;)
+           ;
+      }
+      goto L2;
+  }
+  for (; *i; *i = 1) {
+      if ((h -= 4) == (h != (b ?: d))) {
+         g = 3;
+         goto L3;
+      }
+      i = (int *)&h;
+      *i = f;
+      i = (int *)&f;
+      if ((h && 6) - (h = 0))
+       goto L2;
+  }
+  for (; d;)
+    goto L3;
+}
index ab8a9139f76f2be8c20dc74d1e4ccd8c882e8199..3fe0d3e89941579348c01a94adcc83737d37e447 100644 (file)
@@ -641,24 +641,25 @@ cleanup_tree_cfg_bb (basic_block bb)
       && remove_forwarder_block (bb))
     return true;
 
+  /* If there is a merge opportunity with the predecessor
+     do nothing now but wait until we process the predecessor.
+     This happens when we visit BBs in a non-optimal order and
+     avoids quadratic behavior with adjusting stmts BB pointer.  */
+  if (single_pred_p (bb)
+      && can_merge_blocks_p (single_pred (bb), bb))
+    /* But make sure we _do_ visit it.  When we remove unreachable paths
+       ending in a backedge we fail to mark the destinations predecessors
+       as changed.  */
+    bitmap_set_bit (cfgcleanup_altered_bbs, single_pred (bb)->index);
+
   /* Merging the blocks may create new opportunities for folding
      conditional branches (due to the elimination of single-valued PHI
      nodes).  */
-  if (single_succ_p (bb)
-      && can_merge_blocks_p (bb, single_succ (bb)))
+  else if (single_succ_p (bb)
+          && can_merge_blocks_p (bb, single_succ (bb)))
     {
-      /* If there is a merge opportunity with the predecessor
-         do nothing now but wait until we process the predecessor.
-        This happens when we visit BBs in a non-optimal order and
-        avoids quadratic behavior with adjusting stmts BB pointer.  */
-      if (single_pred_p (bb)
-         && can_merge_blocks_p (single_pred (bb), bb))
-       ;
-      else
-       {
-         merge_blocks (bb, single_succ (bb));
-         return true;
-       }
+      merge_blocks (bb, single_succ (bb));
+      return true;
     }
 
   return false;