diff mbox

[PR78365] ICE in determine_value_range, at tree-ssa-loo p-niter.c:413

Message ID 4f03c618-081b-e5b8-5ef6-6abdfddd9d9b@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah Nov. 28, 2016, 5:25 a.m. UTC
Hi,

On 24/11/16 19:48, Richard Biener wrote:
> On Wed, Nov 23, 2016 at 4:33 PM, Martin Jambor <mjambor@suse.cz> wrote:
>> Hi,
>>
>> On Fri, Nov 18, 2016 at 12:38:18PM +1100, kugan wrote:
>>> Hi,
>>>
>>> I was relying on ipa_get_callee_param_type to get type of parameter and then
>>> convert arguments to this type while computing jump functions. However, in
>>> cases like shown in PR78365, ipa_get_callee_param_type, instead of giving
>>> up, would return the wrong type.
>>
>> At what stage does this happen?  During analysis
>> (ipa_compute_jump_functions_for_edge) or at WPA
>> (propagate_constants_accross_call)?  Both?
>
> Hmm, where does jump function compute require the callee type?
> In my view the jump function should record
>
>  (expected-incoming-type) arg [OP X]
>
> for each call argument in its body.  Thus required conversions are
> done at WPA propagation time.
>
>>> I think the current uses of
>>> ipa_get_callee_param_type are fine with this.
>>>
>>> Attached patch now uses callee's DECL_ARGUMENTS to get the type. If it
>>> cannot be found, then I would give up and set the jump function to varying.
>>
>> But DECL_ARGUMENTS is not available at WPA stage with LTO so your
>> patch would make our IPA layer to optimize less with LTO.  This was
>> the reason to go through the hoops of TYPE_ARG_TYPES in the first
>> place.
>>
>> If TYPE_ARG_TYPES cannot be trusted, then I'm afraid we are back to
>> square one and indeed need to put the correct type in jump functions.
>
> If DECL_ARGUMENTS is not available at WPA stage then I see no other
> way than to put the types on the jump functions.

Here is a patch that does this. To fox PR78365, in 
ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto 
bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux 
with no new regressions. I will build Firefox and measure the memory 
usage as Honza suggested based on the feedback.

Thanks,
Kugan



gcc/ChangeLog:

2016-11-28  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>

	PR IPA/78365
	* ipa-cp.c (propagate_vr_accross_jump_function): Remove param_type 
argument and
	use the one set in jump_func.
	(propagate_constants_accross_call): Likewise.
	* ipa-prop.c (ipa_get_callee_param_type): Chedk DECL_ARGUMENTS first.
	(ipa_compute_jump_functions_for_edge): Set param_type for jump_func.
	(ipa_write_jump_function): Stream param_type.
	(ipa_read_jump_function): Likewise.

gcc/testsuite/ChangeLog:

2016-11-28  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>

	PR IPA/78365
	* gcc.dg/torture/pr78365.c: New test.



>> If just preferring DECL_ARGUMENTS is enough, then changing
>> ipa_get_callee_param_type to use that if is is available, as Richi
>> suggested, would indeed be preferable.  But if even falling back on it
>> can cause errors, then I am not sure if it helps.
>>
>> In any event, thanks for diligently dealing with the fallout,
>>
>> Martin
>>
>>
>>>
>>> Bootstrapped and regression tested on x86_64-linux-gnu with no new
>>> regressions. Is this OK for trunk?
>>>
>>> Thanks,
>>> Kugan
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 2016-11-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>>
>>>       PR IPA/78365
>>>       * gcc.dg/torture/pr78365.c: New test.
>>>
>>> gcc/ChangeLog:
>>>
>>> 2016-11-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>>
>>>       PR IPA/78365
>>>       * ipa-cp.c (propagate_constants_accross_call): get param type from callees
>>>       DECL_ARGUMENTS if available.
>>>       * ipa-prop.c (ipa_compute_jump_functions_for_edge): Likewise.
>>>       (ipcp_update_vr):  Remove now redundant conversion of precision for VR.
>>>       * ipa-prop.h: Make ipa_get_callee_param_type local again.

Comments

