This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix double_int overflow in VRP PLUS_EXPR
- From: Richard Guenther <richard dot guenther at gmail dot com>
- To: Marc Glisse <marc dot glisse at inria dot fr>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 22 Aug 2012 14:19:19 +0200
- Subject: Re: Fix double_int overflow in VRP PLUS_EXPR
- References: <alpine.DEB.2.02.1208221346210.21614@stedding.saclay.inria.fr>
On Wed, Aug 22, 2012 at 1:55 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> when I adapted VRP PLUS_EXPR handling for __int128, I missed one place where
> double_int can overflow. Note that I have no idea if that helps for bug
> 54317, but that's where I noticed the issue.
Ok.
Thanks,
Richard.
> 2012-08-21 Marc Glisse <marc.glisse@inria.fr>
>
> PR tree-optimization/54317
>
> gcc/
> * tree-vrp.c (extract_range_from_binary_expr_1): Test for
> double_int overflow.
> Remove dead tests.
>
> gcc/testsuite/
> * gcc.dg/tree-ssa/vrp79.c: New testcase.
>
> --
> Marc Glisse
> Index: testsuite/gcc.dg/tree-ssa/vrp79.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/vrp79.c (revision 0)
> +++ testsuite/gcc.dg/tree-ssa/vrp79.c (revision 0)
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +#ifdef __SIZEOF_INT128__
> +typedef unsigned __int128 NT;
> +#else
> +typedef unsigned long long NT;
> +#endif
> +
> +extern void do_not_go_away ();
> +
> +void f (NT x, NT y)
> +{
> + NT n = 1;
> + n <<= (8 * sizeof (NT) - 1);
> + if (x > n) return;
> + if (y > n) return;
> + NT z = x + y;
> + if (z == 42) do_not_go_away ();
> +}
> +
> +/* { dg-final { scan-tree-dump "do_not_go_away" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
>
> Property changes on: testsuite/gcc.dg/tree-ssa/vrp79.c
> ___________________________________________________________________
> Added: svn:keywords
> + Author Date Id Revision URL
> Added: svn:eol-style
> + native
>
> Index: tree-vrp.c
> ===================================================================
> --- tree-vrp.c (revision 190590)
> +++ tree-vrp.c (working copy)
> @@ -2467,32 +2467,35 @@ extract_range_from_binary_expr_1 (value_
> && max_ovf == 1)
> {
> /* Underflow and overflow, drop to VR_VARYING. */
> set_value_range_to_varying (vr);
> return;
> }
> else
> {
> /* Min underflow or max overflow. The range kind
> changes to VR_ANTI_RANGE. */
> + bool covers = false;
> double_int tem = tmin;
> gcc_assert ((min_ovf == -1 && max_ovf == 0)
> || (max_ovf == 1 && min_ovf == 0));
> type = VR_ANTI_RANGE;
> tmin = double_int_add (tmax, double_int_one);
> + if (double_int_cmp (tmin, tmax, uns) < 0)
> + covers = true;
> tmax = double_int_add (tem, double_int_minus_one);
> + if (double_int_cmp (tmax, tem, uns) > 0)
> + covers = true;
> /* If the anti-range would cover nothing, drop to varying.
> Likewise if the anti-range bounds are outside of the
> types values. */
> - if (double_int_cmp (tmin, tmax, uns) > 0
> - || double_int_cmp (tmin, type_min, uns) < 0
> - || double_int_cmp (tmax, type_max, uns) > 0)
> + if (covers || double_int_cmp (tmin, tmax, uns) > 0)
> {
> set_value_range_to_varying (vr);
> return;
> }
> min = double_int_to_tree (expr_type, tmin);
> max = double_int_to_tree (expr_type, tmax);
> }
> }
> else
> {
>