This should fix PR56525, we reference ggc_freed loop structures from bb->loop_father when fix_loop_structure removes a loop and then calls flow_loops_find. Fixed by delaying the ggc_free part of loop removal until after that (I thought about other ways to fix the reference but they are way more intrusive).
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2013-03-05 Richard Biener <rguent...@suse.de> PR middle-end/56525 * loop-init.c (fix_loop_structure): Remove loops in two stages, not freeing them until the end. Index: gcc/loop-init.c =================================================================== *** gcc/loop-init.c (revision 196451) --- gcc/loop-init.c (working copy) *************** fix_loop_structure (bitmap changed_bbs) *** 186,192 **** int record_exits = 0; loop_iterator li; struct loop *loop; ! unsigned old_nloops; timevar_push (TV_LOOP_INIT); --- 186,192 ---- int record_exits = 0; loop_iterator li; struct loop *loop; ! unsigned old_nloops, i; timevar_push (TV_LOOP_INIT); *************** fix_loop_structure (bitmap changed_bbs) *** 230,237 **** flow_loop_tree_node_add (loop_outer (loop), ploop); } ! /* Remove the loop and free its data. */ ! delete_loop (loop); } /* Remember the number of loops so we can return how many new loops --- 230,238 ---- flow_loop_tree_node_add (loop_outer (loop), ploop); } ! /* Remove the loop. */ ! loop->header = NULL; ! flow_loop_tree_node_remove (loop); } /* Remember the number of loops so we can return how many new loops *************** fix_loop_structure (bitmap changed_bbs) *** 253,258 **** --- 254,267 ---- } } + /* Finally free deleted loops. */ + FOR_EACH_VEC_ELT (*get_loops (), i, loop) + if (loop && loop->header == NULL) + { + (*get_loops ())[i] = NULL; + flow_loop_free (loop); + } + loops_state_clear (LOOPS_NEED_FIXUP); /* Apply flags to loops. */