Prathamesh Kulkarni Nov. 28, 2016, 5:39 a.m. UTC | #1
On 28 November 2016 at 10:55, kugan <kugan.vivekanandarajah@linaro.org> wrote:
> Hi,
>
> On 24/11/16 19:48, Richard Biener wrote:
>>
>> On Wed, Nov 23, 2016 at 4:33 PM, Martin Jambor <mjambor@suse.cz> wrote:
>>>
>>> Hi,
>>>
>>> On Fri, Nov 18, 2016 at 12:38:18PM +1100, kugan wrote:
>>>>
>>>> Hi,
>>>>
>>>> I was relying on ipa_get_callee_param_type to get type of parameter and
>>>> then
>>>> convert arguments to this type while computing jump functions. However,
>>>> in
>>>> cases like shown in PR78365, ipa_get_callee_param_type, instead of
>>>> giving
>>>> up, would return the wrong type.
>>>
>>>
>>> At what stage does this happen?  During analysis
>>> (ipa_compute_jump_functions_for_edge) or at WPA
>>> (propagate_constants_accross_call)?  Both?
>>
>>
>> Hmm, where does jump function compute require the callee type?
>> In my view the jump function should record
>>
>>  (expected-incoming-type) arg [OP X]
>>
>> for each call argument in its body.  Thus required conversions are
>> done at WPA propagation time.
>>
>>>> I think the current uses of
>>>> ipa_get_callee_param_type are fine with this.
>>>>
>>>> Attached patch now uses callee's DECL_ARGUMENTS to get the type. If it
>>>> cannot be found, then I would give up and set the jump function to
>>>> varying.
>>>
>>>
>>> But DECL_ARGUMENTS is not available at WPA stage with LTO so your
>>> patch would make our IPA layer to optimize less with LTO.  This was
>>> the reason to go through the hoops of TYPE_ARG_TYPES in the first
>>> place.
>>>
>>> If TYPE_ARG_TYPES cannot be trusted, then I'm afraid we are back to
>>> square one and indeed need to put the correct type in jump functions.
>>
>>
>> If DECL_ARGUMENTS is not available at WPA stage then I see no other
>> way than to put the types on the jump functions.
>
>
> Here is a patch that does this. To fox PR78365, in
> ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto
> bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux
> with no new regressions. I will build Firefox and measure the memory usage
> as Honza suggested based on the feedback.
Hi Kugan,
In your patch in ipa_get_callee_param_type():
+ tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;

Perhaps this should be e->callee->function_symbol() ?

Thanks,
Prathamesh
>
> Thanks,
> Kugan
>
>
>
> gcc/ChangeLog:
>
> 2016-11-28  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>
>
>         PR IPA/78365
>         * ipa-cp.c (propagate_vr_accross_jump_function): Remove param_type
> argument and
>         use the one set in jump_func.
>         (propagate_constants_accross_call): Likewise.
>         * ipa-prop.c (ipa_get_callee_param_type): Chedk DECL_ARGUMENTS
> first.
>         (ipa_compute_jump_functions_for_edge): Set param_type for jump_func.
>         (ipa_write_jump_function): Stream param_type.
>         (ipa_read_jump_function): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> 2016-11-28  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>
>
>
>         PR IPA/78365
>         * gcc.dg/torture/pr78365.c: New test.
>
>
>
>>> If just preferring DECL_ARGUMENTS is enough, then changing
>>> ipa_get_callee_param_type to use that if is is available, as Richi
>>> suggested, would indeed be preferable.  But if even falling back on it
>>> can cause errors, then I am not sure if it helps.
>>>
>>> In any event, thanks for diligently dealing with the fallout,
>>>
>>> Martin
>>>
>>>
>>>>
>>>> Bootstrapped and regression tested on x86_64-linux-gnu with no new
>>>> regressions. Is this OK for trunk?
>>>>
>>>> Thanks,
>>>> Kugan
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>
>>>> 2016-11-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>>>
>>>>       PR IPA/78365
>>>>       * gcc.dg/torture/pr78365.c: New test.
>>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2016-11-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>>>
>>>>       PR IPA/78365
>>>>       * ipa-cp.c (propagate_constants_accross_call): get param type from
>>>> callees
>>>>       DECL_ARGUMENTS if available.
>>>>       * ipa-prop.c (ipa_compute_jump_functions_for_edge): Likewise.
>>>>       (ipcp_update_vr):  Remove now redundant conversion of precision
>>>> for VR.
>>>>       * ipa-prop.h: Make ipa_get_callee_param_type local again.
Martin Jambor Dec. 7, 2016, 10:08 a.m. UTC | #2
Hello Kugan,

