This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR26763
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Apr 2006 10:10:24 +0200 (CEST)
- Subject: [PATCH] Fix PR26763
This fixes the PR for mainline.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Ok for mainline?
Thanks,
Richard.
:ADDPATCH middle-end:
2006-04-03 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.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 112634)
--- fold-const.c (working copy)
*************** fold_comparison (enum tree_code code, tr
*** 7305,7337 ****
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
--- 7306,7311 ----
*************** fold_binary (enum tree_code code, tree t
*** 10062,10067 ****
--- 10082,10115 ----
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))
{
Index: testsuite/gcc.dg/torture/pr26763-1.c
===================================================================
*** testsuite/gcc.dg/torture/pr26763-1.c (revision 0)
--- testsuite/gcc.dg/torture/pr26763-1.c (revision 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;
+ }
Index: testsuite/gcc.dg/torture/pr26763-2.c
===================================================================
*** testsuite/gcc.dg/torture/pr26763-2.c (revision 0)
--- testsuite/gcc.dg/torture/pr26763-2.c (revision 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;
+ }