diff mbox

PATCH: Handle ZERO_EXTEND offsettable address

Message ID 20121110064405.GA22641@gmail.com
State New
Headers show

Commit Message

H.J. Lu Nov. 10, 2012, 6:44 a.m. UTC
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?

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

Comments

Paolo Bonzini Nov. 10, 2012, 2:41 p.m. UTC | #1
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);
> +}
>
H.J. Lu Nov. 10, 2012, 6:38 p.m. UTC | #2
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 mbox

Patch

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