From 3e0de2559ee1d85b0b37caf4be13e602b3b54de3 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Mon, 15 Oct 2007 14:49:55 +0000
Subject: [PATCH] fold-const.c (extract_array_ref): Remove.

2007-10-15  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (extract_array_ref): Remove.
	(fold_comparison): Handle POINTER_PLUS_EXPR with the
	generic address expression comparison folding.  Remove
	the folding that used extract_array_ref.

From-SVN: r129347
---
 gcc/ChangeLog    |   7 +++
 gcc/fold-const.c | 129 ++++++-----------------------------------------
 2 files changed, 22 insertions(+), 114 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 536ef54396bb..12452b5bfa9c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-10-15  Richard Guenther  <rguenther@suse.de>
+
+	* fold-const.c (extract_array_ref): Remove.
+	(fold_comparison): Handle POINTER_PLUS_EXPR with the
+	generic address expression comparison folding.  Remove
+	the folding that used extract_array_ref.
+
 2007-10-15  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
 	PR target/33133
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 4a8153cb499d..fd5a7085e913 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6322,76 +6322,6 @@ constant_boolean_node (int value, tree type)
 }
 
 
-/* Return true if expr looks like an ARRAY_REF and set base and
-   offset to the appropriate trees.  If there is no offset,
-   offset is set to NULL_TREE.  Base will be canonicalized to
-   something you can get the element type from using
-   TREE_TYPE (TREE_TYPE (base)).  Offset will be the offset
-   in bytes to the base in sizetype.  */
-
-static bool
-extract_array_ref (tree expr, tree *base, tree *offset)
-{
-  /* One canonical form is a PLUS_EXPR with the first
-     argument being an ADDR_EXPR with a possible NOP_EXPR
-     attached.  */
-  if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
-    {
-      tree op0 = TREE_OPERAND (expr, 0);
-      tree inner_base, dummy1;
-      /* Strip NOP_EXPRs here because the C frontends and/or
-	 folders present us (int *)&x.a p+ 4 possibly.  */
-      STRIP_NOPS (op0);
-      if (extract_array_ref (op0, &inner_base, &dummy1))
-	{
-	  *base = inner_base;
-	  *offset = fold_convert (sizetype, TREE_OPERAND (expr, 1));
-	  if (dummy1 != NULL_TREE)
-	    *offset = fold_build2 (PLUS_EXPR, sizetype,
-				   dummy1, *offset);
-	  return true;
-	}
-    }
-  /* Other canonical form is an ADDR_EXPR of an ARRAY_REF,
-     which we transform into an ADDR_EXPR with appropriate
-     offset.  For other arguments to the ADDR_EXPR we assume
-     zero offset and as such do not care about the ADDR_EXPR
-     type and strip possible nops from it.  */
-  else if (TREE_CODE (expr) == ADDR_EXPR)
-    {
-      tree op0 = TREE_OPERAND (expr, 0);
-      if (TREE_CODE (op0) == ARRAY_REF)
-	{
-	  tree idx = TREE_OPERAND (op0, 1);
-	  *base = TREE_OPERAND (op0, 0);
-	  *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
-				 array_ref_element_size (op0)); 
-	  *offset = fold_convert (sizetype, *offset);
-	}
-      else
-	{
-	  /* Handle array-to-pointer decay as &a.  */
-	  if (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
-	    *base = TREE_OPERAND (expr, 0);
-	  else
-	    *base = expr;
-	  *offset = NULL_TREE;
-	}
-      return true;
-    }
-  /* The next canonical form is a VAR_DECL with POINTER_TYPE.  */
-  else if (SSA_VAR_P (expr)
-	   && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
-    {
-      *base = expr;
-      *offset = NULL_TREE;
-      return true;
-    }
-
-  return false;
-}
-
-
 /* Transform `a + (b ? x : y)' into `b ? (a + x) : (a + y)'.
    Transform, `a + (x < y)' into `(x < y) ? (a + 1) : (a + 0)'.  Here
    CODE corresponds to the `+', COND to the `(b ? x : y)' or `(x < y)'
@@ -8802,11 +8732,13 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
 
   /* For comparisons of pointers we can decompose it to a compile time
      comparison of the base objects and the offsets into the object.
-     This requires at least one operand being an ADDR_EXPR to do more
-     than the operand_equal_p test below.  */
+     This requires at least one operand being an ADDR_EXPR or a
+     POINTER_PLUS_EXPR to do more than the operand_equal_p test below.  */
   if (POINTER_TYPE_P (TREE_TYPE (arg0))
       && (TREE_CODE (arg0) == ADDR_EXPR
-	  || TREE_CODE (arg1) == ADDR_EXPR))
+	  || TREE_CODE (arg1) == ADDR_EXPR
+	  || TREE_CODE (arg0) == POINTER_PLUS_EXPR
+	  || TREE_CODE (arg1) == POINTER_PLUS_EXPR))
     {
       tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
       HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
@@ -8828,6 +8760,11 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
 	  else
 	    indirect_base0 = true;
 	}
+      else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+	{
+	  base0 = TREE_OPERAND (arg0, 0);
+	  offset0 = TREE_OPERAND (arg0, 1);
+	}
 
       base1 = arg1;
       if (TREE_CODE (arg1) == ADDR_EXPR)
@@ -8843,6 +8780,11 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
 	  else if (!indirect_base0)
 	    base1 = NULL_TREE;
 	}
+      else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
+	{
+	  base1 = TREE_OPERAND (arg1, 0);
+	  offset1 = TREE_OPERAND (arg1, 1);
+	}
       else if (indirect_base0)
 	base1 = NULL_TREE;
 
@@ -8904,47 +8846,6 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
 	}
     }
 
-  /* 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 in
-     signed size type.  This is possible because pointer arithmetic is
-     restricted to retain within an object and overflow on pointer differences
-     is undefined as of 6.5.6/8 and /9 with respect to the signed ptrdiff_t.
-
-     We check flag_wrapv directly because pointers types are unsigned,
-     and therefore TYPE_OVERFLOW_WRAPS returns true for them.  That is
-     normally what we want to avoid certain odd overflow cases, but
-     not here.  */
-  if (POINTER_TYPE_P (TREE_TYPE (arg0))
-      && !flag_wrapv
-      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (arg0)))
-    {
-      tree base0, offset0, base1, offset1;
-
-      if (extract_array_ref (arg0, &base0, &offset0)
-	  && extract_array_ref (arg1, &base1, &offset1)
-	  && operand_equal_p (base0, base1, 0))
-        {
-	  tree signed_size_type_node;
-	  signed_size_type_node = signed_type_for (size_type_node);
-
-	  /* By converting to signed size type we cover middle-end pointer
-	     arithmetic which operates on unsigned pointer types of size
-	     type size and ARRAY_REF offsets which are properly sign or
-	     zero extended from their type in case it is narrower than
-	     size type.  */
-	  if (offset0 == NULL_TREE)
-	    offset0 = build_int_cst (signed_size_type_node, 0);
-	  else
-	    offset0 = fold_convert (signed_size_type_node, offset0);
-	  if (offset1 == NULL_TREE)
-	    offset1 = build_int_cst (signed_size_type_node, 0);
-	  else
-	    offset1 = fold_convert (signed_size_type_node, offset1);
-
-	  return fold_build2 (code, type, offset0, offset1);
-	}
-    }
-
   /* Transform comparisons of the form X +- C1 CMP Y +- C2 to
      X CMP Y +- C2 +- C1 for signed X, Y.  This is valid if
      the resulting offset is smaller in absolute value than the
-- 
GitLab