diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-11 21:52:49 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-11 21:52:49 +0000 |
commit | 0207fa9006aa57843f99eb17abb0a04c4cc42b8f (patch) | |
tree | e46e95eb2fb00a9a4043e23fc4ae9d095ad324b4 /gcc/emit-rtl.c | |
parent | 92eba4000df906bae1d3be6d9c2047d6b3f8cac2 (diff) | |
download | gcc-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.c | 20 |
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); } |