The following fixes PR54520 - we were not updating bb->loop_father
for all basic-blocks converted to "pre-header" blocks during jump
threading.  Fixed as follows.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2012-09-10  Richard Guenther  <rguent...@suse.de>

        * tree-ssa-threadupdate.c (def_split_header_continue_p):
        Properly consider sub-loops.

Index: gcc/tree-ssa-threadupdate.c
===================================================================
*** gcc/tree-ssa-threadupdate.c (revision 191129)
--- gcc/tree-ssa-threadupdate.c (working copy)
*************** static bool
*** 846,853 ****
  def_split_header_continue_p (const_basic_block bb, const void *data)
  {
    const_basic_block new_header = (const_basic_block) data;
!   return (bb->loop_father == new_header->loop_father
!         && bb != new_header);
  }
  
  /* Thread jumps through the header of LOOP.  Returns true if cfg changes.
--- 846,854 ----
  def_split_header_continue_p (const_basic_block bb, const void *data)
  {
    const_basic_block new_header = (const_basic_block) data;
!   return (bb != new_header
!         && (loop_depth (bb->loop_father)
!             >= loop_depth (new_header->loop_father)));
  }
  
  /* Thread jumps through the header of LOOP.  Returns true if cfg changes.
*************** thread_through_loop_header (struct loop
*** 1031,1040 ****
        nblocks = dfs_enumerate_from (header, 0, def_split_header_continue_p,
                                    bblocks, loop->num_nodes, tgt_bb);
        for (i = 0; i < nblocks; i++)
!       {
!         remove_bb_from_loops (bblocks[i]);
!         add_bb_to_loop (bblocks[i], loop_outer (loop));
!       }
        free (bblocks);
  
        /* If the new header has multiple latches mark it so.  */
--- 1032,1042 ----
        nblocks = dfs_enumerate_from (header, 0, def_split_header_continue_p,
                                    bblocks, loop->num_nodes, tgt_bb);
        for (i = 0; i < nblocks; i++)
!       if (bblocks[i]->loop_father == loop)
!         {
!           remove_bb_from_loops (bblocks[i]);
!           add_bb_to_loop (bblocks[i], loop_outer (loop));
!         }
        free (bblocks);
  
        /* If the new header has multiple latches mark it so.  */
Index: gcc/testsuite/gcc.dg/torture/pr54520.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr54520.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr54520.c      (working copy)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ 
+ char *a;
+ void
+ fn1 ()
+ {
+   char *p = a;
+   while (p && *p != '\0')
+     {
+       while (*p == '\t')
+       *p++ = '\0';
+       if (*p != '\0')
+       p = 0;
+     }
+ }

Reply via email to