ifcvt is confused about fake edges not being loop exits which the 
following fixes.

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

2016-05-10  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/70986
        * cfganal.c: Include cfgloop.h.
        (connect_infinite_loops_to_exit): Properly register fake edges
        as loop exits.

        * gcc.dg/torture/pr70986-1.c: New testcase.
        * gcc.dg/torture/pr70986-2.c: Likewise.
        * gcc.dg/torture/pr70986-3.c: Likewise.

Index: gcc/cfganal.c
===================================================================
--- gcc/cfganal.c       (revision 236069)
+++ gcc/cfganal.c       (working copy)
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.
 #include "cfghooks.h"
 #include "timevar.h"
 #include "cfganal.h"
+#include "cfgloop.h"
 
 /* Store the data structures necessary for depth-first search.  */
 struct depth_first_search_ds {
@@ -602,7 +603,10 @@ connect_infinite_loops_to_exit (void)
        break;
 
       deadend_block = dfs_find_deadend (unvisited_block);
-      make_edge (deadend_block, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
+      edge e = make_edge (deadend_block, EXIT_BLOCK_PTR_FOR_FN (cfun),
+                         EDGE_FAKE);
+      if (current_loops != NULL)
+       rescan_loop_exit (e, true, false);
       flow_dfs_compute_reverse_add_bb (&dfs_ds, deadend_block);
     }
 
Index: gcc/testsuite/gcc.dg/torture/pr70986-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr70986-1.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr70986-1.c    (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+int a, g;
+char b, c;
+short d, e, f;
+
+char
+fn1 ()
+{
+  return a ? a : 1;
+}
+
+void
+fn2 ()
+{
+  char h;
+  for (; d;)
+    for (; e; e++)
+      c = (fn1 () && h) & !(f |= 9 ^ (b > (g = c)));
+  for (;;)
+    ;
+}
Index: gcc/testsuite/gcc.dg/torture/pr70986-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr70986-2.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr70986-2.c    (working copy)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int gi, dg;
+
+void
+fe (void)
+{
+  int ka = gi;
+
+  for (;;)
+    {
+      if (ka != 0)
+       {
+         if (dg != 0)
+           gi = 0;
+         ++ka;
+       }
+      ++dg;
+    }
+}
Index: gcc/testsuite/gcc.dg/torture/pr70986-3.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr70986-3.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr70986-3.c    (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+int a, b;
+int
+fn1 (int p1)
+{
+  return p1 < 0 ? p1 : a;
+}
+
+void
+fn2 ()
+{
+lbl_100:
+  b = 1;
+  for (; b != 21; b = fn1 (b))
+    ;
+  goto lbl_100;
+}

Reply via email to