> gcc/ChangeLog:
>
> 2023-09-19 Martin Jambor <[email protected]>
>
> 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 <[email protected]>
>
> 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