Hello,

and ping please.  This is now also a fix for PR 123619.

Thanks,

Martin

On Fri, Dec 05 2025, Martin Jambor wrote:
> Hi,
>
> ipa_polymorphic_call_context::equal_to happily ignores the speculative
> part of the context if it is inconsistent with the known part.  While
> this is OK for uses outside of IPA-CP, for this pass it cannot be done
> because it happily drops the non-speculative part when jump functions
> are not known to "preserve types."  This can then mean that two
> contexts from which we can derive diferent "final" ones are
> representeed as one in the IPA-CP lattice and then later IPA-CP is
> confused when the (speculative) one that it has created a clone for is
> not actually available from any caller.
>
> I was only able to trigger this issue with all the patches pending
> review applied and when I relaxed the IPA-CP parameters so much that
> they created a clone for every opportunity , no matter how
> non-profitable, and then tried to build 510.parest_r.  But still it is
> a bug regardless of the patches and I believe the equal_to predicate
> should not be used in this way.
>
> Bootstrapped and tested on x86_64-linux, OK for master?
>
> Thanks,
>
> Martin
>
>
> gcc/ChangeLog:
>
> 2025-12-05  Martin Jambor  <[email protected]>
>
>       * cgraph.h (ipa_polymorphic_call_context::equal_to): Add parametr
>       strict_speculation.
>       * ipa-polymorphic-call.cc (ipa_polymorphic_call_context::equal_to):
>       Likewise.
>       * ipa-cp.cc (values_equal_for_ipcp_p): Pass true to strict_speculation
>       of ipa_polymorphic_call_context::equal_to.
> ---
>  gcc/cgraph.h                |  7 +++++--
>  gcc/ipa-cp.cc               |  2 +-
>  gcc/ipa-polymorphic-call.cc | 22 ++++++++++++++--------
>  3 files changed, 20 insertions(+), 11 deletions(-)
>
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index 91b5de40cef..bca26ddfad1 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1684,8 +1684,11 @@ public:
>  
>    /* Return TRUE if context is fully useless.  */
>    bool useless_p () const;
> -  /* Return TRUE if this context conveys the same information as X.  */
> -  bool equal_to (const ipa_polymorphic_call_context &x) const;
> +  /* Return TRUE if this context conveys the same information as X.  If
> +     STRICT_SPECULATION is true, compare the speculative part even when it is
> +     inconsistent.  */
> +  bool equal_to (const ipa_polymorphic_call_context &x,
> +              bool strict_speculation = false) const;
>  
>    /* Dump human readable context to F.  If NEWLINE is true, it will be
>       terminated by a newline.  */
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 65784761360..5bcca5f2dfa 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -2026,7 +2026,7 @@ static bool
>  values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
>                        ipa_polymorphic_call_context y)
>  {
> -  return x.equal_to (y);
> +  return x.equal_to (y, true);
>  }
>  
>  
> diff --git a/gcc/ipa-polymorphic-call.cc b/gcc/ipa-polymorphic-call.cc
> index 09316de0e6b..7b7036f0f71 100644
> --- a/gcc/ipa-polymorphic-call.cc
> +++ b/gcc/ipa-polymorphic-call.cc
> @@ -2368,11 +2368,13 @@ 
> ipa_polymorphic_call_context::possible_dynamic_type_change (bool 
> in_poly_cdtor,
>      maybe_in_construction = true;
>  }
>  
> -/* Return TRUE if this context conveys the same information as OTHER.  */
> +/* Return TRUE if this context conveys the same information as X.  If
> +   STRICT_SPECULATION is true, compare the speculative part even when it is
> +   inconsistent.  */
>  
>  bool
>  ipa_polymorphic_call_context::equal_to
> -    (const ipa_polymorphic_call_context &x) const
> +(const ipa_polymorphic_call_context &x, bool strict_speculation) const
>  {
>    if (useless_p ())
>      return x.useless_p ();
> @@ -2397,8 +2399,11 @@ ipa_polymorphic_call_context::equal_to
>  
>  
>    if (speculative_outer_type
> -      && speculation_consistent_p (speculative_outer_type, 
> speculative_offset,
> -                                speculative_maybe_derived_type, NULL_TREE))
> +      && (strict_speculation
> +       || speculation_consistent_p (speculative_outer_type,
> +                                    speculative_offset,
> +                                    speculative_maybe_derived_type,
> +                                    NULL_TREE)))
>      {
>        if (!x.speculative_outer_type)
>       return false;
> @@ -2412,10 +2417,11 @@ ipa_polymorphic_call_context::equal_to
>       return false;
>      }
>    else if (x.speculative_outer_type
> -        && x.speculation_consistent_p (x.speculative_outer_type,
> -                                       x.speculative_offset,
> -                                       x.speculative_maybe_derived_type,
> -                                       NULL))
> +        && (strict_speculation
> +            || x.speculation_consistent_p (x.speculative_outer_type,
> +                                           x.speculative_offset,
> +                                           x.speculative_maybe_derived_type,
> +                                           NULL)))
>      return false;
>  
>    return true;
> -- 
> 2.51.1

Reply via email to