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...@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...@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); > +} >