On Sat, Nov 10, 2012 at 6:41 AM, Paolo Bonzini <bonz...@gnu.org> wrote: > 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). >
I don't have a testcase to show that we will generate SIGN_EXTEND for offsettable address. I can add an assert of GET_CODE != SIGN_EXTEND. H.J. --- > >> 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); >> +} >> > -- H.J.