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.

Reply via email to