This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix ICE due to IPA-VRP (PR tree-optimization/78681)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, kugan dot vivekanandarajah at linaro dot org, Jan Hubicka <jh at suse dot de>
- Date: Tue, 6 Dec 2016 09:36:55 +0100 (CET)
- Subject: Re: [PATCH] Fix ICE due to IPA-VRP (PR tree-optimization/78681)
- Authentication-results: sourceware.org; auth=none
- References: <20161205211417.GY3541@tucnak.redhat.com>
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)