re PR tree-optimization/71661 (wrong code at -O3)
authorJeff Law <law@redhat.com>
Thu, 6 Oct 2016 16:23:22 +0000 (10:23 -0600)
committerJeff Law <law@gcc.gnu.org>
Thu, 6 Oct 2016 16:23:22 +0000 (10:23 -0600)
PR tree-optimization/71661
* tree-cfgcleanup.c (remove_forwarder_block_with_phi): Handle case when
removal of a forwarder exposes a new natural loop.

PR tree-optimization/71661
* gcc.dg/tree-ssa/pr71661.c: New test.

From-SVN: r240836

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

index 6b8acef79bc9527b5d4941dff87fa12bf51bb8e6..0092be861e84f16aa89d755b1baf2366f58962b7 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-05  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/71661
+       * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Handle case when
+       removal of a forwarder exposes a new natural loop.
+
 2016-10-06  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/sse.md (andnot<mode>3): Add FALLTHRU comments.
index e180375cd7cd8b76f4dc7d6c5fcb7addab2ace4b..56f1c8dbd406a6344f31616689975ebf96debb04 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-06  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/71661
+       * gcc.dg/tree-ssa/pr71661.c: New test.
+
 2016-10-06  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/77855
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71661.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71661.c
new file mode 100644 (file)
index 0000000..c273ea1
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fdisable-tree-ethread" } */
+
+extern void exit (int);
+
+int a, b;
+
+void
+fn1 ()
+{
+  unsigned c = 0;
+  int d;
+  b = a;
+  if (a < 0)
+    goto L1;
+  for (; a < 1; a++)
+    d = 0;
+  for (; d < 2; d++)
+    {
+      for (c = 0; c < 3; c++)
+      L1:
+        a = 2;
+    }
+}
+
+int
+main ()
+{
+  fn1 ();
+  exit (0);
+}
index 6052872cb575da1f09eae257f48868d5f0fec103..21873f8d516c2e27836f95e6eb002359bde04d50 100644 (file)
@@ -840,6 +840,11 @@ remove_forwarder_block_with_phi (basic_block bb)
   if (dest == bb)
     return false;
 
+  /* Removal of forwarders may expose new natural loops and thus
+     a block may turn into a loop header.  */
+  if (current_loops && bb_loop_header_p (bb))
+    return false;
+
   /* If the destination block consists of a nonlocal label, do not
      merge it.  */
   label = first_stmt (dest);