https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68375
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu.org Target Milestone|--- |6.0 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to ktkachov from comment #0) > I was investigating the testcase from PR 68194 > > int printf (const char *, ...); > > int a, c, d, e, g, h; > short f; > > short > fn1 () > { > int j[2]; > for (; e; e++) > if (j[0]) > for (;;) > ; > if (!g) > return f; > } > > int > main () > { > for (; a < 1; a++) > { > for (c = 0; c < 2; c++) > { > d && (f = 0); > h = fn1 (); > } > printf ("%d\n", (char) f); > } > > return 0; > } > > and hit an ICe when compiling with -fdump-tree-optimized-graph -O2: > internal compiler error: in get_loop_body_in_bfs_order, at cfgloop.c:944 > fn1 () > ^~~ > > 0x7114e8 get_loop_body_in_bfs_order(loop const*) > ../../gcc/gcc/cfgloop.c:944 > 0x1166ce2 draw_cfg_nodes_for_loop > ../../gcc/gcc/graph.c:220 > 0x1166cad draw_cfg_nodes_for_loop > ../../gcc/gcc/graph.c:212 > 0x1166e64 draw_cfg_nodes > ../../gcc/gcc/graph.c:242 > 0x1166e64 print_graph_cfg(char const*, function*) > ../../gcc/gcc/graph.c:288 > 0xa17806 execute_function_dump > ../../gcc/gcc/passes.c:1751 > Please submit a full bug report, > with preprocessed source if appropriate. > Please include the complete backtrace with any bug report. > See <http://gcc.gnu.org/bugs.html> for instructions. > > The assert "gcc_assert (i > vc);" triggers. > Changing it to "gcc_assert (i >= vc);" fixes it for me but it was explicitly > changed to i > vc from i >= vc with: > > 2015-06-09 Richard Biener <rguent...@suse.de> > > * cfgloop.c (get_loop_body_in_bfs_order): Fix assert. > > so there must be something I'm missing? if i == vc then blocks[vc++] will read from uninitialized memory as we always write to blocks[i++]. I think the case that is not handled well here is a a loop with just a header (no explicit latch). Then i == 1 and vc == 1 at the end (but the loop will terminate immediately after the read from blocks[vc++] which is even outside of the allocation due to the loop header check i < 1). Re-structuring the loop like blocks[0] = loop->header; bitmap_set_bit (visited, loop->header->index); vc = 0; i = 1; while (i < loop->num_nodes) { gcc_assert (i > vc); bb = blocks[vc++]; FOR_EACH_EDGE (e, ei, bb->succs) { if (flow_bb_inside_loop_p (loop, e->dest)) { if (bitmap_set_bit (visited, e->dest->index)) blocks[i++] = e->dest; } } } would fix this I guess.