aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2006-05-02 13:54:20 -0600
committerJeff Law <law@gcc.gnu.org>2006-05-02 13:54:20 -0600
commit26ef43017a241c551c893b3d0da3282c68b989fe (patch)
treefb6626d3659e936c2efbe650999f417c6e9eb12a
parente6cbdf26b4b126b1271818399b4069fa9d40d850 (diff)
downloadgcc-26ef43017a241c551c893b3d0da3282c68b989fe.zip
gcc-26ef43017a241c551c893b3d0da3282c68b989fe.tar.gz
gcc-26ef43017a241c551c893b3d0da3282c68b989fe.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr27364.c13
-rw-r--r--gcc/tree-vrp.c24
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 378be12..28e2616 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-05-02 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/27364
+ * tree-vrp.c (vrp_int_const_binop): Fix detection of overflow from
+ multiply expressions.
+
2006-05-02 Tom Tromey <tromey@redhat.com>
* tree-flow-inline.h (op_iter_init_phiuse): Fixed typo.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9608839..2a654bc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-02 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/27364
+ * gcc.c-torture/execute/pr27364.c: New test.
+
2006-05-02 Mark Mitchell <mark@codesourcery.com>
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 0000000..aa608b2
--- /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 7c6fe6e..d487df6 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)