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

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Macleod from comment #4)
> This seems to be the issue?
> 
>   <bb 4> [local count: 350791453]:
>   _1 = g (i_3);
>   if (_1 != 0)
>     goto <bb 5>; [50.00%]
>   else
>     goto <bb 6>; [50.00%]
> 
>   <bb 5> [local count: 175395727]:
> 
>   <bb 6> [local count: 1063004408]:
>   # iftmp.0_4 = PHI <1(3), 0(4), 1(5)>
> 
> That 3 way PHI isn't used in any threads,  so we don't get a threaded path
> to the eventual return of 1.

The irreducible check is at least badly named - as written it does not
make the containing loop irreducible, instead it partly unrolls things.

But with that fixed we still reject the path in
jt_path_registry::cancel_invalid_paths by

2840          cancel_thread (&path, "Path crosses loop header but does not exit
it");

which is true again.  We can allow another subset of threads, but this
then enables the

path: 9->6->7->3->6

path which just duplicates one iteration which does not help.

We need to create a subloop or sibling loop w/o the call.  I don't see
offhand why this doesn't work - but then isolating a path will never
create a new loop(?)

I've played with the following.

diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index 23bfc14c8f0..2603d27f1f3 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -789,6 +789,7 @@ back_threader_profitability::profitable_path_p (const
vec<basic_block> &m_path,
   *creates_irreducible_loop = false;
   if (m_threaded_through_latch
       && loop == taken_edge->dest->loop_father
+      && taken_edge->dest != m_path[m_path.length () - 2]
       && (determine_bb_domination_status (loop, taken_edge->dest)
          == DOMST_NONDOMINATING))
     *creates_irreducible_loop = true;
diff --git a/gcc/tree-ssa-threadupdate.cc b/gcc/tree-ssa-threadupdate.cc
index 4e5c7566857..d91c0c7bf20 100644
--- a/gcc/tree-ssa-threadupdate.cc
+++ b/gcc/tree-ssa-threadupdate.cc
@@ -2811,6 +2811,10 @@ jt_path_registry::cancel_invalid_paths
(vec<jump_thread_edge *> &path)
       && flow_loop_nested_p (exit->dest->loop_father, exit->src->loop_father))
     return false;

+  // If we thread a whole loop round-trip, we are just creating a subloop
+  if (entry->dest == exit->dest)
+    return false;
+
   if (cfun->curr_properties & PROP_loop_opts_done)
     return false;

Reply via email to