From aa0f70e672f6723e56d2a88be36060d7825fe179 Mon Sep 17 00:00:00 2001
From: Steve Ellcey <sje@cup.hp.com>
Date: Tue, 23 Jul 2002 14:58:04 +0000
Subject: [PATCH] explow.c (convert_memory_address): Fix conversion of CONSTs.

	* gcc/explow.c (convert_memory_address): Fix conversion of CONSTs.
	Fix permutation of conversion and plus/mult.

	* gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is
	ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined.
	(expand_builtin_strncpy) Ditto.
	(expand_builtin_memset) Ditto.

From-SVN: r55679
---
 gcc/ChangeLog  |  9 +++++++++
 gcc/builtins.c | 44 ++++++++++++++++++++++++++++++++++++++------
 gcc/explow.c   | 32 ++++++++++++++++++++++----------
 3 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aeb15c449138..b9f0d3632fa0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2002-07-23  Steve Ellcey  <sje@cup.hp.com>
+
+	* gcc/explow.c (convert_memory_address): Fix conversion of CONSTs.
+	Fix permutation of conversion and plus/mult.
+	* gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is
+	ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined.
+	(expand_builtin_strncpy) Ditto.
+	(expand_builtin_memset) Ditto.
+
 2002-07-23  Gabriel Dos Reis  <gdr@nerim.net>
 
 	Fix PR/7363:
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 457067649c0d..1c8e8a8ea4d8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1981,7 +1981,12 @@ expand_builtin_memcpy (arglist, target, mode)
 	  store_by_pieces (dest_mem, INTVAL (len_rtx),
 			   builtin_memcpy_read_str,
 			   (PTR) src_str, dest_align);
-	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_mem) != ptr_mode)
+	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
+#endif
+	  return dest_mem;
 	}
 
       src_mem = get_memory_rtx (src);
@@ -1991,7 +1996,13 @@ expand_builtin_memcpy (arglist, target, mode)
       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx);
 
       if (dest_addr == 0)
-	dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	{
+	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_addr) != ptr_mode)
+	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
+#endif
+	}
 
       return dest_addr;
     }
@@ -2107,7 +2118,12 @@ expand_builtin_strncpy (arglist, target, mode)
 	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
 			   builtin_strncpy_read_str,
 			   (PTR) p, dest_align);
-	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_mem) != ptr_mode)
+	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
+#endif
+	  return dest_mem;
 	}
 
       /* OK transform into builtin memcpy.  */
@@ -2232,7 +2248,12 @@ expand_builtin_memset (exp, target, mode)
 	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
 			   builtin_memset_gen_str,
 			   (PTR)val_rtx, dest_align);
-	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_mem) != ptr_mode)
+	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
+#endif
+	  return dest_mem;
 	}
 
       if (target_char_cast (val, &c))
@@ -2251,7 +2272,12 @@ expand_builtin_memset (exp, target, mode)
 	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
 			   builtin_memset_read_str,
 			   (PTR) &c, dest_align);
-	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_mem) != ptr_mode)
+	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
+#endif
+	  return dest_mem;
 	}
 
       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
@@ -2261,7 +2287,13 @@ expand_builtin_memset (exp, target, mode)
       dest_addr = clear_storage (dest_mem, len_rtx);
 
       if (dest_addr == 0)
-	dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+	{
+	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  if (GET_MODE (dest_addr) != ptr_mode)
+	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
+#endif
+	}
 
       return dest_addr;
     }
diff --git a/gcc/explow.c b/gcc/explow.c
index 13a7b82be5be..3cda41046723 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -353,6 +353,7 @@ convert_memory_address (to_mode, x)
 {
   enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
   rtx temp;
+  enum rtx_code code;
 
   /* Here we handle some special cases.  If none of them apply, fall through
      to the default case.  */
@@ -360,7 +361,18 @@ convert_memory_address (to_mode, x)
     {
     case CONST_INT:
     case CONST_DOUBLE:
-      return x;
+      if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode))
+	code = TRUNCATE;
+      else if (POINTERS_EXTEND_UNSIGNED < 0)
+	break;
+      else if (POINTERS_EXTEND_UNSIGNED > 0)
+	code = ZERO_EXTEND;
+      else
+	code = SIGN_EXTEND;
+      temp = simplify_unary_operation (code, to_mode, x, from_mode);
+      if (temp)
+	return temp;
+      break;
 
     case SUBREG:
       if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
@@ -389,17 +401,17 @@ convert_memory_address (to_mode, x)
 
     case PLUS:
     case MULT:
-      /* For addition the second operand is a small constant, we can safely
-	 permute the conversion and addition operation.  We can always safely
-	 permute them if we are making the address narrower.  In addition,
-	 always permute the operations if this is a constant.  */
-      if ((GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
-	      || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
-		  && (INTVAL (XEXP (x, 1)) + 20000 < 40000
-		      || CONSTANT_P (XEXP (x, 0))))))
+      /* For addition we can safely permute the conversion and addition
+	 operation if one operand is a constant and converting the constant
+	 does not change it.  We can always safely permute them if we are
+	 making the address narrower.  */
+      if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
+	  || (GET_CODE (x) == PLUS
+	      && GET_CODE (XEXP (x, 1)) == CONST_INT
+	      && XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))))
 	return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
 			       convert_memory_address (to_mode, XEXP (x, 0)),
-			       convert_memory_address (to_mode, XEXP (x, 1)));
+			       XEXP (x, 1));
       break;
 
     default:
-- 
GitLab