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:
parent
099f36ab8c
commit
b17775aba4
6 changed files with 109 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
22
gcc/testsuite/gcc.c-torture/execute/vrp-5.c
Normal file
22
gcc/testsuite/gcc.c-torture/execute/vrp-5.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
33
gcc/testsuite/gcc.c-torture/execute/vrp-6.c
Normal file
33
gcc/testsuite/gcc.c-torture/execute/vrp-6.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
26
gcc/testsuite/gcc.dg/tree-ssa/vrp21.c
Normal file
26
gcc/testsuite/gcc.dg/tree-ssa/vrp21.c
Normal 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" } } */
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue