aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-04-05 08:16:38 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-04-05 08:16:38 +0000
commit6eee98936968c67edc8d9190b215819498840b57 (patch)
tree45b8361ffc4c1c5d575d89fb35f70ef96623e1d1 /gcc
parent80521187ef59a2d150007032f04c2ccdeb59afe1 (diff)
downloadgcc-6eee98936968c67edc8d9190b215819498840b57.zip
gcc-6eee98936968c67edc8d9190b215819498840b57.tar.gz
gcc-6eee98936968c67edc8d9190b215819498840b57.tar.bz2
re PR tree-optimization/26763 (wrong final value of induction variable calculated)
2006-04-05 Richard Guenther <rguenther@suse.de> PR tree-optimization/26763 * fold-const.c (fold_comparison): Move folding of PTR + CST CMP PTR + CST ... (fold_binary): ... here. Fold only for EQ_EXPR and NE_EXPR. * gcc.dg/torture/pr26763-1.c: New testcase. * gcc.dg/torture/pr26763-2.c: Likewise. From-SVN: r112697
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c55
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr26763-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr26763-2.c18
5 files changed, 77 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa7f412..5c3f251 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-04-05 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/26763
+ * fold-const.c (fold_comparison): Move folding of
+ PTR + CST CMP PTR + CST ...
+ (fold_binary): ... here. Fold only for EQ_EXPR and NE_EXPR.
+
2006-04-05 Gerald Pfeifer <gerald@pfeifer.com>
* doc/install.texi (Prerequisites): Refine some wording on
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index aa710b1..d8f7efc 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -7305,33 +7305,6 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
if (tree_swap_operands_p (arg0, arg1, true))
return fold_build2 (swap_tree_comparison (code), type, op1, op0);
- /* If this is a comparison of two exprs that look like an
- ARRAY_REF of the same object, then we can fold this to a
- comparison of the two offsets. */
- {
- tree base0, offset0, base1, offset1;
-
- if (extract_array_ref (arg0, &base0, &offset0)
- && extract_array_ref (arg1, &base1, &offset1)
- && operand_equal_p (base0, base1, 0))
- {
- /* Handle no offsets on both sides specially. */
- if (offset0 == NULL_TREE && offset1 == NULL_TREE)
- return fold_build2 (code, type, integer_zero_node,
- integer_zero_node);
-
- if (!offset0 || !offset1
- || TREE_TYPE (offset0) == TREE_TYPE (offset1))
- {
- if (offset0 == NULL_TREE)
- offset0 = build_int_cst (TREE_TYPE (offset1), 0);
- if (offset1 == NULL_TREE)
- offset1 = build_int_cst (TREE_TYPE (offset0), 0);
- return fold_build2 (code, type, offset0, offset1);
- }
- }
- }
-
/* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 +- C1. */
if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
@@ -10062,6 +10035,34 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
tem, build_int_cst (TREE_TYPE (tem), 0));
}
+ /* If this is a comparison of two exprs that look like an
+ ARRAY_REF of the same object, then we can fold this to a
+ comparison of the two offsets. This is only safe for
+ EQ_EXPR and NE_EXPR because of overflow issues. */
+ {
+ tree base0, offset0, base1, offset1;
+
+ if (extract_array_ref (arg0, &base0, &offset0)
+ && extract_array_ref (arg1, &base1, &offset1)
+ && operand_equal_p (base0, base1, 0))
+ {
+ /* Handle no offsets on both sides specially. */
+ if (offset0 == NULL_TREE && offset1 == NULL_TREE)
+ return fold_build2 (code, type, integer_zero_node,
+ integer_zero_node);
+
+ if (!offset0 || !offset1
+ || TREE_TYPE (offset0) == TREE_TYPE (offset1))
+ {
+ if (offset0 == NULL_TREE)
+ offset0 = build_int_cst (TREE_TYPE (offset1), 0);
+ if (offset1 == NULL_TREE)
+ offset1 = build_int_cst (TREE_TYPE (offset0), 0);
+ return fold_build2 (code, type, offset0, offset1);
+ }
+ }
+ }
+
if (integer_zerop (arg1)
&& tree_expr_nonzero_p (arg0))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index da9fedb..8c32d4e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-04-05 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/26763
+ * gcc.dg/torture/pr26763-1.c: New testcase.
+ * gcc.dg/torture/pr26763-2.c: Likewise.
+
2006-04-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/23634
diff --git a/gcc/testsuite/gcc.dg/torture/pr26763-1.c b/gcc/testsuite/gcc.dg/torture/pr26763-1.c
new file mode 100644
index 0000000..37054e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr26763-1.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+extern void abort(void);
+
+int try (int *a)
+{
+ return a + -1 > a;
+}
+
+int main(void)
+{
+ int bla[100];
+
+ if (try (bla + 50))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr26763-2.c b/gcc/testsuite/gcc.dg/torture/pr26763-2.c
new file mode 100644
index 0000000..d8155fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr26763-2.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+extern void abort(void);
+
+int try (char *a, int d)
+{
+ return a + d > a;
+}
+
+int main(void)
+{
+ char bla[100];
+
+ if (try (bla + 50, -1))
+ abort ();
+
+ return 0;
+}