On Wed, Sep 3, 2014 at 10:46 AM, Martin Jambor <mjam...@suse.cz> wrote:
> Hi,
>
> intersecting known aggregate values coming along a given set of call
> graph edges requires that all lists are in ascending order of offsets
> in order to perform it in only one sweep through each of them.
> However, aggregate replacement nodes are produced in exactly the
> opposite order.  This makes us miss an item in the intersection and
> assert later.  The ordering is fixed by the following patch.
>
> Bootstrapped and tested on x86_64-linux.  OK for the trunk and all
> problematic branches (4.9 for sure, I am not sure about 4.8 at this
> moment).

Ok.

Thanks,
Richard.

> Thanks,
>
> Martin
>
>
> 2014-09-02  Martin Jambor  <mjam...@suse.cz>
>
>         PR ipa/61986
>         * ipa-cp.c (find_aggregate_values_for_callers_subset): Chain
>         created replacements in ascending order of offsets.
>         (known_aggs_to_agg_replacement_list): Likewise.
>
> testsuite/
>         * gcc.dg/ipa/pr61986.c: New test.
>
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 44d4c9a..58121d4 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -3146,7 +3146,8 @@ find_aggregate_values_for_callers_subset (struct 
> cgraph_node *node,
>                                           vec<cgraph_edge *> callers)
>  {
>    struct ipa_node_params *dest_info = IPA_NODE_REF (node);
> -  struct ipa_agg_replacement_value *res = NULL;
> +  struct ipa_agg_replacement_value *res;
> +  struct ipa_agg_replacement_value **tail = &res;
>    struct cgraph_edge *cs;
>    int i, j, count = ipa_get_param_count (dest_info);
>
> @@ -3190,14 +3191,15 @@ find_aggregate_values_for_callers_subset (struct 
> cgraph_node *node,
>           v->offset = item->offset;
>           v->value = item->value;
>           v->by_ref = plats->aggs_by_ref;
> -         v->next = res;
> -         res = v;
> +         *tail = v;
> +         tail = &v->next;
>         }
>
>      next_param:
>        if (inter.exists ())
>         inter.release ();
>      }
> +  *tail = NULL;
>    return res;
>  }
>
> @@ -3206,7 +3208,8 @@ find_aggregate_values_for_callers_subset (struct 
> cgraph_node *node,
>  static struct ipa_agg_replacement_value *
>  known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs)
>  {
> -  struct ipa_agg_replacement_value *res = NULL;
> +  struct ipa_agg_replacement_value *res;
> +  struct ipa_agg_replacement_value **tail = &res;
>    struct ipa_agg_jump_function *aggjf;
>    struct ipa_agg_jf_item *item;
>    int i, j;
> @@ -3220,9 +3223,10 @@ known_aggs_to_agg_replacement_list 
> (vec<ipa_agg_jump_function> known_aggs)
>         v->offset = item->offset;
>         v->value = item->value;
>         v->by_ref = aggjf->by_ref;
> -       v->next = res;
> -       res = v;
> +       *tail = v;
> +       tail = &v->next;
>        }
> +  *tail = NULL;
>    return res;
>  }
>
> diff --git a/gcc/testsuite/gcc.dg/ipa/pr61986.c 
> b/gcc/testsuite/gcc.dg/ipa/pr61986.c
> new file mode 100644
> index 0000000..8d2f658
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/pr61986.c
> @@ -0,0 +1,48 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3" } */
> +
> +int a, b, c;
> +
> +struct S
> +{
> +  int f0;
> +  int f1;
> +} d;
> +
> +static int fn2 (struct S);
> +void fn3 (struct S);
> +
> +void
> +fn1 (struct S p)
> +{
> +  struct S h = { 0, 0 };
> +  fn3 (p);
> +  fn2 (h);
> +}
> +
> +int
> +fn2 (struct S p)
> +{
> +  struct S j = { 0, 0 };
> +  fn3 (p);
> +  fn2 (j);
> +  return 0;
> +}
> +
> +void
> +fn3 (struct S p)
> +{
> +  for (; b; a++)
> +    c = p.f0;
> +  fn1 (d);
> +}
> +
> +void
> +fn4 ()
> +{
> +  for (;;)
> +    {
> +      struct S f = { 0, 0 };
> +      fn1 (f);
> +    }
> +}

Reply via email to