diff mbox

[x32] PATCH: PR target/47744: [x32] ICE: in reload_cse_simplify_operands, at postreload.c:403

Message ID 20110215133230.GA24954@intel.com
State New
Headers show

Commit Message

H.J. Lu Feb. 15, 2011, 1:32 p.m. UTC
Hi,

For x32 , IRA may generate

     (set (reg:SI 40 r11)
           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
		             (const_int 8))
		    (subreg:SI (plus:DI (reg/f:DI 7 sp)
					(const_int CONST1)) 0))
	   (const_int CONST2)))

This patch translates it into

     (set (reg:SI 40 r11)
           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
		             (const_int 8))
		    (reg/f:SI 7 sp))
	   (const_int [CONST1 + CONST2])))

Checked into x32 branch.

H.J.
---
From e1ceb6fc008e8139d20955d023fb20f347da8386 Mon Sep 17 00:00:00 2001
From: H.J. Lu <hjl.tools@gmail.com>
Date: Tue, 15 Feb 2011 05:20:06 -0800
Subject: [PATCH 2/2] Process (reg + const) base for TARGET_X32.

---
 gcc/ChangeLog.x32                      |    6 +++
 gcc/config/i386/i386.c                 |   57 ++++++++++++++++++++++++++++++++
 gcc/testsuite/ChangeLog.x32            |    5 +++
 gcc/testsuite/gcc.dg/torture/pr47744.c |   21 ++++++++++++
 4 files changed, 89 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr47744.c

Comments

