re PR tree-optimization/23128 (VRP fails for unsigned values)

2005-08-05  James A. Morrison  <phython@gcc.gnu.org>

        PR tree-optimization/23128
        * tree-vrp.c (vrp_int_const_binop): Check if unsigned addition or
        subtraction wrap, and set TREE_OVERFLOW if they do.

From-SVN: r102800
This commit is contained in:
James A. Morrison 2005-08-06 05:35:31 +00:00
parent 099f36ab8c
commit b17775aba4
6 changed files with 109 additions and 3 deletions

View file

@ -1,3 +1,9 @@
2005-08-05 James A. Morrison <phython@gcc.gnu.org>
PR tree-optimization/23128
* tree-vrp.c (vrp_int_const_binop): Check if unsigned addition or
subtraction wrap, and set TREE_OVERFLOW if they do.
2005-08-05 Richard Henderson <rth@redhat.com>
PR 21728

View file

@ -1,3 +1,9 @@
2005-08-05 James A. Morrison <phython@gcc.gnu.org>
* gcc.c-torture/execute/vrp-5.c: New test.
* gcc.c-torture/execute/vrp-6.c: New test.
* gcc.dg/tree-ssa/vrp21.c: New test.
2005-08-05 James A. Morrison <phython@gcc.gnu.org>
* g++.dg/parse/pr22514.C: New test.

View file

@ -0,0 +1,22 @@
extern void exit (int);
extern void abort ();
void test(unsigned int a, unsigned int b)
{
if (a < 5)
abort();
if (b < 5)
abort();
if (a + b != 0U)
abort();
}
int main(int argc, char *argv[])
{
unsigned int x = 0x80000000;
test(x, x);
exit (0);
}

View file

@ -0,0 +1,33 @@
#include <limits.h>
extern void exit (int);
extern void abort ();
void test01(unsigned int a, unsigned int b)
{
if (a < 5)
abort();
if (b < 5)
abort();
if (a - b != 5)
abort();
}
void test02(unsigned int a, unsigned int b)
{
if (a >= 12)
if (b > 15)
if (a - b < UINT_MAX - 15U)
abort ();
}
int main(int argc, char *argv[])
{
unsigned x = 0x80000000;
test01(x + 5, x);
test02(14, 16);
exit (0);
}

View file

@ -0,0 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-O1 -ftree-vrp -fdump-tree-vrp" } */
extern void link_error ();
void test01(unsigned int a, unsigned int b)
{
unsigned int x = 0x80000000;
if (a < x)
if (b < x)
if (a > 5)
if (a + b == 0U)
link_error ();
}
void test02(unsigned int a, unsigned int b)
{
unsigned int x = 0x80000000;
if (a > x)
if (b < x)
if (a - b == 1U)
link_error ();
}
/* { dg-final { scan-tree-dump-times "link_error" 0 "vrp" } } */
/* { dg-final { cleanup-tree-dump "vrp" } } */

View file

@ -915,12 +915,25 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
on -INF and +INF. */
res = int_const_binop (code, val1, val2, 0);
if (TYPE_UNSIGNED (TREE_TYPE (val1)))
{
int checkz = compare_values (res, val1);
/* Ensure that res = val1 + val2 >= val1
or that res = val1 - val2 <= val1. */
if ((code == PLUS_EXPR && !(checkz == 1 || checkz == 0))
|| (code == MINUS_EXPR && !(checkz == 0 || checkz == -1)))
{
res = copy_node (res);
TREE_OVERFLOW (res) = 1;
}
}
/* If the operation overflowed but neither VAL1 nor VAL2 are
overflown, return -INF or +INF depending on the operation
and the combination of signs of the operands. */
if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
else if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
{
int sgn1 = tree_int_cst_sgn (val1);
int sgn2 = tree_int_cst_sgn (val2);