aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr43000.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr43002.c16
-rw-r--r--gcc/tree-vrp.c6
5 files changed, 55 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e9a82c9..73e2be6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-02-09 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/43000
+ * tree-vrp.c (vrp_int_const_binop): Only handle unsigned
+ arithmetic manually.
+
2010-02-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/42931
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c92c428..bbc21ec2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-02-09 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/43000
+ * gcc.dg/torture/pr43000.c: New testcase.
+ * gcc.dg/torture/pr43002.c: Likewise.
+
2010-02-09 Daniel Kraft <d@domob.eu>
PR fortran/39171
diff --git a/gcc/testsuite/gcc.dg/torture/pr43000.c b/gcc/testsuite/gcc.dg/torture/pr43000.c
new file mode 100644
index 0000000..c1123375
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr43000.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-fwrapv" } */
+
+int __attribute__((noinline))
+foo (long i, long j)
+{
+ if (i >= 1)
+ if (j > -(long)(((unsigned long)(long)-1)>>1))
+ {
+ long x;
+ j--;
+ x = i + j;
+ if (x >= 0)
+ return 1;
+ }
+ return 0;
+}
+extern void abort (void);
+int main()
+{
+ if (foo (1, 1) != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr43002.c b/gcc/testsuite/gcc.dg/torture/pr43002.c
new file mode 100644
index 0000000..f28a910
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr43002.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -fwrapv" } */
+
+long A[4], B[100];
+
+void foo(void)
+{
+ int i, j, k = 3;
+ while (A[k] && k > 0) k--; /* k = {0, 1, 2, 3} */
+ for (i = 3 - k; i >= 0; i--) /* i = {0..3-k} */
+ for (j = 0; j <= k; j++) { /* line 8; j = {0..k} */
+ B[i + j] = 0; /* line 9; i + j = {0..3-k+k} = {0..3} */
+ for (j = 0; j <= k; j++); /* only one iteration is done, with j == 0 */
+ }
+}
+
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index c1ba16a..73dcf23 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1898,9 +1898,9 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
res = int_const_binop (code, val1, val2, 0);
- /* If we are not using wrapping arithmetic, operate symbolically
- on -INF and +INF. */
- if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
+ /* If we are using unsigned arithmetic, operate symbolically
+ on -INF and +INF as int_const_binop only handles signed overflow. */
+ if (TYPE_UNSIGNED (TREE_TYPE (val1)))
{
int checkz = compare_values (res, val1);
bool overflow = false;