Paolo Bonzini Feb. 15, 2011, 2:56 p.m. UTC | #1
On 02/15/2011 02:32 PM, H.J. Lu wrote:
> Hi,
>
> For x32 , IRA may generate
>
>       (set (reg:SI 40 r11)
>             (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
> 		             (const_int 8))
> 		    (subreg:SI (plus:DI (reg/f:DI 7 sp)
> 					(const_int CONST1)) 0))
> 	   (const_int CONST2)))
>
> This patch translates it into
>
>       (set (reg:SI 40 r11)
>             (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
> 		             (const_int 8))
> 		    (reg/f:SI 7 sp))
> 	   (const_int [CONST1 + CONST2])))
>
> Checked into x32 branch.
>
> H.J.
> ---
>  From e1ceb6fc008e8139d20955d023fb20f347da8386 Mon Sep 17 00:00:00 2001
> From: H.J. Lu<hjl.tools@gmail.com>
> Date: Tue, 15 Feb 2011 05:20:06 -0800
> Subject: [PATCH 2/2] Process (reg + const) base for TARGET_X32.
>
> ---
>   gcc/ChangeLog.x32                      |    6 +++
>   gcc/config/i386/i386.c                 |   57 ++++++++++++++++++++++++++++++++
>   gcc/testsuite/ChangeLog.x32            |    5 +++
>   gcc/testsuite/gcc.dg/torture/pr47744.c |   21 ++++++++++++
>   4 files changed, 89 insertions(+), 0 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.dg/torture/pr47744.c
>
> diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
> index b189b74..68e2bb8 100644
> --- a/gcc/ChangeLog.x32
> +++ b/gcc/ChangeLog.x32
> @@ -1,3 +1,9 @@
> +2011-02-15  H.J. Lu<hongjiu.lu@intel.com>
> +
> +	PR target/47744
> +	* config/i386/i386.c (ix86_decompose_address): Process
> +	(reg + const) base for TARGET_X32.
> +
>   2011-02-14  H.J. Lu<hongjiu.lu@intel.com>
>
>   	* config/i386/i386.c (ix86_output_addr_vec_elt): Output
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 98fa75d..2fc3053 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11735,6 +11735,63 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
>     if (disp == const0_rtx&&  (base || index))
>       disp = NULL_RTX;
>
> +  /* For TARGET_X32, IRA may generate
> +
> +     (set (reg:SI 40 r11)
> +           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
> +		             (const_int 8))
> +		    (subreg:SI (plus:DI (reg/f:DI 7 sp)
> +					(const_int CONST1)) 0))
> +	   (const_int CONST2)))
> +
> +     We translate it into
> +
> +     (set (reg:SI 40 r11)
> +           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
> +		             (const_int 8))
> +		    (reg/f:SI 7 sp))
> +	   (const_int [CONST1 + CONST2])))
> +    */
> +
> +  if (TARGET_X32
> +&&  base
> +&&  GET_MODE (base) == ptr_mode
> +&&  GET_CODE (base) == SUBREG
> +&&  (disp == NULL_RTX
> +	  || disp == const0_rtx
> +	  || CONST_INT_P (disp))
> +&&  GET_CODE (base_reg) == PLUS)
> +    {
> +      rtx op0 = XEXP (base_reg, 0);
> +      rtx op1 = XEXP (base_reg, 1);
> +      rtx addend;
> +      unsigned int base_regno;
> +
> +      if (REG_P (op0)&&  CONST_INT_P (op1))
> +	{
> +	  base_reg = op0;
> +	  addend  = op1;
> +	}
> +      else if (REG_P (op1)&&  CONST_INT_P (op0))
> +	{
> +	  base_reg = op1;
> +	  addend = op0;
> +	}
> +      else
> +	return 0;
> +
> +      base_regno = REGNO (base_reg);
> +      if (base_regno != SP_REG&&  base_regno != BP_REG)
> +	return 0;
> +
> +      if (disp == NULL_RTX || disp == const0_rtx)
> +	disp = addend;
> +      else
> +	disp = GEN_INT (INTVAL (disp) + INTVAL (addend));
> +
> +      base = gen_rtx_REG (ptr_mode, base_regno);
> +    }
> +
>     /* Allow arg pointer and stack pointer as index if there is not scaling.  */
>     if (base_reg&&  index_reg&&  scale == 1
>         &&  (index_reg == arg_pointer_rtx
> diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
> index 27543f8..6249b85 100644
> --- a/gcc/testsuite/ChangeLog.x32
> +++ b/gcc/testsuite/ChangeLog.x32
> @@ -1,3 +1,8 @@
> +2011-02-15  H.J. Lu<hongjiu.lu@intel.com>
> +
> +	PR target/47744
> +	* gcc.dg/torture/pr47744.c: New.
> +
>   2011-02-14  H.J. Lu<hongjiu.lu@intel.com>
>
>   	PR middle-end/47727
> diff --git a/gcc/testsuite/gcc.dg/torture/pr47744.c b/gcc/testsuite/gcc.dg/torture/pr47744.c
> new file mode 100644
> index 0000000..0f7efa9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr47744.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fpic" { target fpic } } */
> +
> +typedef int int32_t;
> +static const int init_jk[] = {2,3,4,6};
> + int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
> +{
> + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
> + double z,fw,f[20],fq[20],q[20];
> + jk = init_jk[prec];
> + jp = jk;
> + jx = nx-1;
> + for (i=0;i<=jk;i++) {
> +     for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
> + }
> + for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
> +     z = q[j-1]+fw;
> + }
> + n = (int32_t) z;
> + return n&7;
> +}

This is a general problem with simplify_subreg.  Unfortunately, fixing 
it would require auditing of all backends for (subreg:X (OP:Y ...)) 
patterns.

Paolo
Nathan Froyd Feb. 15, 2011, 3:52 p.m. UTC | #2
On Tue, Feb 15, 2011 at 03:56:16PM +0100, Paolo Bonzini wrote:
> On 02/15/2011 02:32 PM, H.J. Lu wrote:
>> For x32 , IRA may generate
>>
>>       (set (reg:SI 40 r11)
>>             (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
>> 		             (const_int 8))
>> 		    (subreg:SI (plus:DI (reg/f:DI 7 sp)
>> 					(const_int CONST1)) 0))
>> 	   (const_int CONST2)))
>>
>> This patch translates it into
>>
>>       (set (reg:SI 40 r11)
>>             (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
>> 		             (const_int 8))
>> 		    (reg/f:SI 7 sp))
>> 	   (const_int [CONST1 + CONST2])))
>>
>> Checked into x32 branch.
>
> This is a general problem with simplify_subreg.  Unfortunately, fixing  
> it would require auditing of all backends for (subreg:X (OP:Y ...))  
> patterns.

