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.

Reply via email to