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
+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.
2014-10-24 Yvan Roux <yvan.roux@linaro.org>
* LINARO-VERSION: Bump version.
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
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);
{
#ifndef POINTERS_EXTEND_UNSIGNED
gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
case CONST:
return gen_rtx_CONST (to_mode,
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:
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
We can always safely permute them if we are making the address
+ 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))
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,
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),
x, POINTERS_EXTEND_UNSIGNED);
#endif /* defined(POINTERS_EXTEND_UNSIGNED) */
}
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,
\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,