On Thu, 15 Dec 2022, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase ICEs, because ccp1 replaced
>   s.0_1 = &s;
>   __asm__ goto("" : "=r" MEM[(T *)s.0_1] :  :  : "lab" lab);
> with
>   __asm__ goto("" : "=r" s :  :  : "lab" lab);
> and because s is no longer addressable, we are rewriting it into
> ssa and want
>   __asm__ goto("" : "=r" s_7 :  :  : "lab" lab);
> plus debug stmt
>   # DEBUG s => s_7
> The code assumes that there is at most one non-EH edge in that
> case, but with the addition of outputs to asm goto that is no longer the
> case, we can have many outgoing edges.
> 
> The patch keeps the checking assertion that there is at most one such
> edge for everything but asm goto, but moves the addition of the debug
> stmt into the loop, so that it can be added on all edges where it is
> possible, not just one of them.
> 
> Furthermore, looking at gsi_insert_on_edge_immediate
> -> gimple_find_edge_insert_loc, the conditions to insert stmt there
> to the destination block are
>   if (single_pred_p (dest)
>       && gimple_seq_empty_p (phi_nodes (dest))
>       && dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
> (plus there is code to insert it in the previous block but that is
> never true when the pred is known to be stmt_ends_bb_p), while
> mayube_register_def was just checking
>                  if (ef && single_pred_p (ef->dest)
>                      && ef->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
> so if for whatever reason ef->dest had any PHIs, we'd split the
> edge for -g and not for -g0, something we must avoid for -fcompare-debug
> stability.  So, I've added the no phi_nodes check too.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2022-12-15  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/108095
>       * tree-into-ssa.cc (maybe_register_def): Insert debug stmt
>       on all non-EH edges from asm goto if they have a single
>       predecessor rather than asserting there is at most one such edge.
>       Test whether there are no PHI nodes next to the single predecessor
>       test.
> 
>       * gcc.dg/pr108095.c: New test.
> 
> --- gcc/tree-into-ssa.cc.jj   2022-12-05 23:20:24.000000000 +0100
> +++ gcc/tree-into-ssa.cc      2022-12-14 14:20:50.301283097 +0100
> @@ -1934,9 +1934,8 @@ maybe_register_def (def_operand_p def_p,
>         tree tracked_var = target_for_debug_bind (sym);
>         if (tracked_var)
>           {
> -           gimple *note = gimple_build_debug_bind (tracked_var, def, stmt);
> -           /* If stmt ends the bb, insert the debug stmt on the single
> -              non-EH edge from the stmt.  */
> +           /* If stmt ends the bb, insert the debug stmt on the non-EH
> +              edge(s) from the stmt.  */
>             if (gsi_one_before_end_p (gsi) && stmt_ends_bb_p (stmt))
>               {
>                 basic_block bb = gsi_bb (gsi);
> @@ -1945,33 +1944,46 @@ maybe_register_def (def_operand_p def_p,
>                 FOR_EACH_EDGE (e, ei, bb->succs)
>                   if (!(e->flags & EDGE_EH))
>                     {
> -                     gcc_checking_assert (!ef);
> +                     /* asm goto can have multiple non-EH edges from the
> +                        stmt.  Insert on all of them where it is
> +                        possible.  */
> +                     gcc_checking_assert (!ef || (gimple_code (stmt)
> +                                                  == GIMPLE_ASM));
>                       ef = e;
> -                   }
> -               /* If there are other predecessors to ef->dest, then
> -                  there must be PHI nodes for the modified
> -                  variable, and therefore there will be debug bind
> -                  stmts after the PHI nodes.  The debug bind notes
> -                  we'd insert would force the creation of a new
> -                  block (diverging codegen) and be redundant with
> -                  the post-PHI bind stmts, so don't add them.
> +                     /* If there are other predecessors to ef->dest, then
> +                        there must be PHI nodes for the modified
> +                        variable, and therefore there will be debug bind
> +                        stmts after the PHI nodes.  The debug bind notes
> +                        we'd insert would force the creation of a new
> +                        block (diverging codegen) and be redundant with
> +                        the post-PHI bind stmts, so don't add them.
>  
> -                  As for the exit edge, there wouldn't be redundant
> -                  bind stmts, but there wouldn't be a PC to bind
> -                  them to either, so avoid diverging the CFG.  */
> -               if (ef && single_pred_p (ef->dest)
> -                   && ef->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
> -                 {
> -                   /* If there were PHI nodes in the node, we'd
> -                      have to make sure the value we're binding
> -                      doesn't need rewriting.  But there shouldn't
> -                      be PHI nodes in a single-predecessor block,
> -                      so we just add the note.  */
> -                   gsi_insert_on_edge_immediate (ef, note);
> -                 }
> +                        As for the exit edge, there wouldn't be redundant
> +                        bind stmts, but there wouldn't be a PC to bind
> +                        them to either, so avoid diverging the CFG.  */
> +                     if (e
> +                         && single_pred_p (e->dest)
> +                         && gimple_seq_empty_p (phi_nodes (e->dest))
> +                         && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
> +                       {
> +                         /* If there were PHI nodes in the node, we'd
> +                            have to make sure the value we're binding
> +                            doesn't need rewriting.  But there shouldn't
> +                            be PHI nodes in a single-predecessor block,
> +                            so we just add the note.  */
> +                         gimple *note
> +                           = gimple_build_debug_bind (tracked_var, def,
> +                                                      stmt);
> +                         gsi_insert_on_edge_immediate (ef, note);
> +                       }
> +                   }
>               }
>             else
> -             gsi_insert_after (&gsi, note, GSI_SAME_STMT);
> +             {
> +               gimple *note
> +                 = gimple_build_debug_bind (tracked_var, def, stmt);
> +               gsi_insert_after (&gsi, note, GSI_SAME_STMT);
> +             }
>           }
>       }
>  
> --- gcc/testsuite/gcc.dg/pr108095.c.jj        2022-12-14 14:31:57.206580191 
> +0100
> +++ gcc/testsuite/gcc.dg/pr108095.c   2022-12-14 14:31:25.234045359 +0100
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/108095 */
> +/* { dg-do compile } */
> +/* { dg-options "-Os -g" } */
> +
> +int v;
> +typedef unsigned T;
> +
> +void
> +foo (void)
> +{
> +  unsigned s;
> +  asm goto ("" : "=r" (*(T *) &s) : : : lab);
> +  v = 0;
> +lab:
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

Reply via email to