> 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

Reply via email to