https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80549

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok.  So the issue is that the irreducible region becomes reducible after DOM1
which means cfg-cleanup ends up with a CFG that has the former exit edge
of loop 2 turned into an additional latch (re-starting the loop IV at 5).
This invalidates the number of iteration upper bounds.

So the error lies in fix_loop_structure which fails to reset the upper
bound / estimates.  Doing so unconditionally is quite a hammer (but well,
we shouldn't do fix_loop_structure so often...).  I don't see a good way
to detect this situation though (given in fixup we can't rely on
irreducible flags being set for example, neither can we at the start of
CFG cleanup).

The easiest thing would be if we can rely on the loop not be re-discovered
as loop 2.

Maybe we can, in CFG cleanup, ensure that we have preheaders.  Like the
following:

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c       (revision 247362)
+++ gcc/tree-cfgcleanup.c       (working copy)
@@ -766,6 +766,26 @@ cleanup_tree_cfg_noloop (void)
       changed = false;
     }

+  /* Make sure existing loops have preheaders as we need to preserve
+     the existing loop structure to not wreck niter bounds and generally
+     regions identified as a specific loop.  */
+  if (current_loops)
+    {
+      /* ???  To be able to use create_preheaders we have to first
+         fixup loops.  Another possibility is to refactor it somehow
+        and rely on bb_loop_header_p and a full CFG walk, also handling
+        multiple latches.  */
+      if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+       fix_loop_structure (NULL);
+      if (! loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
+       {
+         if (loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
+           disambiguate_loops_with_multiple_latches ();
+         create_preheaders (LOOPS_HAVE_PREHEADERS);
+         loops_state_clear (LOOPS_HAVE_PREHEADERS);
+       }
+    }
+
   changed |= cleanup_tree_cfg_1 ();

   gcc_assert (dom_info_available_p (CDI_DOMINATORS));

Reply via email to