Hi, On Mon, Jan 05 2026, Jan Hubicka wrote: >> Hi, >> >> since the IPA-CP lattices for value ranges cannot hold more values and >> don't have any "variable" flag, we initialize them to bottom for >> non-local nodes. However, that means we don't make use of known >> information gathered in jump functions when the corresponding node is >> cloned for some other reason. This patch allows collection of the >> information and only does not use them for the original non-local >> nodes. > > Since IPA predicates can tell you if function will simplify by known > value range, I think we should eventually start handling VRP based > cloining by same path as we currently do constants and > devirtulalization. Common example are NULL pointer checks and overflow > checks that are common in C++ code... >> >> Bootstrapped, LTO-bootstrapped and tested on x86_64, OK for master? >> >> Thanks, >> >> Martin >> >> >> gcc/ChangeLog: >> >> 2025-11-04 Martin Jambor <[email protected]> >> >> * ipa-cp.cc (set_all_contains_variable): New parameter >> INCLUDE_SIMPLE, make setting bits and vr lattices to bottom >> conditional on it. >> (initialize_node_lattices): Pass false to the second parameter of >> set_all_contains_variable. >> (ipcp_store_vr_results): Skip non-local nodes. >> --- >> gcc/ipa-cp.cc | 21 ++++++++++++++++----- >> 1 file changed, 16 insertions(+), 5 deletions(-) >> >> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc >> index 915d29b4bb2..fcb3123b9ed 100644 >> --- a/gcc/ipa-cp.cc >> +++ b/gcc/ipa-cp.cc >> @@ -1322,17 +1322,23 @@ intersect_argaggs_with (vec<ipa_argagg_value> &elts, >> } >> >> /* Mark bot aggregate and scalar lattices as containing an unknown variable, >> - return true is any of them has not been marked as such so far. */ >> + return true is any of them has not been marked as such so far. If >> + INCLUDE_SIMPLE is true, also set the lattices that can only hold one >> value >> + to bottom. */ >> >> static inline bool >> -set_all_contains_variable (class ipcp_param_lattices *plats) >> +set_all_contains_variable (class ipcp_param_lattices *plats, >> + bool include_simple = true) >> { >> bool ret; >> ret = plats->itself.set_contains_variable (); >> ret |= plats->ctxlat.set_contains_variable (); >> ret |= set_agg_lats_contain_variable (plats); >> - ret |= plats->bits_lattice.set_to_bottom (); >> - ret |= plats->m_value_range.set_to_bottom (); >> + if (include_simple) >> + { >> + ret |= plats->bits_lattice.set_to_bottom (); >> + ret |= plats->m_value_range.set_to_bottom (); > > It took me a whlie to understand this. So the first three values > are those where we handle clonning for diffeent contextes, while bits > and value ranges does not (yet). >> + } >> return ret; >> } >> >> @@ -1477,7 +1483,7 @@ initialize_node_lattices (struct cgraph_node *node) >> { >> plats->m_value_range.init (type); >> if (variable) >> - set_all_contains_variable (plats); >> + set_all_contains_variable (plats, false); > So here we will start propagating even if function can be called > externally. >> } >> } >> >> @@ -6323,6 +6329,11 @@ ipcp_store_vr_results (void) >> bool do_vr = true; >> bool do_bits = true; >> >> + /* If the function is not local, the gathered information is only >> useful >> + for clones. */ >> + if (!node->local) >> + continue; > > Assume we have A->B->C where A sets value ranges, B can be called > externally and C is local and would benefit from known range. > If we clone B then we will end up > > A->B'->C > B ->C > > and C will not see the value range passed from A? > However if we decide to clone C for some other reason we will have > > A->B'->C' > B ->C > and here C' will see the value range and C will not? > I do not see how you can distinguish these situation as > ipcp_store_vr_results time?
yes, I thought I had told you in person, the patch is wrong. I have found out just a few days after posting it already when testing the patch-set further. We'd need a bit in the lattice itself to distinguish this and the effort should probably be spent making value-range lattices for cloning. Martin
