http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52756

--- Comment #6 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-04-02 
11:38:59 UTC ---
It doesn't work, as we expect loop_latch_edge () to work during further
threading.
It also does not work because we miss some threadings and thus hit the assert
that e->aux is NULL after threading is done.

The issue is that we thread both the latch and the loop entry edge.  But the
code special casing each case does not consider that both may happen at
the same time.  If we'd re-start at thread_through_loop_header for the case
in this bug we'd fail, as the entry edges THREAD_TARGET2 is set.

Thus, I'll try again with

Index: gcc/tree-ssa-threadupdate.c
===================================================================
--- gcc/tree-ssa-threadupdate.c (revision 186066)
+++ gcc/tree-ssa-threadupdate.c (working copy)
@@ -838,6 +838,7 @@ thread_through_loop_header (struct loop
   edge_iterator ei;
   basic_block tgt_bb, atgt_bb;
   enum bb_dom_status domst;
+  bool threaded_latch = false;

   /* We have already threaded through headers to exits, so all the threading
      requests now are to the inside of the loop.  We need to avoid creating
@@ -908,6 +909,7 @@ thread_through_loop_header (struct loop
   if (single_succ_p (header))
     goto fail;

+thread_rest:
   if (latch->aux)
     {
       if (THREAD_TARGET2 (latch))
@@ -916,7 +918,7 @@ thread_through_loop_header (struct loop
       tgt_bb = tgt_edge->dest;
     }
   else if (!may_peel_loop_headers
-          && !redirection_block_p (loop->header))
+          && !redirection_block_p (header))
     goto fail;
   else
     {
@@ -950,7 +952,7 @@ thread_through_loop_header (struct loop
       if (!tgt_bb)
        {
          /* There are no threading requests.  */
-         return false;
+         return threaded_latch;
        }

       /* Redirecting to empty loop latch is useless.  */
@@ -971,7 +973,7 @@ thread_through_loop_header (struct loop
       loop->header = NULL;
       loop->latch = NULL;
       loops_state_set (LOOPS_NEED_FIXUP);
-      return thread_block (header, false);
+      return threaded_latch | thread_block (header, false);
     }

   if (tgt_bb->loop_father->header == tgt_bb)
@@ -994,9 +996,10 @@ thread_through_loop_header (struct loop
       loop->latch = thread_single_edge (latch);
       gcc_assert (single_succ (loop->latch) == tgt_bb);
       loop->header = tgt_bb;
+      threaded_latch = true;

       /* Thread the remaining edges through the former header.  */
-      thread_block (header, false);
+      goto thread_rest;
     }
   else
     {
@@ -1039,7 +1042,7 @@ fail:
       free (e->aux);
       e->aux = NULL;
     }
-  return false;
+  return threaded_latch;
 }

 /* Walk through the registered jump threads and convert them into a

Reply via email to