2014-11-13 Yvan Roux <yvan.roux@linaro.org>
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Nov 2014 14:00:48 +0000 (14:00 +0000)
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Nov 2014 14:00:48 +0000 (14:00 +0000)
Backport from trunk r216229, r216230.
2014-10-14  Andrew Pinski  <apinski@cavium.com>

* explow.c (convert_memory_address_addr_space): Rename to ...
(convert_memory_address_addr_space_1): This.  Add in_const argument.
Inside a CONST RTL, permute the conversion and addition of constant
for zero and sign extended pointers.
(convert_memory_address_addr_space): New function.

2014-10-14  Andrew Pinski  <apinski@cavium.com>

Revert:
2011-08-19  H.J. Lu  <hongjiu.lu@intel.com>

        PR middle-end/49721
        * explow.c (convert_memory_address_addr_space): Also permute the
        conversion and addition of constant for zero-extend.

git-svn-id: svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@217497 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog.linaro
gcc/explow.c

index b438257..c7cd510 100644 (file)
@@ -1,3 +1,23 @@
+2014-11-13  Yvan Roux  <yvan.roux@linaro.org>
+
+       Backport from trunk r216229, r216230.
+       2014-10-14  Andrew Pinski  <apinski@cavium.com>
+
+       * explow.c (convert_memory_address_addr_space): Rename to ...
+       (convert_memory_address_addr_space_1): This.  Add in_const argument.
+       Inside a CONST RTL, permute the conversion and addition of constant
+       for zero and sign extended pointers.
+       (convert_memory_address_addr_space): New function.
+
+       2014-10-14  Andrew Pinski  <apinski@cavium.com>
+
+       Revert:
+       2011-08-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+        PR middle-end/49721
+        * explow.c (convert_memory_address_addr_space): Also permute the
+        conversion and addition of constant for zero-extend.
+
 2014-10-24  Yvan Roux  <yvan.roux@linaro.org>
 
        * LINARO-VERSION: Bump version.
index 48e91a6..d43b24a 100644 (file)
@@ -329,11 +329,13 @@ break_out_memory_refs (rtx x)
    an address in the address space's address mode, or vice versa (TO_MODE says
    which way).  We take advantage of the fact that pointers are not allowed to
    overflow by commuting arithmetic operations over conversions so that address
-   arithmetic insns can be used.  */
+   arithmetic insns can be used. IN_CONST is true if this conversion is inside
+   a CONST.  */
 
-rtx
-convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
-                                  rtx x, addr_space_t as ATTRIBUTE_UNUSED)
+static rtx
+convert_memory_address_addr_space_1 (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+                                    rtx x, addr_space_t as ATTRIBUTE_UNUSED,
+                                    bool in_const)
 {
 #ifndef POINTERS_EXTEND_UNSIGNED
   gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
@@ -389,32 +391,29 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
 
     case CONST:
       return gen_rtx_CONST (to_mode,
-                           convert_memory_address_addr_space
-                             (to_mode, XEXP (x, 0), as));
+                           convert_memory_address_addr_space_1
+                             (to_mode, XEXP (x, 0), as, true));
       break;
 
     case PLUS:
     case MULT:
-      /* FIXME: For addition, we used to permute the conversion and
-        addition operation only if one operand is a constant and
-        converting the constant does not change it or if one operand
-        is a constant and we are using a ptr_extend instruction
-        (POINTERS_EXTEND_UNSIGNED < 0) even if the resulting address
-        may overflow/underflow.  We relax the condition to include
-        zero-extend (POINTERS_EXTEND_UNSIGNED > 0) since the other
-        parts of the compiler depend on it.  See PR 49721.
-
+      /* 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 or if one operand is a constant and we are
+        using a ptr_extend instruction  (POINTERS_EXTEND_UNSIGNED < 0).
         We can always safely permute them if we are making the address
-        narrower.  */
+        narrower. Inside a CONST RTL, this is safe for both pointers
+        zero or sign extended as pointers cannot wrap. */
       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
          || (GET_CODE (x) == PLUS
              && CONST_INT_P (XEXP (x, 1))
-             && (POINTERS_EXTEND_UNSIGNED != 0
-                 || XEXP (x, 1) == convert_memory_address_addr_space
-                                       (to_mode, XEXP (x, 1), as))))
+             && ((in_const && POINTERS_EXTEND_UNSIGNED != 0)
+                 || XEXP (x, 1) == convert_memory_address_addr_space_1
+                                    (to_mode, XEXP (x, 1), as, in_const)
+                  || POINTERS_EXTEND_UNSIGNED < 0)))
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
-                              convert_memory_address_addr_space
-                                (to_mode, XEXP (x, 0), as),
+                              convert_memory_address_addr_space_1
+                                (to_mode, XEXP (x, 0), as, in_const),
                               XEXP (x, 1));
       break;
 
@@ -426,6 +425,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
                        x, POINTERS_EXTEND_UNSIGNED);
 #endif /* defined(POINTERS_EXTEND_UNSIGNED) */
 }
+
+/* Given X, a memory address in address space AS' pointer mode, convert it to
+   an address in the address space's address mode, or vice versa (TO_MODE says
+   which way).  We take advantage of the fact that pointers are not allowed to
+   overflow by commuting arithmetic operations over conversions so that address
+   arithmetic insns can be used.  */
+
+rtx
+convert_memory_address_addr_space (enum machine_mode to_mode, rtx x, addr_space_t as)
+{
+  return convert_memory_address_addr_space_1 (to_mode, x, as, false);
+}
 \f
 /* Return something equivalent to X but valid as a memory address for something
    of mode MODE in the named address space AS.  When X is not itself valid,