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
