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)