https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85615
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at gcc dot gnu.org --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- It looks like loop structure is already broken to the extent that loop->num_nodes cannot be trusted and thus bblocks = XCNEWVEC (basic_block, loop->num_nodes); dbds_ce_stop = loop->header; nblocks = dfs_enumerate_from (loop->latch, 1, dbds_continue_enumeration_p, bblocks, loop->num_nodes, bb); breaks (not enough space in bblocks, thus bb is not reachable from loop->latch). In fact loop structure looks totally broken to me :/ We seem to thread through always true/false conditions that are left over from VRP substitute-and-fold which relies on CFG cleanup to cleanup things here. When we thread through block 12, Breakpoint 5, thread_block_1 (bb=<basic_block 0x7ffff689f750 (12)>, noloop_only=true, joiners=false) we have threaded through the loop header which in the end wrecks things. We do not hit /* One case occurs when there was loop header buried in a jump threading path that crosses loop boundaries. We do not try and thread this elsewhere, so just cancel the jump threading request by clearing the AUX field now. */ if (bb->loop_father != e2->src->loop_father && !loop_exit_edge_p (e2->src->loop_father, e2)) { nor /* Another case occurs when trying to thread through our own loop header, possibly from inside the loop. We will thread these later. */ unsigned int i; for (i = 1; i < path->length (); i++) { but the case involves a very long path (6 edges) where we thread through the header of an outer loop into an inner loop and finally through the exit of the inner loop. I guess we should hit the first case by allowing the exit threading only if the exit is to bb->loop_father. Otherwise we create an alternate entry (which is what happens here). Like by making the check consisted with the others. I'm testing the following. Index: gcc/tree-ssa-threadupdate.c =================================================================== --- gcc/tree-ssa-threadupdate.c (revision 259879) +++ gcc/tree-ssa-threadupdate.c (working copy) @@ -1309,7 +1309,7 @@ thread_block_1 (basic_block bb, bool nol and thread this elsewhere, so just cancel the jump threading request by clearing the AUX field now. */ if (bb->loop_father != e2->src->loop_father - && !loop_exit_edge_p (e2->src->loop_father, e2)) + && !loop_exit_edge_p (bb->loop_father, e2)) { /* Since this case is not handled by our special code to thread through a loop header, we must explicitly