diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8eca25049878..6fd39c76efdf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-10-11 Richard Guenther + + PR tree-optimization/28230 + * tree-vrp.c (vrp_int_const_binop): Move flag_wrapv handling + to the correct place. + 2006-10-11 Richard Guenther PR inline-asm/29119 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9b7c54fd6d2..aa9cd9ec1345 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-10-11 Richard Guenther + + PR tree-optimization/28230 + * gcc.dg/torture/pr28230.c: New testcase. + 2006-10-11 Richard Guenther PR inline-asm/29119 diff --git a/gcc/testsuite/gcc.dg/torture/pr28230.c b/gcc/testsuite/gcc.dg/torture/pr28230.c new file mode 100644 index 000000000000..5ecc0c716bae --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr28230.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-fwrapv" } */ + +void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w ); +void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w ) +{ + unsigned n = tn + bb; + do { + e = (e > n) ? e : *w; + n -= (e > n) ? n : e; + if (*w) + *w = 0; + } while ( n ); +} +int main() +{ + unsigned w = 0; + foo( 0, 0, 0, &w ); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index a2127446a852..4a30e4ee8a55 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1235,14 +1235,12 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2) { tree res; - if (flag_wrapv) - return int_const_binop (code, val1, val2, 0); + res = int_const_binop (code, val1, val2, 0); /* If we are not using wrapping arithmetic, operate symbolically on -INF and +INF. */ - res = int_const_binop (code, val1, val2, 0); - - if (TYPE_UNSIGNED (TREE_TYPE (val1))) + if (TYPE_UNSIGNED (TREE_TYPE (val1)) + || flag_wrapv) { int checkz = compare_values (res, val1); bool overflow = false;