From 25bf4cabd21a584abe8a88230cb67fe57db6bae4 Mon Sep 17 00:00:00 2001
From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 5 Apr 2006 08:16:38 +0000
Subject: [PATCH] 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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112697 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                            |  7 +++
 gcc/fold-const.c                         | 55 ++++++++++++------------
 gcc/testsuite/ChangeLog                  |  6 +++
 gcc/testsuite/gcc.dg/torture/pr26763-1.c | 18 ++++++++
 gcc/testsuite/gcc.dg/torture/pr26763-2.c | 18 ++++++++
 5 files changed, 77 insertions(+), 27 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr26763-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr26763-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa7f4128f51a..5c3f2515db51 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 aa710b126c8a..d8f7efc62e5c 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 da9fedb6c58c..8c32d4ee2c87 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 000000000000..37054e7a4fbe
--- /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 000000000000..d8155fb0831a
--- /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;
+}
-- 
GitLab