The following fixes PR65517 - we need to mark loops for fixup if we
remove a path inside a loop.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2015-03-23  Richard Biener  <rguent...@suse.de>

        PR middle-end/65517
        * tree-cfg.c (remove_edge_and_dominated_blocks): Mark loops
        for fixup if necessary.

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

Index: gcc/testsuite/gcc.dg/torture/pr65517.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr65517.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr65517.c      (working copy)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+typedef void (*argmatch_exit_fn)();
+int a;
+void __argmatch_die () { __builtin_exit (0); }
+
+int
+main ()
+{
+  while (1)
+    {
+      argmatch_exit_fn b = __argmatch_die;
+      if (a)
+       b ();
+    }
+  return 0;
+}
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 221591)
+++ gcc/tree-cfg.c      (working copy)
@@ -7824,6 +7824,13 @@ remove_edge_and_dominated_blocks (edge e
   basic_block bb, dbb;
   bitmap_iterator bi;
 
+  /* If we are removing a path inside a non-root loop that may change
+     loop ownership of blocks or remove loops.  Mark loops for fixup.  */
+  if (current_loops
+      && loop_outer (e->src->loop_father) != NULL
+      && e->src->loop_father == e->dest->loop_father)
+    loops_state_set (LOOPS_NEED_FIXUP);
+
   if (!dom_info_available_p (CDI_DOMINATORS))
     {
       remove_edge (e);

Reply via email to