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);
 }

Reply via email to