From 26ef43017a241c551c893b3d0da3282c68b989fe Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 2 May 2006 13:54:20 -0600 Subject: [PATCH] re PR tree-optimization/27364 (VRP miscompiles some unsigned math) PR tree-optimization/27364 * tree-vrp.c (vrp_int_const_binop): Fix detection of overflow from multiply expressions. * gcc.c-torture/execute/pr27364.c: New test. From-SVN: r113481 --- gcc/ChangeLog | 6 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/execute/pr27364.c | 13 ++++++++++ gcc/tree-vrp.c | 24 ++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr27364.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 378be12e2ce..28e261605e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-05-02 Jeff Law + + PR tree-optimization/27364 + * tree-vrp.c (vrp_int_const_binop): Fix detection of overflow from + multiply expressions. + 2006-05-02 Tom Tromey * tree-flow-inline.h (op_iter_init_phiuse): Fixed typo. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9608839ee78..2a654bc87d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-05-02 Jeff Law + + PR tree-optimization/27364 + * gcc.c-torture/execute/pr27364.c: New test. + 2006-05-02 Mark Mitchell PR c++/27309 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr27364.c b/gcc/testsuite/gcc.c-torture/execute/pr27364.c new file mode 100644 index 00000000000..aa608b2a2fe --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr27364.c @@ -0,0 +1,13 @@ +int f(unsigned number_of_digits_to_use) +{ + if (number_of_digits_to_use >1294) + return 0; + return (number_of_digits_to_use * 3321928 / 1000000 + 1) /16; +} + +int main(void) +{ + if (f(11) != 2) + __builtin_abort (); + exit (0); +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 7c6fe6e32ab..d487df62caa 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1191,17 +1191,39 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2) if (TYPE_UNSIGNED (TREE_TYPE (val1))) { int checkz = compare_values (res, val1); + bool overflow = false; /* Ensure that res = val1 [+*] val2 >= val1 or that res = val1 - val2 <= val1. */ - if (((code == PLUS_EXPR || code == MULT_EXPR) + if ((code == PLUS_EXPR && !(checkz == 1 || checkz == 0)) || (code == MINUS_EXPR && !(checkz == 0 || checkz == -1))) + { + overflow = true; + } + /* Checking for multiplication overflow is done by dividing the + output of the multiplication by the first input of the + multiplication. If the result of that division operation is + not equal to the second input of the multiplication, then the + multiplication overflowed. */ + else if (code == MULT_EXPR && !integer_zerop (val1)) + { + tree tmp = int_const_binop (TRUNC_DIV_EXPR, + TYPE_MAX_VALUE (TREE_TYPE (val1)), + val1, 0); + int check = compare_values (tmp, val2); + + if (check != 0) + overflow = true; + } + + if (overflow) { res = copy_node (res); TREE_OVERFLOW (res) = 1; } + } else if (TREE_OVERFLOW (res) && !TREE_OVERFLOW (val1)