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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Alexander Monakov from comment #4)
> It seems to avoid this sort of gotchas cleanup_cfg should
> 
>   gcc_checking_assert (!dom_info_available_p (CDI_DOMINATORS));
>   gcc_checking_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
> 
> but maybe there's a deeper reason it's not done already — I cannot be sure.

It already does it in a not always executed path:

  /* ???  We probably do this way too often.  */
  if (current_loops
      && (changed
          || (mode & CLEANUP_CFG_CHANGED)))
    {
      timevar_push (TV_REPAIR_LOOPS);
      /* The above doesn't preserve dominance info if available.  */
      gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
      calculate_dominance_info (CDI_DOMINATORS);

hardening this contract might be a good idea but expect some fallout.  I
think the correct mode-switching local fix is to do

diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index ef6f6e1984c..2ff21a40081 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -856,7 +856,10 @@ optimize_mode_switching (void)
     commit_edge_insertions ();

   if (targetm.mode_switching.entry && targetm.mode_switching.exit)
-    cleanup_cfg (CLEANUP_NO_INSN_DEL);
+    {
+      free_dominance_info (CDI_DOMINATORS);
+      cleanup_cfg (CLEANUP_NO_INSN_DEL);
+    }
   else if (!need_commit && !emitted)
     return 0;

Reply via email to