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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org
             Blocks|                            |107997
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
ip_normal_pos doesn't handle loops where the exit block isn't the single-pred
of the loop latch.  Usually IVOPTs guards things against this situation, but it
doesn't work here as we have two IV candidates, and the
loop looking originally as

<bb 6> [local count: 1073741824]:
# e__lsm.6_16 = PHI <e__lsm.6_18(4), _7(5)>
# f_lsm.7_17 = PHI <f_lsm.7_19(4), _8(5)>
g:
_4 = f_lsm.7_17 + 1;
_5 = b[_4];
_6 = (long unsigned int) _5;
_7 = _6 ^ e__lsm.6_16;
_8 = f_lsm.7_17 + -1;
if (_8 != 0)
  goto <bb 5>; [89.00%]
else
  goto <bb 7>; [11.00%]

<bb 5> [local count: 955630224]:
__asm__ __volatile__ goto("" :  :  :  : "g" g);

but inserting one at IP_END first splits the latch block, making the
next IP_NORMAL_POS fail (we are re-computing the insert interator
during transform).

Note that LOOPS_HAVE_SIMPLE_LATCHES documents latches should have a single
successor, not that they should end in a non-branch.

Arguably

static void
create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
{ 
...
    case IP_END:
      incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
      after = true;  
      if (!gsi_end_p (incr_pos) && stmt_ends_bb_p (gsi_stmt (incr_pos)))
        {
          edge e = find_edge (gsi_bb (incr_pos), data->current_loop->header);
          incr_pos = gsi_after_labels (split_edge (e));
          after = false;

breaks the initial analysis for IP_NORMAL_POS IVs.

Ordering IVs before creating them could be a workaround - simply inserting
before the control stmt for IP_END another.

This was caused by r13-4594-g7676235f690e62 which introduces the above.

Arguably an asm goto might refer to IVs, so to avoid overlapping lifetimes
incrementing after is better for coalescing.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107997
[Bug 107997] [10/11/12/13 Regression] r13-4389-gfd8dd6c0384969 probably
uncovered an issue building the Linux kernel

Reply via email to