> Hi,
> 
> On Tue, Dec 17 2019, Feng Xue OS wrote:
> > If argument for a self-recursive call is a simple pass-through, the call
> > edge is also considered as source of any value originated from
> > non-recursive call to the function. Scalar pass-through and full aggregate
> > pass-through due to pointer pass-through have also been handled.
> > But we missed another kind of pass-through like below case,  partial
> > aggregate pass-through. This patch is meant to fix the problem which
> > caused ICE as in 92794.
> >
> >   void foo(struct T *val_ptr)
> >   {
> >     struct T new_val;
> >     new_val.field = val_ptr->field;
> >     foo (&temp);
> >     ...
> >   }
> >
> > Bootstrapped/regtested on x86_64-linux and aarch64-linux.
> >
> > 2019-12-17  Feng Xue  <f...@os.amperecomputing.com>
> >
> >         PR ipa/92794
> >         * ipa-cp.c (self_recursive_agg_pass_through_p): New function.
> >         (intersect_with_plats): Use error_mark_node as place holder
> >         when aggregate jump function is simple pass-through for
> >         self-recursive call.
> >         (intersect_with_agg_replacements): Likewise.
> >         (intersect_aggregates_with_edge): Likewise.
> >         (find_aggregate_values_for_callers_subset): Likewise.
> >
> > Thanks,
> > Feng
> > From 42ba553ebf80eadb62619c5570a4b406f8c90c49 Mon Sep 17 00:00:00 2001
> > From: Feng Xue <f...@os.amperecomputing.com>
> > Date: Mon, 16 Dec 2019 20:33:36 +0800
> > Subject: [PATCH] Handle aggregate simple pass-through for self-recursive 
> > call
> >
> > ---
> >  gcc/ipa-cp.c                       | 97 +++++++++++++++++++++++++-----
> >  gcc/testsuite/gcc.dg/ipa/pr92794.c | 30 +++++++++
> >  2 files changed, 111 insertions(+), 16 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/ipa/pr92794.c
> >
> > diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> > index 1a80ccbde2d..0e17fedd649 100644
> > --- a/gcc/ipa-cp.c
> > +++ b/gcc/ipa-cp.c
> > @@ -4564,6 +4564,23 @@ self_recursive_pass_through_p (cgraph_edge *cs, 
> > ipa_jump_func *jfunc, int i)
> >    return false;
> >  }
> >  
> > +/* Return true, if JFUNC, which describes a part of an aggregate 
> > represented
> > +   or pointed to by the i-th parameter of call CS, is a simple no-operation
> > +   pass-through function to itself.  */
> > +
> > +static bool
> > +self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
> > +                              int i)
> > +{
> > +  if (cs->caller == cs->callee->function_symbol ()
> 
> I don't know if self-recursive calls can be interposed at all, if yes
> you need to add the availability check like we have in
> self_recursive_pass_through_p (if not, we should probably remove it
> there).

Yes, self recursion can interpose if you have alias and enter the
recursive loop by different symbol name then recurse.
We have optional ref argument in ultimate_alias_target and friends where
you can specify symbol in which the reference appears and then the
predicate knows how to verify this (odd) condition.

There is cgraph_edge::recursive_p that can make mistake in positive
direction in the case of interposition. We probably want to distinguish
these cases and have parameter for that...

Honza
> 
> Apart from that, I believe the patch is probably the best thing we can
> do to deal with these interesting situations.
> 
> Thanks for looking into the bug,
> 
> Martin
> 
> 
> > +      && jfunc->jftype == IPA_JF_LOAD_AGG
> > +      && jfunc->offset == jfunc->value.load_agg.offset
> > +      && jfunc->value.pass_through.operation == NOP_EXPR
> > +      && jfunc->value.pass_through.formal_id == i)
> > +    return true;
> > +  return false;
> > +}

Reply via email to