aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@redhat.com>2005-06-28 00:52:35 +0000
committerDiego Novillo <dnovillo@gcc.gnu.org>2005-06-27 20:52:35 -0400
commit3eca1bd776507834a9092ee8c871e91e78ef59b8 (patch)
tree6ac1b1fa0c3b8ade5a237d12fe531f37f0172b03 /gcc
parent5ab2b3e44e3a264663c716a85cd8d7566043ac7c (diff)
downloadgcc-3eca1bd776507834a9092ee8c871e91e78ef59b8.zip
gcc-3eca1bd776507834a9092ee8c871e91e78ef59b8.tar.gz
gcc-3eca1bd776507834a9092ee8c871e91e78ef59b8.tar.bz2
re PR tree-optimization/21959 (vrp miscompiles Ada front-end, drops loop exit test in well-defined wrap-around circumstances)
PR 21959 * tree-ssa-loop-niter.c (scev_probably_wraps_p): Handle type casts between unsigned and signed types with different size or precision. testsuite/ChangeLog PR 21959 * gcc.dg/tree-ssa/pr21959.c: New test. From-SVN: r101365
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21959.c20
-rw-r--r--gcc/tree-ssa-loop-niter.c35
4 files changed, 67 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bdbbe42..d8fdb6d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-06-27 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21959
+ * tree-ssa-loop-niter.c (scev_probably_wraps_p): Handle type
+ casts between unsigned and signed types with different size
+ or precision.
+
2005-06-28 Jan Hubicka <jh@suse.cz>
* tree-optimize.c (exercute_free_datastructures):
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 31444a4..1fab590 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-27 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21959
+ * gcc.dg/tree-ssa/pr21959.c: New test.
+
2005-06-27 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/builtins/lib/main.c (abort): Add prototype.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21959.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21959.c
new file mode 100644
index 0000000..7b83b03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21959.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+unsigned char c[0xFF];
+void f(void)
+{
+ unsigned char i;
+ c[128] = 128;
+ i = 0;
+ while (1)
+ {
+ /* This predicate should not be folded out. */
+ if (((signed char) i) < 0) break;
+ c[i] = ' ';
+ i++;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate " 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 83c291d..c99aa38 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1649,6 +1649,41 @@ scev_probably_wraps_p (tree type, tree base, tree step,
return true;
}
+ /* If AT_STMT represents a cast operation, we may not be able to
+ take advantage of the undefinedness of signed type evolutions.
+ See PR 21959 for a test case. Essentially, given a cast
+ operation
+ unsigned char i;
+ signed char i.0;
+ ...
+ i.0_6 = (signed char) i_2;
+ if (i.0_6 < 0)
+ ...
+
+ where i_2 and i.0_6 have the scev {0, +, 1}, we would consider
+ i_2 to wrap around, but not i.0_6, because it is of a signed
+ type. This causes VRP to erroneously fold the predicate above
+ because it thinks that i.0_6 cannot be negative. */
+ if (TREE_CODE (at_stmt) == MODIFY_EXPR)
+ {
+ tree rhs = TREE_OPERAND (at_stmt, 1);
+ tree outer_t = TREE_TYPE (rhs);
+
+ if (!TYPE_UNSIGNED (outer_t)
+ && (TREE_CODE (rhs) == NOP_EXPR || TREE_CODE (rhs) == CONVERT_EXPR))
+ {
+ tree inner_t = TREE_TYPE (TREE_OPERAND (rhs, 0));
+
+ /* If the inner type is unsigned and its size and/or
+ precision are smaller to that of the outer type, then the
+ expression may wrap around. */
+ if (TYPE_UNSIGNED (inner_t)
+ && (TYPE_SIZE (inner_t) <= TYPE_SIZE (outer_t)
+ || TYPE_PRECISION (inner_t) <= TYPE_PRECISION (outer_t)))
+ return true;
+ }
+ }
+
/* After having set INIT_IS_MAX, we can return false: when not using
wrapping arithmetic, signed types don't wrap. */
if (!flag_wrapv && !TYPE_UNSIGNED (type))