aboutsummaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2012-11-11 21:52:49 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-11-11 21:52:49 +0000
commit0207fa9006aa57843f99eb17abb0a04c4cc42b8f (patch)
treee46e95eb2fb00a9a4043e23fc4ae9d095ad324b4 /gcc/emit-rtl.c
parent92eba4000df906bae1d3be6d9c2047d6b3f8cac2 (diff)
downloadgcc-0207fa9006aa57843f99eb17abb0a04c4cc42b8f.zip
gcc-0207fa9006aa57843f99eb17abb0a04c4cc42b8f.tar.gz
gcc-0207fa9006aa57843f99eb17abb0a04c4cc42b8f.tar.bz2
re PR rtl-optimization/55247 (internal compiler error: Max. number of generated reload insns per insn is achieved (90))
PR rtl-optimization/55247 PR middle-end/55259 * emit-rtl.c (adjust_address_1): If POINTERS_EXTEND_UNSIGNED > 0, handle ZERO_EXTEND. * recog.c (offsettable_address_addr_space_p): Likewise. From-SVN: r193415
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 95bbfa7..f39d861 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2071,10 +2071,12 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
rtx new_rtx;
enum machine_mode address_mode;
int pbits;
- struct mem_attrs attrs, *defattrs;
+ struct mem_attrs attrs = *get_mem_attrs (memref), *defattrs;
unsigned HOST_WIDE_INT max_align;
-
- attrs = *get_mem_attrs (memref);
+#ifdef POINTERS_EXTEND_UNSIGNED
+ enum machine_mode pointer_mode
+ = targetm.addr_space.pointer_mode (attrs.addrspace);
+#endif
/* If there are no changes, just return the original memory reference. */
if (mode == GET_MODE (memref) && !offset
@@ -2109,6 +2111,18 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
addr = gen_rtx_LO_SUM (address_mode, XEXP (addr, 0),
plus_constant (address_mode,
XEXP (addr, 1), offset));
+#ifdef POINTERS_EXTEND_UNSIGNED
+ /* If MEMREF is a ZERO_EXTEND from pointer_mode and the offset is valid
+ in that mode, we merge it into the ZERO_EXTEND. We take advantage of
+ the fact that pointers are not allowed to overflow. */
+ else if (POINTERS_EXTEND_UNSIGNED > 0
+ && GET_CODE (addr) == ZERO_EXTEND
+ && GET_MODE (XEXP (addr, 0)) == pointer_mode
+ && trunc_int_for_mode (offset, pointer_mode) == offset)
+ addr = gen_rtx_ZERO_EXTEND (address_mode,
+ plus_constant (pointer_mode,
+ XEXP (addr, 0), offset));
+#endif
else
addr = plus_constant (address_mode, addr, offset);
}