Message ID | 20121110064405.GA22641@gmail.com |
---|---|
State | New |
Headers | show |
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); > +} >
On Sat, Nov 10, 2012 at 6:41 AM, Paolo Bonzini <bonzini@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.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); >> +} >> >
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); +}