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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|target                      |rtl-optimization
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=121829
                 CC|                            |ebotcazou at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Robin Dapp from comment #2)
> Happens in vsetvl but during the initialization phase when we call
> loop_optimizer_init which does checking_verify_loop_structure.  Maybe the
> loop structure has been broken for several passes already and we only notice
> in vsetvl?

The pass manager verifies loop structure after each pass.

> ;; basic block 3, loop depth 1, count 1073741824 (estimated locally, freq
> 9.0909), maybe hot
> ;;  prev block 6, next block 4, flags: (REACHABLE, RTL, MODIFIED)
> ;;  pred:       6 [always]  count:955630224 (estimated locally, freq 8.0909)
> (FALLTHRU,DFS_BACK)
> ;;              2 [50.0% (adjusted)]  count:59055800 (estimated locally,
> freq 0.5000)
> ;;              5 [always]  count:59055800 (estimated locally, freq 0.5000)
> 
> The loop is being changed by apply_loop_flags before verifying it.

Unlikely but not impossible that this wrecks it.  I see:

t.c:10:1: error: loop 1’s header does not have exactly 2 entries
   10 | }
      | ^
during RTL pass: vsetvl
t.c:10:1: internal compiler error: in verify_loop_structure, at cfgloop.cc:1741

and indeed there's a missing preheader.  Before loop_optimizer_init ()
we have

(code_label 10 8 11 3 4 ("j") [2 uses])
(note 11 10 12 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(jump_insn 12 11 13 3 (asm_operands/v ("#asm2") ("") 0 []
         []
         [
            (label_ref:DI 10)
        ] t.c:15) "t.c":15:3 -1
     (nil)
 -> 10)

as loop (single block, but with asm goto).  We then split the entry
edge to create a preheader but that messes up the asm goto in BB 2.
This looks very similar to the situation in PR121829.  We do _not_
create a forwarder block on RTL.

But the problematic transform is force_single_succ_latches (), which does
simply split_edge () on the latch edge and that in turn messes up the
preheader because of:

  /* We are going to place the new block in front of edge destination.
     Avoid existence of fallthru predecessors.  */
  if ((edge_in->flags & EDGE_FALLTHRU) == 0)
    { 
      edge e = find_fallthru_edge (edge_in->dest->preds);

      if (e) 
        force_nonfallthru (e);
    }

and force_nonfallthru_and_redirect does not seem to handle asm goto
correctly and we end up with a diamond.

I'm not very familiar with cfgrtl.cc, but clearly what force_nonfallthru
above does looks weird (if not wrong).  Seems like a latent issue though,
possibly to avoid in the risc backend if you avoid LOOPS_NORMAL but
use AVOID_CFG_MANIPULATION - unsure if you need any of the things
LOOPS_NORMAL gets you.

diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc
index 81b64f7d063..0455c901c45 100644
--- a/gcc/cfgloopmanip.cc
+++ b/gcc/cfgloopmanip.cc
@@ -1623,9 +1623,11 @@ create_preheader (class loop *loop, int flags)
                     should not end with a control instruction.  */
                  /* ???  This, and below JUMP_P check needs to be a new
                     CFG hook.  */
-                 || (cfun->curr_properties & PROP_gimple
-                     && !gsi_end_p (gsi_last_bb (single_entry->src))
-                     && stmt_ends_bb_p (*gsi_last_bb (single_entry->src)))))
+                 || ((cfun->curr_properties & PROP_gimple
+                      && !gsi_end_p (gsi_last_bb (single_entry->src))
+                      && stmt_ends_bb_p (*gsi_last_bb (single_entry->src))
+                      || (cfun->curr_properties & PROP_rtl
+                          && JUMP_P (BB_END (single_entry->src)))))))
             need_forwarder_block = true;
           /* If we want fallthru preheaders, also create forwarder block when

avoids the issue (extending the PR121829 fix to RTL).

Reply via email to