aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2005-08-06 05:35:31 +0000
committerJames A. Morrison <phython@gcc.gnu.org>2005-08-06 05:35:31 +0000
commitb17775aba4c709c1fc3f19af33d50b025e3891f4 (patch)
tree2e47c97b535d7d1d721621ee6339c61536de7863
parent099f36ab8c55844ae47def2f3cacaef7d006d441 (diff)
downloadgcc-b17775aba4c709c1fc3f19af33d50b025e3891f4.zip
gcc-b17775aba4c709c1fc3f19af33d50b025e3891f4.tar.gz
gcc-b17775aba4c709c1fc3f19af33d50b025e3891f4.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vrp-5.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vrp-6.c33
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp21.c26
-rw-r--r--gcc/tree-vrp.c19
6 files changed, 109 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a9b189..db61463 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0fb7f3..8b37d46 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
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.
2005-08-05 J"orn Rennecke <joern.rennecke@st.com>
diff --git a/gcc/testsuite/gcc.c-torture/execute/vrp-5.c b/gcc/testsuite/gcc.c-torture/execute/vrp-5.c
new file mode 100644
index 0000000..8f3c725
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/vrp-5.c
@@ -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);
+}
+
+
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/vrp-6.c b/gcc/testsuite/gcc.c-torture/execute/vrp-6.c
new file mode 100644
index 0000000..7c6a175
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/vrp-6.c
@@ -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);
+}
+
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp21.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp21.c
new file mode 100644
index 0000000..3cd817d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp21.c
@@ -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" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 68bcb1e..a77be84 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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);