What would you need to do to fix it and what would you need to look for
during the audit?

-Nathan
diff mbox

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index b189b74..68e2bb8 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,9 @@ 
+2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/47744
+	* config/i386/i386.c (ix86_decompose_address): Process
+	(reg + const) base for TARGET_X32.
+
 2011-02-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/i386/i386.c (ix86_output_addr_vec_elt): Output
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 98fa75d..2fc3053 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11735,6 +11735,63 @@  ix86_decompose_address (rtx addr, struct ix86_address *out)
   if (disp == const0_rtx && (base || index))
     disp = NULL_RTX;
 
+  /* For TARGET_X32, IRA may generate
+
+     (set (reg:SI 40 r11)
+           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+		             (const_int 8))
+		    (subreg:SI (plus:DI (reg/f:DI 7 sp)
+					(const_int CONST1)) 0))
+	   (const_int CONST2)))
+
+     We translate it into
+
+     (set (reg:SI 40 r11)
+           (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+		             (const_int 8))
+		    (reg/f:SI 7 sp))
+	   (const_int [CONST1 + CONST2])))
+    */
+
+  if (TARGET_X32
+      && base
+      && GET_MODE (base) == ptr_mode
+      && GET_CODE (base) == SUBREG
+      && (disp == NULL_RTX
+	  || disp == const0_rtx
+	  || CONST_INT_P (disp))
+      && GET_CODE (base_reg) == PLUS)
+    {
+      rtx op0 = XEXP (base_reg, 0);
+      rtx op1 = XEXP (base_reg, 1);
+      rtx addend;
+      unsigned int base_regno;
+
+      if (REG_P (op0) && CONST_INT_P (op1))
+	{
+	  base_reg = op0;
+	  addend  = op1;
+	}
+      else if (REG_P (op1) && CONST_INT_P (op0))
+	{
+	  base_reg = op1;
+	  addend = op0;
+	}
+      else
+	return 0;
+
+      base_regno = REGNO (base_reg);
+      if (base_regno != SP_REG && base_regno != BP_REG)
+	return 0;
+
+      if (disp == NULL_RTX || disp == const0_rtx)
+	disp = addend;
+      else
+	disp = GEN_INT (INTVAL (disp) + INTVAL (addend));
+
+      base = gen_rtx_REG (ptr_mode, base_regno);
+    }
+
   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   if (base_reg && index_reg && scale == 1
       && (index_reg == arg_pointer_rtx
diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
index 27543f8..6249b85 100644
--- a/gcc/testsuite/ChangeLog.x32
+++ b/gcc/testsuite/ChangeLog.x32
@@ -1,3 +1,8 @@ 
+2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/47744
+	* gcc.dg/torture/pr47744.c: New.
+
 2011-02-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR middle-end/47727
diff --git a/gcc/testsuite/gcc.dg/torture/pr47744.c b/gcc/testsuite/gcc.dg/torture/pr47744.c
new file mode 100644
index 0000000..0f7efa9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr47744.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fpic" { target fpic } } */
+
+typedef int int32_t;
+static const int init_jk[] = {2,3,4,6};
+ int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ double z,fw,f[20],fq[20],q[20];
+ jk = init_jk[prec];
+ jp = jk;
+ jx = nx-1;
+ for (i=0;i<=jk;i++) {
+     for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+     z = q[j-1]+fw;
+ }
+ n = (int32_t) z;
+ return n&7;
+}