sorry, I have lost track of this patch and re-discovered it only now.

On Mon, Nov 28, 2016 at 04:25:00PM +1100, kugan wrote:
> Hi,
> 
> On 24/11/16 19:48, Richard Biener wrote:
> > On Wed, Nov 23, 2016 at 4:33 PM, Martin Jambor <mjambor@suse.cz> wrote:
> > > Hi,
> > > 
> > > On Fri, Nov 18, 2016 at 12:38:18PM +1100, kugan wrote:
> > > > Hi,
> > > > 
> > > > I was relying on ipa_get_callee_param_type to get type of parameter and then
> > > > convert arguments to this type while computing jump functions. However, in
> > > > cases like shown in PR78365, ipa_get_callee_param_type, instead of giving
> > > > up, would return the wrong type.
> > > 
> > > At what stage does this happen?  During analysis
> > > (ipa_compute_jump_functions_for_edge) or at WPA
> > > (propagate_constants_accross_call)?  Both?
> > 
> > Hmm, where does jump function compute require the callee type?
> > In my view the jump function should record
> > 
> >  (expected-incoming-type) arg [OP X]
> > 
> > for each call argument in its body.  Thus required conversions are
> > done at WPA propagation time.
> > 
> > > > I think the current uses of
> > > > ipa_get_callee_param_type are fine with this.
> > > > 
> > > > Attached patch now uses callee's DECL_ARGUMENTS to get the type. If it
> > > > cannot be found, then I would give up and set the jump function to varying.
> > > 
> > > But DECL_ARGUMENTS is not available at WPA stage with LTO so your
> > > patch would make our IPA layer to optimize less with LTO.  This was
> > > the reason to go through the hoops of TYPE_ARG_TYPES in the first
> > > place.
> > > 
> > > If TYPE_ARG_TYPES cannot be trusted, then I'm afraid we are back to
> > > square one and indeed need to put the correct type in jump functions.
> > 
> > If DECL_ARGUMENTS is not available at WPA stage then I see no other
> > way than to put the types on the jump functions.
> 
> Here is a patch that does this. To fox PR78365, in
> ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto
> bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux
> with no new regressions. I will build Firefox and measure the memory usage
> as Honza suggested based on the feedback.
> 

So, do you have any numbers?


> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 2ec671f..3d50041 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -1846,11 +1846,11 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
>  static bool
>  propagate_vr_accross_jump_function (cgraph_edge *cs,
>  				    ipa_jump_func *jfunc,
> -				    struct ipcp_param_lattices *dest_plats,
> -				    tree param_type)
> +				    struct ipcp_param_lattices *dest_plats)
>  {
>    struct ipcp_param_lattices *src_lats;
>    ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
> +  tree param_type = jfunc->param_type;
>  
>    if (dest_lat->bottom_p ())
>      return false;
> @@ -1895,9 +1895,9 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
>        tree val = ipa_get_jf_constant (jfunc);
>        if (TREE_CODE (val) == INTEGER_CST)
>  	{
> +	  val = fold_convert (param_type, val);
>  	  if (TREE_OVERFLOW_P (val))
>  	    val = drop_tree_overflow (val);
> -	  val = fold_convert (param_type, val);
>  	  jfunc->vr_known = true;
>  	  jfunc->m_vr.type = VR_RANGE;
>  	  jfunc->m_vr.min = val;
> @@ -2247,7 +2247,6 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
>      {
>        struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
>        struct ipcp_param_lattices *dest_plats;
> -      tree param_type = ipa_get_callee_param_type (cs, i);
>  
>        dest_plats = ipa_get_parm_lattices (callee_info, i);
>        if (availability == AVAIL_INTERPOSABLE)
> @@ -2264,8 +2263,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
>  						       dest_plats);
>  	  if (opt_for_fn (callee->decl, flag_ipa_vrp))
>  	    ret |= propagate_vr_accross_jump_function (cs,
> -						       jump_func, dest_plats,
> -						       param_type);
> +						       jump_func, dest_plats);
>  	  else
>  	    ret |= dest_plats->m_value_range.set_to_bottom ();
>  	}
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index 90c19fc..235531b 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -1651,14 +1651,24 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
>  /* Return the Ith param type of callee associated with call graph
>     edge E.  */
>  
> -tree
> +static tree
>  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>  {
>    int n;
> +  tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;
> +  if (t)
> +    for (n = 0; n < i; n++)
> +      {
> +	if (!t)
> +	  return NULL;
> +	t = TREE_CHAIN (t);
> +      }
> +  if (t)
> +    return TREE_TYPE (t);
>    tree type = (e->callee
>  	       ? TREE_TYPE (e->callee->decl)
>  	       : gimple_call_fntype (e->call_stmt));
> -  tree t = TYPE_ARG_TYPES (type);
> +  t = TYPE_ARG_TYPES (type);

If TYPE_ARG_TYPES is inherently unreliable then I am afraid you must
not fallback on it but rather return NULL if cs->callee is not
available and adjust the caller to give up in that case.

(I have checked both testcases that we hope to fix with types in jump
functions and the gimple_call_fntype is the same as
TREE_TYPE(e->callee->decl) so that does not help either).

>  
>    for (n = 0; n < i; n++)
>      {
> @@ -1670,15 +1680,6 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>      return TREE_VALUE (t);
>    if (!e->callee)
>      return NULL;
> -  t = DECL_ARGUMENTS (e->callee->decl);
> -  for (n = 0; n < i; n++)
> -    {
> -      if (!t)
> -	return NULL;
> -      t = TREE_CHAIN (t);
> -    }
> -  if (t)
> -    return TREE_TYPE (t);
>    return NULL;
>  }
>  
> @@ -1724,6 +1725,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
>  	    useful_context = true;
>  	}
>  
> +      jfunc->param_type = param_type;
>        if (POINTER_TYPE_P (TREE_TYPE (arg)))
>  	{
>  	  bool addr_nonzero = false;
> @@ -4709,6 +4711,7 @@ ipa_write_jump_function (struct output_block *ob,
>    int i, count;
>  
>    streamer_write_uhwi (ob, jump_func->type);
> +  stream_write_tree (ob, jump_func->param_type, true);
>    switch (jump_func->type)
>      {
>      case IPA_JF_UNKNOWN:
> @@ -4792,6 +4795,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>    int i, count;
>  
>    jftype = (enum jump_func_type) streamer_read_uhwi (ib);
> +  jump_func->param_type = stream_read_tree (ib, data_in);
>    switch (jftype)
>      {
>      case IPA_JF_UNKNOWN:
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 0e75cf4..8dcce99 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -180,6 +180,7 @@ struct GTY (()) ipa_jump_func
>  
>    /* Information about value range.  */
>    bool vr_known;
> +  tree  param_type;

Please add a comment describing what this is.

Otherwise, the intent looks fine to me.

Thanks!

Martin
Kugan Vivekanandarajah Dec. 7, 2016, 10:42 p.m. UTC | #3
Hi Martin,

On 07/12/16 21:08, Martin Jambor wrote:
> Hello Kugan,
>
> sorry, I have lost track of this patch and re-discovered it only now.
>
> On Mon, Nov 28, 2016 at 04:25:00PM +1100, kugan wrote:
>> Hi,
>>
>> On 24/11/16 19:48, Richard Biener wrote:
>>> On Wed, Nov 23, 2016 at 4:33 PM, Martin Jambor <mjambor@suse.cz> wrote:
>>>> Hi,
>>>>
>>>> On Fri, Nov 18, 2016 at 12:38:18PM +1100, kugan wrote:
>>>>> Hi,
>>>>>
>>>>> I was relying on ipa_get_callee_param_type to get type of parameter and then
>>>>> convert arguments to this type while computing jump functions. However, in
>>>>> cases like shown in PR78365, ipa_get_callee_param_type, instead of giving
>>>>> up, would return the wrong type.
>>>>
>>>> At what stage does this happen?  During analysis
>>>> (ipa_compute_jump_functions_for_edge) or at WPA
>>>> (propagate_constants_accross_call)?  Both?
>>>
>>> Hmm, where does jump function compute require the callee type?
>>> In my view the jump function should record
>>>
>>>  (expected-incoming-type) arg [OP X]
>>>
>>> for each call argument in its body.  Thus required conversions are
>>> done at WPA propagation time.
>>>
>>>>> I think the current uses of
>>>>> ipa_get_callee_param_type are fine with this.
>>>>>
>>>>> Attached patch now uses callee's DECL_ARGUMENTS to get the type. If it
>>>>> cannot be found, then I would give up and set the jump function to varying.
>>>>
>>>> But DECL_ARGUMENTS is not available at WPA stage with LTO so your
>>>> patch would make our IPA layer to optimize less with LTO.  This was
>>>> the reason to go through the hoops of TYPE_ARG_TYPES in the first
>>>> place.
>>>>
>>>> If TYPE_ARG_TYPES cannot be trusted, then I'm afraid we are back to
>>>> square one and indeed need to put the correct type in jump functions.
>>>
>>> If DECL_ARGUMENTS is not available at WPA stage then I see no other
>>> way than to put the types on the jump functions.
>>
>> Here is a patch that does this. To fox PR78365, in
>> ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto
>> bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux
>> with no new regressions. I will build Firefox and measure the memory usage
>> as Honza suggested based on the feedback.
>>
>
> So, do you have any numbers?
I am starting this now. Do we have an easiest and accurate way to 
measure memory usage by gcc for Firefox compilation. Honza's LTO blog 
talks about using vmstat.


Thanks,
Kugan
>
>
>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>> index 2ec671f..3d50041 100644
>> --- a/gcc/ipa-cp.c
>> +++ b/gcc/ipa-cp.c
>> @@ -1846,11 +1846,11 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
>>  static bool
>>  propagate_vr_accross_jump_function (cgraph_edge *cs,
>>  				    ipa_jump_func *jfunc,
>> -				    struct ipcp_param_lattices *dest_plats,
>> -				    tree param_type)
>> +				    struct ipcp_param_lattices *dest_plats)
>>  {
>>    struct ipcp_param_lattices *src_lats;
>>    ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
>> +  tree param_type = jfunc->param_type;
>>
>>    if (dest_lat->bottom_p ())
>>      return false;
>> @@ -1895,9 +1895,9 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
>>        tree val = ipa_get_jf_constant (jfunc);
>>        if (TREE_CODE (val) == INTEGER_CST)
>>  	{
>> +	  val = fold_convert (param_type, val);
>>  	  if (TREE_OVERFLOW_P (val))
>>  	    val = drop_tree_overflow (val);
>> -	  val = fold_convert (param_type, val);
>>  	  jfunc->vr_known = true;
>>  	  jfunc->m_vr.type = VR_RANGE;
>>  	  jfunc->m_vr.min = val;
>> @@ -2247,7 +2247,6 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
>>      {
>>        struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
>>        struct ipcp_param_lattices *dest_plats;
>> -      tree param_type = ipa_get_callee_param_type (cs, i);
>>
>>        dest_plats = ipa_get_parm_lattices (callee_info, i);
>>        if (availability == AVAIL_INTERPOSABLE)
>> @@ -2264,8 +2263,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
>>  						       dest_plats);
>>  	  if (opt_for_fn (callee->decl, flag_ipa_vrp))
>>  	    ret |= propagate_vr_accross_jump_function (cs,
>> -						       jump_func, dest_plats,
>> -						       param_type);
>> +						       jump_func, dest_plats);
>>  	  else
>>  	    ret |= dest_plats->m_value_range.set_to_bottom ();
>>  	}
>> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
>> index 90c19fc..235531b 100644
>> --- a/gcc/ipa-prop.c
>> +++ b/gcc/ipa-prop.c
>> @@ -1651,14 +1651,24 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
>>  /* Return the Ith param type of callee associated with call graph
>>     edge E.  */
>>
>> -tree
>> +static tree
>>  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>>  {
>>    int n;
>> +  tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;
>> +  if (t)
>> +    for (n = 0; n < i; n++)
>> +      {
>> +	if (!t)
>> +	  return NULL;
>> +	t = TREE_CHAIN (t);
>> +      }
>> +  if (t)
>> +    return TREE_TYPE (t);
>>    tree type = (e->callee
>>  	       ? TREE_TYPE (e->callee->decl)
>>  	       : gimple_call_fntype (e->call_stmt));
>> -  tree t = TYPE_ARG_TYPES (type);
>> +  t = TYPE_ARG_TYPES (type);
>
> If TYPE_ARG_TYPES is inherently unreliable then I am afraid you must
> not fallback on it but rather return NULL if cs->callee is not
> available and adjust the caller to give up in that case.
>
> (I have checked both testcases that we hope to fix with types in jump
> functions and the gimple_call_fntype is the same as
> TREE_TYPE(e->callee->decl) so that does not help either).
>
>>
>>    for (n = 0; n < i; n++)
>>      {
>> @@ -1670,15 +1680,6 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>>      return TREE_VALUE (t);
>>    if (!e->callee)
>>      return NULL;
>> -  t = DECL_ARGUMENTS (e->callee->decl);
>> -  for (n = 0; n < i; n++)
>> -    {
>> -      if (!t)
>> -	return NULL;
>> -      t = TREE_CHAIN (t);
>> -    }
>> -  if (t)
>> -    return TREE_TYPE (t);
>>    return NULL;
>>  }
>>
>> @@ -1724,6 +1725,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
>>  	    useful_context = true;
>>  	}
>>
>> +      jfunc->param_type = param_type;
>>        if (POINTER_TYPE_P (TREE_TYPE (arg)))
>>  	{
>>  	  bool addr_nonzero = false;
>> @@ -4709,6 +4711,7 @@ ipa_write_jump_function (struct output_block *ob,
>>    int i, count;
>>
>>    streamer_write_uhwi (ob, jump_func->type);
>> +  stream_write_tree (ob, jump_func->param_type, true);
>>    switch (jump_func->type)
>>      {
>>      case IPA_JF_UNKNOWN:
>> @@ -4792,6 +4795,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>    int i, count;
>>
>>    jftype = (enum jump_func_type) streamer_read_uhwi (ib);
>> +  jump_func->param_type = stream_read_tree (ib, data_in);
>>    switch (jftype)
>>      {
>>      case IPA_JF_UNKNOWN:
>> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
>> index 0e75cf4..8dcce99 100644
>> --- a/gcc/ipa-prop.h
>> +++ b/gcc/ipa-prop.h
>> @@ -180,6 +180,7 @@ struct GTY (()) ipa_jump_func
>>
>>    /* Information about value range.  */
>>    bool vr_known;
>> +  tree  param_type;
>
> Please add a comment describing what this is.
>
> Otherwise, the intent looks fine to me.
>
> Thanks!
>
> Martin
>
diff mbox

Patch

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 2ec671f..3d50041 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1846,11 +1846,11 @@  propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
 static bool
 propagate_vr_accross_jump_function (cgraph_edge *cs,
 				    ipa_jump_func *jfunc,
-				    struct ipcp_param_lattices *dest_plats,
-				    tree param_type)
+				    struct ipcp_param_lattices *dest_plats)
 {
   struct ipcp_param_lattices *src_lats;
   ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
+  tree param_type = jfunc->param_type;
 
   if (dest_lat->bottom_p ())
     return false;
@@ -1895,9 +1895,9 @@  propagate_vr_accross_jump_function (cgraph_edge *cs,
       tree val = ipa_get_jf_constant (jfunc);
       if (TREE_CODE (val) == INTEGER_CST)
 	{
+	  val = fold_convert (param_type, val);
 	  if (TREE_OVERFLOW_P (val))
 	    val = drop_tree_overflow (val);
-	  val = fold_convert (param_type, val);
 	  jfunc->vr_known = true;
 	  jfunc->m_vr.type = VR_RANGE;
 	  jfunc->m_vr.min = val;
@@ -2247,7 +2247,6 @@  propagate_constants_accross_call (struct cgraph_edge *cs)
     {
       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
       struct ipcp_param_lattices *dest_plats;
-      tree param_type = ipa_get_callee_param_type (cs, i);
 
       dest_plats = ipa_get_parm_lattices (callee_info, i);
       if (availability == AVAIL_INTERPOSABLE)
@@ -2264,8 +2263,7 @@  propagate_constants_accross_call (struct cgraph_edge *cs)
 						       dest_plats);
 	  if (opt_for_fn (callee->decl, flag_ipa_vrp))
 	    ret |= propagate_vr_accross_jump_function (cs,
-						       jump_func, dest_plats,
-						       param_type);
+						       jump_func, dest_plats);
 	  else
 	    ret |= dest_plats->m_value_range.set_to_bottom ();
 	}
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 90c19fc..235531b 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1651,14 +1651,24 @@  determine_locally_known_aggregate_parts (gcall *call, tree arg,
 /* Return the Ith param type of callee associated with call graph
    edge E.  */
 
-tree
+static tree
 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
 {
   int n;
+  tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;
+  if (t)
+    for (n = 0; n < i; n++)
+      {
+	if (!t)
+	  return NULL;
+	t = TREE_CHAIN (t);
+      }
+  if (t)
+    return TREE_TYPE (t);
   tree type = (e->callee
 	       ? TREE_TYPE (e->callee->decl)
 	       : gimple_call_fntype (e->call_stmt));
-  tree t = TYPE_ARG_TYPES (type);
+  t = TYPE_ARG_TYPES (type);
 
   for (n = 0; n < i; n++)
     {
@@ -1670,15 +1680,6 @@  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
     return TREE_VALUE (t);
   if (!e->callee)
     return NULL;
-  t = DECL_ARGUMENTS (e->callee->decl);
-  for (n = 0; n < i; n++)
-    {
-      if (!t)
-	return NULL;
-      t = TREE_CHAIN (t);
-    }
-  if (t)
-    return TREE_TYPE (t);
   return NULL;
 }
 
@@ -1724,6 +1725,7 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    useful_context = true;
 	}
 
+      jfunc->param_type = param_type;
       if (POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  bool addr_nonzero = false;
@@ -4709,6 +4711,7 @@  ipa_write_jump_function (struct output_block *ob,
   int i, count;
 
   streamer_write_uhwi (ob, jump_func->type);
+  stream_write_tree (ob, jump_func->param_type, true);
   switch (jump_func->type)
     {
     case IPA_JF_UNKNOWN:
@@ -4792,6 +4795,7 @@  ipa_read_jump_function (struct lto_input_block *ib,
   int i, count;
 
   jftype = (enum jump_func_type) streamer_read_uhwi (ib);
+  jump_func->param_type = stream_read_tree (ib, data_in);
   switch (jftype)
     {
     case IPA_JF_UNKNOWN:
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 0e75cf4..8dcce99 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -180,6 +180,7 @@  struct GTY (()) ipa_jump_func
 
   /* Information about value range.  */
   bool vr_known;
+  tree  param_type;
   value_range m_vr;
 
   enum jump_func_type type;
@@ -818,7 +819,6 @@  ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
 						   ipa_parm_adjustment_vec,
 						   bool);
 void ipa_release_body_info (struct ipa_func_body_info *);
-tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
 
 /* From tree-sra.c:  */
 tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, bool, tree,
diff --git a/gcc/testsuite/gcc.dg/torture/pr78365.c b/gcc/testsuite/gcc.dg/torture/pr78365.c
index e69de29..5180a01 100644
--- a/gcc/testsuite/gcc.dg/torture/pr78365.c
+++ b/gcc/testsuite/gcc.dg/torture/pr78365.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+
+int a, b, c;
+char d;
+static void fn1 (void *, int);
+int fn2 (int);
+
+void fn1 (cc, yh) void *cc;
+char yh;
+{
+  char y;
+  a = fn2(c - b + 1);
+  for (; y <= yh; y++)
+    ;
+}
+
+void fn3()
+{
+    fn1((void *)fn3, 1);
+    fn1((void *)fn3, d - 1);
+}