[Bug middle-end/126887] backward threader cannot peel a single-iteration loop that the DOM threader peels

"rguenth at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126887

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #1)
> We hit
> 
>               if (e->flags & EDGE_ABNORMAL
>                   // This is like path_crosses_loops in profitable_path_p but
>                   // more restrictive to avoid peeling off loop iterations
> (see
>                   // tree-ssa/pr14341.c for an example).
>                   // ???  Note this restriction only applied when visiting an
>                   // interesting PHI with the former resolve_phi.
>                   || (!interesting_phis.is_empty ()
>                       && m_path[0]->loop_father != e->src->loop_father))
>                 continue;
> 
> in find_paths_to_names.  I guess we might want to defer this check and
> only disallow when the path exit condition resolves to not exiting the
> loop.  That is, the above tries to prevent peeling the first iteration
> for the case the exit test would be, say, i != 8 when the condition
> would resolve to know to stay inside the loop.  The above point of
> rejection is premature.
> 
> I suppose for policy rejection (rather than profitability rejection)
> m_registry.register_path would be responsible.  But maybe there's a similar
> enough check in the profitable_path_p that could be enhanced.
> 
> Let me give it a stab.

And then:

  // The backwards thread copier cannot copy blocks that do not belong
  // to the same loop, so when the new source of the path entry no
  // longer belongs to it we don't need to search further.
  else if (m_path[0]->loop_father != bb->loop_father)
    ;     

that would need to read "unless the threading does not duplicate the loop".
Aka, m_path[0]->loop_father would need to be the loop father of the
destination of the taken edge of the branch at the path exit.

We then get

maybe_register_phi_relation in bb5: Registering killing_def (path_oracle) i_1
 Registering value_relation (path_oracle) (i_8 == i_1) (root: bb2)
Checking profitability of path (backwards):
  [4] Registering jump thread: (2, 4) incoming edge;  (4, 5) normal (5, 6)
nocopy;  
path: 2->4->5->6 SUCCESS
Checking profitability of path (backwards):  bb:5 (4 insns) bb:7 (latch)
  Control statement insns: 2
  Overall: 2 insns

but fail the "subloop" sanity check in duplicate_thread_path.  Fixing that
makes the path threaded in thread2.  The subloop check prevents peeling
in this case.  But for the following both thread2 and threadfull2 would
peel one iteration:

volatile unsigned sink;

void
f (int flag, unsigned n)
{
  unsigned i = /*flag*/ 1 ? 0 : n;
  do
    {
      sink = i;
      i += 4;
    }
  while (i != 128);
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.