https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107661
--- Comment #13 from Sergei Trofimovich <slyfox at gcc dot gnu.org> --- (In reply to Sergei Trofimovich from comment #12) > Testing the following: > > --- a/gcc/ipa-cp.cc > +++ b/gcc/ipa-cp.cc > @@ -5869,37 +5869,37 @@ cgraph_edge_brings_all_scalars_for_node (struct > cgraph_edge *cs, > /* Determine whether CS also brings all aggregate values that NODE is > specialized for. */ > > static bool > cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, > struct cgraph_node *node) > { > ipcp_transformation *ts = ipcp_get_transformation_summary (node); > if (!ts || vec_safe_is_empty (ts->m_agg_values)) > return true; > > const ipa_argagg_value_list existing (ts->m_agg_values); > auto_vec<ipa_argagg_value, 32> edge_values; > ipa_node_params *dest_info = ipa_node_params_sum->get (node); > gcc_checking_assert (dest_info->ipcp_orig_node); > dest_info = ipa_node_params_sum->get (dest_info->ipcp_orig_node); > push_agg_values_from_edge (cs, dest_info, &edge_values, &existing); > const ipa_argagg_value_list avl (&edge_values); > - return avl.superset_of_p (existing); > + return existing.superset_of_p (avl); > } It was not enough. What I expected: - avl contains: callback_fn_L and callback_fn_R - existing contains: callback_fn_L What I get: - avl contains: callback_fn_L - existing contains: callback_fn_L It seems to have something to do with push_agg_values_from_edge()/push_agg_values_for_index_from_edge() behaviour of filtering self-recursive lattice values: if (interim && self_recursive_pass_through_p (cs, jfunc, index)) { interim->push_adjusted_values (src_idx, index, unit_delta, res); return; } Here we seem to ignore lattice values discovered on the edges and only copy already encountered values. But we only populate 'interim' with values we specialised the self-recursive call against: push_agg_values_from_edge (cs, dest_info, &edge_values, &existing); ('existing' variable is populated by values caller uses in one location). The following hack seems to fix the test case for me but I suspect it just breaks any self-recursive propagation: --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -5868,35 +5868,35 @@ cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs, /* Determine whether CS also brings all aggregate values that NODE is specialized for. */ static bool cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, struct cgraph_node *node) { ipcp_transformation *ts = ipcp_get_transformation_summary (node); if (!ts || vec_safe_is_empty (ts->m_agg_values)) return true; const ipa_argagg_value_list existing (ts->m_agg_values); auto_vec<ipa_argagg_value, 32> edge_values; ipa_node_params *dest_info = ipa_node_params_sum->get (node); gcc_checking_assert (dest_info->ipcp_orig_node); dest_info = ipa_node_params_sum->get (dest_info->ipcp_orig_node); - push_agg_values_from_edge (cs, dest_info, &edge_values, &existing); + push_agg_values_from_edge (cs, dest_info, &edge_values, NULL); const ipa_argagg_value_list avl (&edge_values); return avl.superset_of_p (existing); }