diff options
author | Diego Novillo <dnovillo@redhat.com> | 2006-02-09 12:38:35 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2006-02-09 07:38:35 -0500 |
commit | 7dc32197a8f098c05d589d80ccbcc7ea51a62bea (patch) | |
tree | 33ef846a4e5a0e2ffd2f172f144a0e07e597bf8d /gcc | |
parent | e10fbf96398ce612c334754e0614c998e3ec3335 (diff) | |
download | gcc-7dc32197a8f098c05d589d80ccbcc7ea51a62bea.zip gcc-7dc32197a8f098c05d589d80ccbcc7ea51a62bea.tar.gz gcc-7dc32197a8f098c05d589d80ccbcc7ea51a62bea.tar.bz2 |
re PR tree-optimization/26180 (wrong code due to VRP and unsigned multiplies with wraps)
PR 26180
* tree-vrp.c (vrp_int_const_binop): Detect overflow when
multiplying unsigned values.
Tidy comments.
testsuite
PR 26180
* gcc.dg/tree-ssa/pr26180.c: New test.
From-SVN: r110794
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr26180.c | 43 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 14 |
4 files changed, 63 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e64fe3..ee54252 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-02-09 Diego Novillo <dnovillo@redhat.com> + + PR 26180 + * tree-vrp.c (vrp_int_const_binop): Detect overflow when + multiplying unsigned values. + Tidy comments. + 2006-02-09 Eric Botcazou <ebotcazou@libertysurf.fr> * config/sparc/sparc.c (tls_call_delay): Fix oversight. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad136b3..e130683 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-02-09 Diego Novillo <dnovillo@redhat.com> + + PR 26180 + * gcc.dg/tree-ssa/pr26180.c: New test. + 2006-02-08 Jeff Law <law@redhat.com> * gcc.dg/tree-ssa/pr21417.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr26180.c b/gcc/testsuite/gcc.dg/tree-ssa/pr26180.c new file mode 100644 index 0000000..730115b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr26180.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +void abort(void); +int bar(int x, int y) +{ + int x1, y1; + int x2, y2; + unsigned int x3, y3, w; + int z = 1; + + x1 = (x < (1 << 30)); + y1 = (y < (1 << 30)); + if (x1) + if (y1) { + x2 = ((x > 0)? (x): -(x)); + y2 = ((y > 0)? (y): -(y)); + + x3 = x2; + y3 = y2; + w = x3 * y3; + + if (w >= (1 << 30)) { + z = 1; + } else { + z = -1; + } + } + + return z; +} + + +int main() +{ + int x, y, z; + x = 536870912; /* 2^29 */ + y = 2; + z = bar(x, y); + if (z != 1) + abort (); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 80dcf39..8734f51 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1191,22 +1191,24 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2) { int checkz = compare_values (res, val1); - /* Ensure that res = val1 + val2 >= 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))) + if (((code == PLUS_EXPR || code == MULT_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. */ else if (TREE_OVERFLOW (res) && !TREE_OVERFLOW (val1) && !TREE_OVERFLOW (val2)) { + /* 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. */ int sgn1 = tree_int_cst_sgn (val1); int sgn2 = tree_int_cst_sgn (val2); |