[PATCH] Fix ICE due to IPA-VRP (PR tree-optimization/78681)

Richard Biener rguenther@suse.de
Tue Dec 6 08:37:00 GMT 2016


On Mon, 5 Dec 2016, Jakub Jelinek wrote:

> Hi!
> 
> As shown on the testcase, with K&R definitions and fn prototypes with
> promoted types, we can end up computing caller's value ranges in wider
> type than the parameter actually has in the function.
> The problem with that is that wide_int_storage::from can actually wrap
> around, so either as in the testcase we end up with invalid range (minimum
> larger than maximum), or just with a range that doesn't cover all the values
> the parameter can have.
> The patch punts if the range bounds cast to type aren't equal to the
> original values.  Similarly (just theoretical), for pointers it only
> optimizes if the caller's precision as at most as wide as the pointer,
> if it would be wider, even ~[0, 0] range could actually be a NULL pointer
> (some multiple of ~(uintptr_t)0 + (uintmax_t) 1).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok, but I wonder whether this also addresses PR78365 which has a
patch pending (to be reviewed by IPA maintainers) that makes propagation
across such calls more sensible by recording type information in
the jump functions.

Thanks,
Richard.

> 2016-12-05  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/78681
> 	* ipa-prop.c (ipcp_update_vr): Punt if vr[i].min precision is bigger
> 	then type's precision and vr[i].min or vr[i].max in type would wrap.
> 
> 	* gcc.c-torture/compile/pr78681.c: New test.
> 
> --- gcc/ipa-prop.c.jj	2016-11-25 18:11:05.000000000 +0100
> +++ gcc/ipa-prop.c	2016-12-05 18:48:48.853882864 +0100
> @@ -5709,8 +5709,23 @@ ipcp_update_vr (struct cgraph_node *node
>  	{
>  	  tree type = TREE_TYPE (ddef);
>  	  unsigned prec = TYPE_PRECISION (type);
> +	  unsigned mprec = wi::get_precision (vr[i].min);
> +	  gcc_assert (mprec == wi::get_precision (vr[i].max));
>  	  if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
>  	    {
> +	      if (prec < mprec)
> +		{
> +		  /* If there is a disagreement between callers and callee
> +		     on the argument type, e.g. when using K&R function
> +		     definitions, punt if vr[i].min or vr[i].max are outside
> +		     of type's precision.  */
> +		  wide_int m = wi::ext (vr[i].min, prec, TYPE_SIGN (type));
> +		  if (m != vr[i].min)
> +		    continue;
> +		  m = wi::ext (vr[i].max, prec, TYPE_SIGN (type));
> +		  if (m != vr[i].max)
> +		    continue;
> +		}
>  	      if (dump_file)
>  		{
>  		  fprintf (dump_file, "Setting value range of param %u ", i);
> @@ -5729,6 +5744,7 @@ ipcp_update_vr (struct cgraph_node *node
>  	    }
>  	  else if (POINTER_TYPE_P (TREE_TYPE (ddef))
>  		   && vr[i].type == VR_ANTI_RANGE
> +		   && mprec <= prec
>  		   && wi::eq_p (vr[i].min, 0)
>  		   && wi::eq_p (vr[i].max, 0))
>  	    {
> --- gcc/testsuite/gcc.c-torture/compile/pr78681.c.jj	2016-12-05 19:51:15.353646309 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr78681.c	2016-12-05 19:50:57.000000000 +0100
> @@ -0,0 +1,27 @@
> +/* PR tree-optimization/78681 */
> +
> +struct S { char b; };
> +char d, e, f, l, m;
> +struct S n;
> +int bar (char, char);
> +static void foo (struct S *, int, int, int, int);
> +
> +static void
> +foo (x, g, h, i, j)
> +  struct S *x;
> +  char g, h, i, j;
> +{
> +  char k;
> +  for (k = 0; k <= j; k++)
> +    if (bar (g, k))
> +      for (; i; k++)
> +	if (d)
> +	  x->b = g;
> +}
> +
> +void
> +baz (int q)
> +{
> +  foo (&n, m, l, f, 1);
> +  foo (&n, m, e, f, e - 1);
> +}
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)



More information about the Gcc-patches mailing list