> gcc/ChangeLog: > > 2023-09-19 Martin Jambor <mjam...@suse.cz> > > PR ipa/111157 > * ipa-prop.h (struct ipa_argagg_value): Newf flag killed. > * ipa-modref.cc (ipcp_argagg_and_kill_overlap_p): New function. > (update_signature): Mark any any IPA-CP aggregate constants at > positions known to be killed as killed. Move check that there is > clone_info after this pruning. > * ipa-cp.cc (ipa_argagg_value_list::dump): Dump the killed flag. > (ipa_argagg_value_list::push_adjusted_values): Clear the new flag. > (push_agg_values_from_plats): Likewise. > (ipa_push_agg_values_from_jfunc): Likewise. > (estimate_local_effects): Likewise. > (push_agg_values_for_index_from_edge): Likewise. > * ipa-prop.cc (write_ipcp_transformation_info): Stream the killed > flag. > (read_ipcp_transformation_info): Likewise. > (ipcp_get_aggregate_const): Update comment, assert that encountered > record does not have killed flag set. > (ipcp_transform_function): Prune all aggregate constants with killed > set. > > gcc/testsuite/ChangeLog: > > 2023-09-18 Martin Jambor <mjam...@suse.cz> > > PR ipa/111157 > * gcc.dg/lto/pr111157_0.c: New test. > * gcc.dg/lto/pr111157_1.c: Second file of the same new test.
> diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc > index c04f9f44c06..a8fcf159259 100644 > --- a/gcc/ipa-modref.cc > +++ b/gcc/ipa-modref.cc > @@ -4065,21 +4065,71 @@ remap_kills (vec <modref_access_node> &kills, const > vec <int> &map) > i++; > } > > +/* Return true if the V can overlap with KILL. */ > + > +static bool > +ipcp_argagg_and_kill_overlap_p (const ipa_argagg_value &v, > + const modref_access_node &kill) > +{ > + if (kill.parm_index == v.index) > + { > + gcc_assert (kill.parm_offset_known); > + gcc_assert (known_eq (kill.max_size, kill.size)); > + poly_int64 repl_size; > + bool ok = poly_int_tree_p (TYPE_SIZE (TREE_TYPE (v.value)), > + &repl_size); > + gcc_assert (ok); > + poly_int64 repl_offset (v.unit_offset); > + repl_offset <<= LOG2_BITS_PER_UNIT; > + poly_int64 combined_offset > + = (kill.parm_offset << LOG2_BITS_PER_UNIT) + kill.offset; parm_offset may be negative which I think will confuse ranges_maybe_overlap_p. I think you need to test for this and if it is negative adjust repl_offset instead of kill.offset > + if (ranges_maybe_overlap_p (repl_offset, repl_size, > + combined_offset, kill.size)) > + return true; > + } > + return false; > +} > + > /* If signature changed, update the summary. */ > > static void > update_signature (struct cgraph_node *node) > { > - clone_info *info = clone_info::get (node); > - if (!info || !info->param_adjustments) > - return; > - > modref_summary *r = optimization_summaries > ? optimization_summaries->get (node) : NULL; > modref_summary_lto *r_lto = summaries_lto > ? summaries_lto->get (node) : NULL; > if (!r && !r_lto) > return; > + > + ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node); Please add comment on why this is necessary. > + if (ipcp_ts) > + { > + for (auto &v : ipcp_ts->m_agg_values) > + { > + if (!v.by_ref) > + continue; > + if (r) > + for (const modref_access_node &kill : r->kills) > + if (ipcp_argagg_and_kill_overlap_p (v, kill)) > + { > + v.killed = true; > + break; > + } > + if (!v.killed && r_lto) > + for (const modref_access_node &kill : r_lto->kills) > + if (ipcp_argagg_and_kill_overlap_p (v, kill)) > + { > + v.killed = 1; = true? > + break; > + } > + } > + } > + > + clone_info *info = clone_info::get (node); > + if (!info || !info->param_adjustments) > + return; > + OK. Honza