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));