PATCH: Handle ZERO_EXTEND offsettable address
Paolo Bonzini
bonzini@gnu.org
Sat Nov 10 14:41:00 GMT 2012
Il 10/11/2012 07:44, H.J. Lu ha scritto:
> Hi,
>
> In
>
> (insn 19 17 20 2 (set (reg:TI 85 [ *_15 ])
> (mem:TI (zero_extend:DI (reg:SI 82)) [0 *_15+0 S16 A32])) x.i:29 61
> {*movti_internal_rex64}
> (expr_list:REG_DEAD (reg:SI 82)
> (expr_list:REG_EQUIV (mem/c:TI (plus:DI (reg/f:DI 20 frame)
> (const_int -16 [0xfffffffffffffff0])) [0 sym+0 S16 A64])
>
> we fail to see (mem:TI (zero_extend:DI (reg:SI 82))) is offsettable.
> This patch adds ZERO_EXTEND support to adjust_address_1 and
> offsettable_address_addr_space_p. Tested on Linux/x32. OK to install?
Is there any reason why SIGN_EXTEND should be handled differently?
(Just asking, I don't know this code well).
Paolo
> Thanks.
>
>
> H.J.
> ---
> gcc/
>
> 2012-11-10 H.J. Lu <hongjiu.lu@intel.com>
>
> PR rtl-optimization/55247
> PR middle-end/55259
> * emit-rtl.c (adjust_address_1): Handle ZERO_EXTEND.
> * recog.c (offsettable_address_addr_space_p): Likewise.
>
> gcc/testsuite/
>
> 2012-11-10 H.J. Lu <hongjiu.lu@intel.com>
>
> PR rtl-optimization/55247
> PR middle-end/55259
>
> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
> index 95bbfa7..d7c454c 100644
> --- a/gcc/emit-rtl.c
> +++ b/gcc/emit-rtl.c
> @@ -2109,6 +2109,12 @@ 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));
> + else if (GET_CODE (addr) == ZERO_EXTEND)
> + {
> + addr = XEXP (addr, 0);
> + addr = plus_constant (GET_MODE (addr), addr, offset);
> + addr = gen_rtx_ZERO_EXTEND (address_mode, addr);
> + }
> else
> addr = plus_constant (address_mode, addr, offset);
> }
> diff --git a/gcc/recog.c b/gcc/recog.c
> index ee68e30..d3dd591 100644
> --- a/gcc/recog.c
> +++ b/gcc/recog.c
> @@ -1934,15 +1934,21 @@ int
> offsettable_address_addr_space_p (int strictp, enum machine_mode mode, rtx y,
> addr_space_t as)
> {
> - enum rtx_code ycode = GET_CODE (y);
> + enum rtx_code ycode;
> rtx z;
> - rtx y1 = y;
> + rtx y1;
> rtx *y2;
> int (*addressp) (enum machine_mode, rtx, addr_space_t) =
> (strictp ? strict_memory_address_addr_space_p
> : memory_address_addr_space_p);
> unsigned int mode_sz = GET_MODE_SIZE (mode);
>
> + if (GET_CODE (y) == ZERO_EXTEND)
> + y = XEXP (y, 0);
> +
> + ycode = GET_CODE (y);
> + y1 = y;
> +
> if (CONSTANT_ADDRESS_P (y))
> return 1;
>
> diff --git a/gcc/testsuite/gcc.target/i386/pr55247.c b/gcc/testsuite/gcc.target/i386/pr55247.c
> new file mode 100644
> index 0000000..594139e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr55247.c
> @@ -0,0 +1,35 @@
> +/* { dg-do compile { target { ! { ia32 } } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-options "-O -mno-sse -mno-mmx -mx32 -maddress-mode=long" } */
> +
> +typedef unsigned int uint32_t;
> +typedef uint32_t Elf32_Word;
> +typedef uint32_t Elf32_Addr;
> +typedef struct {
> + Elf32_Word st_name;
> + Elf32_Addr st_value;
> + Elf32_Word st_size;
> + unsigned char st_other;
> +} Elf32_Sym;
> +typedef struct {
> + Elf32_Word r_info;
> +}
> +Elf32_Rela;
> +typedef struct {
> + union {
> + Elf32_Addr d_ptr;
> + }
> + d_un;
> +} Elf32_Dyn;
> +struct link_map {
> + Elf32_Dyn *l_info[34];
> +};
> +extern void symbind32 (Elf32_Sym *);
> +void
> +_dl_profile_fixup (struct link_map *l, Elf32_Word reloc_arg)
> +{
> + const Elf32_Sym *const symtab = (const void *) l->l_info[6]->d_un.d_ptr;
> + const Elf32_Rela *const reloc = (const void *) (l->l_info[23]->d_un.d_ptr + reloc_arg * sizeof (Elf32_Rela));
> + Elf32_Sym sym = symtab[(reloc->r_info) >> 8];
> + symbind32 (&sym);
> +}
>
More information about the Gcc-patches
mailing list