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