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; + } + }