Message ID | ZcXpltFL8tFYXHYi@tucnak |
---|---|
State | New |
Headers | show |
Series | lower-bitint: Fix up additions of EH edges [PR113818] | expand |
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 <jakub@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 > >
--- 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); +}