On Wed, Feb 23, 2022 at 11:44 PM Alexandre Oliva via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > When we duplicate a throwing compare for hardening, the EH edge from > the original compare gets duplicated for the inverted compare, but we > failed to adjust any PHI nodes in the EH block. This patch adds the > needed adjustment, copying the PHI args from those of the preexisting > edge. > > Regstrapped on x86_64-linux-gnu. Ok to install?
OK. > > for gcc/ChangeLog > > PR tree-optimization/103856 > * gimple-harden-conditionals.cc (non_eh_succ_edge): Enable the > eh edge to be requested through an extra parameter. > (pass_harden_compares::execute): Copy PHI args in the EH dest > block for the new EH edge added for the inverted compare. > > for gcc/testsuite/ChangeLog > > PR tree-optimization/103856 > * g++.dg/pr103856.C: New. > --- > gcc/gimple-harden-conditionals.cc | 31 ++++++++++++++++++++++++++++--- > gcc/testsuite/g++.dg/pr103856.C | 17 +++++++++++++++++ > 2 files changed, 45 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/pr103856.C > > diff --git a/gcc/gimple-harden-conditionals.cc > b/gcc/gimple-harden-conditionals.cc > index 9418194cb20c2..6a5fc3fb9e1a2 100644 > --- a/gcc/gimple-harden-conditionals.cc > +++ b/gcc/gimple-harden-conditionals.cc > @@ -361,9 +361,9 @@ make_pass_harden_conditional_branches (gcc::context *ctxt) > } > > /* Return the fallthru edge of a block whose other edge is an EH > - edge. */ > + edge. If EHP is not NULL, store the EH edge in it. */ > static inline edge > -non_eh_succ_edge (basic_block bb) > +non_eh_succ_edge (basic_block bb, edge *ehp = NULL) > { > gcc_checking_assert (EDGE_COUNT (bb->succs) == 2); > > @@ -375,6 +375,9 @@ non_eh_succ_edge (basic_block bb) > gcc_checking_assert (!(ret->flags & EDGE_EH) > && (eh->flags & EDGE_EH)); > > + if (ehp) > + *ehp = eh; > + > return ret; > } > > @@ -538,8 +541,9 @@ pass_harden_compares::execute (function *fun) > add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn)); > make_eh_edges (asgnck); > > + edge ckeh; > basic_block nbb = split_edge (non_eh_succ_edge > - (gimple_bb (asgnck))); > + (gimple_bb (asgnck), &ckeh)); > gsi_split = gsi_start_bb (nbb); > > if (dump_file) > @@ -547,6 +551,27 @@ pass_harden_compares::execute (function *fun) > "Splitting non-EH edge from block %i into %i after" > " the newly-inserted reversed throwing compare\n", > gimple_bb (asgnck)->index, nbb->index); > + > + if (!gimple_seq_empty_p (phi_nodes (ckeh->dest))) > + { > + edge aseh; > + non_eh_succ_edge (gimple_bb (asgn), &aseh); > + > + gcc_checking_assert (aseh->dest == ckeh->dest); > + > + for (gphi_iterator psi = gsi_start_phis (ckeh->dest); > + !gsi_end_p (psi); gsi_next (&psi)) > + { > + gphi *phi = psi.phi (); > + add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (phi, aseh), ckeh, > + gimple_phi_arg_location_from_edge (phi, > aseh)); > + } > + > + if (dump_file) > + fprintf (dump_file, > + "Copying PHI args in EH block %i from %i to %i\n", > + aseh->dest->index, aseh->src->index, > ckeh->src->index); > + } > } > > gcc_checking_assert (single_succ_p (gsi_bb (gsi_split))); > diff --git a/gcc/testsuite/g++.dg/pr103856.C b/gcc/testsuite/g++.dg/pr103856.C > new file mode 100644 > index 0000000000000..26c7d8750255a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/pr103856.C > @@ -0,0 +1,17 @@ > +/* { dg-do compile } */ > +/* { dg-options "-Og -fnon-call-exceptions -fsignaling-nans > -fharden-compares" } */ > + > +struct S { > + S(float); > + S(); > + operator float(); > + ~S() {} > +}; > + > +int > +main() { > + S s_arr[] = {2}; > + S var1; > + if (var1) > + ; > +} > > > -- > Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ > Free Software Activist GNU Toolchain Engineer > Disinformation flourishes because many people care deeply about injustice > but very few check the facts. Ask me about <https://stallmansupport.org>