On Fri, 9 Feb 2024, Jakub Jelinek wrote:

> Hi!
> 
> Due to -fnon-call-exceptions the bitint lowering adds new EH edges
> in various places, so that the EH edge points from handling (e.g. load or
> store) of each of the limbs.  The problem is that the EH edge destination
> as shown in the testcase can have some PHIs.  If it is just a virtual
> PHI, no big deal, the pass uses TODO_update_ssa_only_virtuals, but if
> it has other PHIs, I think we need to copy the values from the preexisting
> corresponding EH edge (which is from the original stmt to the EH pad)
> to the newly added EH edge, so that the PHI arguments are the same rather
> than missing (which ICEs during checking at the end of the pass).
> 
> This patch adds a function to do that and uses it whenever adding EH edges.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2024-02-09  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/113818
>       * gimple-lower-bitint.cc (add_eh_edge): New function.
>       (bitint_large_huge::handle_load,
>       bitint_large_huge::lower_mergeable_stmt,
>       bitint_large_huge::lower_muldiv_stmt): Use it.
> 
>       * gcc.dg/bitint-89.c: New test.
> 
> --- gcc/gimple-lower-bitint.cc.jj     2024-02-08 14:33:36.033220098 +0100
> +++ gcc/gimple-lower-bitint.cc        2024-02-08 17:29:38.182386934 +0100
> @@ -1681,6 +1681,27 @@ bitint_large_huge::handle_cast (tree lhs
>    return NULL_TREE;
>  }
>  
> +/* Add a new EH edge from SRC to EH_EDGE->dest, where EH_EDGE
> +   is an older EH edge, and except for virtual PHIs duplicate the
> +   PHI argument from the EH_EDGE to the new EH edge.  */
> +
> +static void
> +add_eh_edge (basic_block src, edge eh_edge)
> +{
> +  edge e = make_edge (src, eh_edge->dest, EDGE_EH);
> +  e->probability = profile_probability::very_unlikely ();
> +  for (gphi_iterator gsi = gsi_start_phis (eh_edge->dest);
> +       !gsi_end_p (gsi); gsi_next (&gsi))
> +    {
> +      gphi *phi = gsi.phi ();
> +      tree lhs = gimple_phi_result (phi);
> +      if (virtual_operand_p (lhs))
> +     continue;
> +      const phi_arg_d *arg = gimple_phi_arg (phi, eh_edge->dest_idx);
> +      add_phi_arg (phi, arg->def, e, arg->locus);
> +    }
> +}
> +
>  /* Helper function for handle_stmt method, handle a load from memory.  */
>  
>  tree
> @@ -1756,8 +1777,7 @@ bitint_large_huge::handle_load (gimple *
>                 if (eh_edge)
>                   {
>                     edge e = split_block (gsi_bb (m_gsi), g);
> -                   make_edge (e->src, eh_edge->dest, EDGE_EH)->probability
> -                     = profile_probability::very_unlikely ();
> +                   add_eh_edge (e->src, eh_edge);
>                     m_gsi = gsi_after_labels (e->dest);
>                     if (gsi_bb (save_gsi) == e->src)
>                       {
> @@ -1876,8 +1896,7 @@ bitint_large_huge::handle_load (gimple *
>               {
>                 edge e = split_block (gsi_bb (m_gsi), g);
>                 m_gsi = gsi_after_labels (e->dest);
> -               make_edge (e->src, eh_edge->dest, EDGE_EH)->probability
> -                 = profile_probability::very_unlikely ();
> +               add_eh_edge (e->src, eh_edge);
>               }
>           }
>         if (conditional)
> @@ -1934,8 +1953,7 @@ normal_load:
>       {
>         edge e = split_block (gsi_bb (m_gsi), g);
>         m_gsi = gsi_after_labels (e->dest);
> -       make_edge (e->src, eh_edge->dest, EDGE_EH)->probability
> -         = profile_probability::very_unlikely ();
> +       add_eh_edge (e->src, eh_edge);
>       }
>        if (tree_fits_uhwi_p (idx))
>       {
> @@ -2554,8 +2572,8 @@ bitint_large_huge::lower_mergeable_stmt
>                       {
>                         edge e = split_block (gsi_bb (m_gsi), g);
>                         m_gsi = gsi_after_labels (e->dest);
> -                       make_edge (e->src, eh_pad, EDGE_EH)->probability
> -                         = profile_probability::very_unlikely ();
> +                       add_eh_edge (e->src,
> +                                    find_edge (gimple_bb (stmt), eh_pad));
>                       }
>                   }
>                 if (kind == bitint_prec_large)
> @@ -2633,8 +2651,8 @@ bitint_large_huge::lower_mergeable_stmt
>                   {
>                     edge e = split_block (gsi_bb (m_gsi), g);
>                     m_gsi = gsi_after_labels (e->dest);
> -                   make_edge (e->src, eh_pad, EDGE_EH)->probability
> -                     = profile_probability::very_unlikely ();
> +                   add_eh_edge (e->src,
> +                                find_edge (gimple_bb (stmt), eh_pad));
>                   }
>               }
>             if (new_bb)
> @@ -2777,8 +2795,7 @@ bitint_large_huge::lower_mergeable_stmt
>               {
>                 edge e = split_block (gsi_bb (m_gsi), g);
>                 m_gsi = gsi_after_labels (e->dest);
> -               make_edge (e->src, eh_pad, EDGE_EH)->probability
> -                 = profile_probability::very_unlikely ();
> +               add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
>               }
>           }
>         if (kind == bitint_prec_huge && i == (bo_bit != 0))
> @@ -2822,8 +2839,7 @@ bitint_large_huge::lower_mergeable_stmt
>           {
>             edge e = split_block (gsi_bb (m_gsi), g);
>             m_gsi = gsi_after_labels (e->dest);
> -           make_edge (e->src, eh_pad, EDGE_EH)->probability
> -             = profile_probability::very_unlikely ();
> +           add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
>           }
>       }
>      }
> @@ -3479,8 +3495,7 @@ bitint_large_huge::lower_muldiv_stmt (tr
>       {
>         edge e2 = split_block (gsi_bb (m_gsi), g);
>         m_gsi = gsi_after_labels (e2->dest);
> -       make_edge (e2->src, e1->dest, EDGE_EH)->probability
> -         = profile_probability::very_unlikely ();
> +       add_eh_edge (e2->src, e1);
>       }
>      }
>  }
> --- gcc/testsuite/gcc.dg/bitint-89.c.jj       2024-02-08 17:35:01.693881442 
> +0100
> +++ gcc/testsuite/gcc.dg/bitint-89.c  2024-02-08 17:34:39.555189760 +0100
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/113818 */
> +/* { dg-do compile { target bitint } } */
> +/* { dg-options "-Os -fnon-call-exceptions -finstrument-functions-once" } */
> +
> +int c, i;
> +void bar (int *);
> +
> +#if __BITINT_MAXWIDTH__ >= 129
> +_BitInt(129) *a;
> +#else
> +_BitInt(63) *a;
> +#endif
> +
> +void
> +foo (void)
> +{
> +  if (c)
> +    return;
> +  int q;
> +  a[i] = 0;
> +  bar (&q);
> +}
> 
>       Jakub
> 
> 

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

Reply via email to