This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [x32] PATCH: PR target/47744: [x32] ICE: in reload_cse_simplify_operands, at postreload.c:403
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 1 Mar 2011 11:25:39 -0800
- Subject: Re: [x32] PATCH: PR target/47744: [x32] ICE: in reload_cse_simplify_operands, at postreload.c:403
- References: <20110215133230.GA24954@intel.com> <20110218190601.GA920@intel.com>
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
On Fri, Feb 18, 2011 at 11:06:01AM -0800, H.J. Lu wrote:
> On Tue, Feb 15, 2011 at 05:32:30AM -0800, 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
>
>
> I checked in this patch to add ix86_simplify_base_disp and use it
> for TARGET_X32 after reload is completed.
>
I checked this patch into x32 branch to translate:
(set (reg:SI 40 r11)
(plus:SI (plus:SI (reg:SI 1 dx)
(subreg:SI (plus:DI (reg/f:DI 7 sp)
(const_int CONST1)) 0))
(const_int CONST2)))
into
(set (reg:SI 40 r11)
(plus:SI (plus:SI (reg:SI 1 dx)
(reg/f:SI 7 sp))
(const_int [CONST1 + CONST2])))
H.J.
----
diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index 191ed24..497866d 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,5 +1,12 @@
2011-03-01 H.J. Lu <hongjiu.lu@intel.com>
+ PR target/47744
+ * config/i386/i386.c (ix86_simplify_base_disp): Add PLUS base
+ support.
+ (ix86_decompose_address): Updated.
+
+2011-03-01 H.J. Lu <hongjiu.lu@intel.com>
+
PR target/47926
* config/i386/i386.c (ix86_trampoline_init): Use movl instead
of movabs for x32.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4f7433d..ad5bbc3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11620,10 +11620,26 @@ ix86_live_on_entry (bitmap regs)
(const_int 8))
(reg/f:SI 7 sp))
(const_int [CONST1 + CONST2])))
- */
+
+ If PLUS is true, we also translate
+
+ (set (reg:SI 40 r11)
+ (plus:SI (plus:SI (reg:SI 1 dx)
+ (subreg:SI (plus:DI (reg/f:DI 7 sp)
+ (const_int CONST1)) 0))
+ (const_int CONST2)))
+
+ into
+
+ (set (reg:SI 40 r11)
+ (plus:SI (plus:SI (reg:SI 1 dx)
+ (reg/f:SI 7 sp))
+ (const_int [CONST1 + CONST2])))
+
+ */
static void
-ix86_simplify_base_disp (rtx *base_p, rtx *disp_p)
+ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
{
rtx base = *base_p;
rtx disp;
@@ -11649,13 +11665,33 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p)
if (REG_P (op0) && CONST_INT_P (op1))
{
base = op0;
- addend = op1;
+ addend = op1;
}
else if (REG_P (op1) && CONST_INT_P (op0))
{
base = op1;
addend = op0;
}
+ else if (plus
+ && GET_CODE (op1) == SUBREG
+ && GET_MODE (op1) == ptr_mode)
+ {
+ op1 = SUBREG_REG (op1);
+ if (GET_CODE (op1) == PLUS)
+ {
+ addend = XEXP (op1, 1);
+ op1 = XEXP (op1, 0);
+ if (REG_P (op1) && CONST_INT_P (addend))
+ {
+ op1 = gen_rtx_REG (ptr_mode, REGNO (op1));
+ *base_p = gen_rtx_PLUS (ptr_mode, op0, op1);
+ }
+ else
+ return;
+ }
+ else
+ return;
+ }
else
return;
@@ -11664,7 +11700,8 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p)
else
*disp_p = GEN_INT (INTVAL (disp) + INTVAL (addend));
- *base_p = gen_rtx_REG (ptr_mode, REGNO (base));
+ if (!plus)
+ *base_p = gen_rtx_REG (ptr_mode, REGNO (base));
}
}
@@ -11706,15 +11743,20 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
addends[n++] = XEXP (op, 1);
op = XEXP (op, 0);
/* Support 32bit address in x32 mode. */
- if (TARGET_X32
- && reload_completed
- && GET_CODE (op) == ZERO_EXTEND
- && GET_MODE (op) == Pmode
- && GET_CODE (XEXP (op, 0)) == PLUS)
+ if (TARGET_X32 && reload_completed)
{
- op = XEXP (op, 0);
- if (n == 1)
- ix86_simplify_base_disp (&op, &addends[0]);
+ if (GET_CODE (op) == ZERO_EXTEND
+ && GET_MODE (op) == Pmode
+ && GET_CODE (XEXP (op, 0)) == PLUS)
+ {
+ op = XEXP (op, 0);
+ if (n == 1)
+ ix86_simplify_base_disp (&op, &addends[0], false);
+ }
+ else if (n == 1
+ && GET_CODE (op) == PLUS
+ && GET_MODE (op) == ptr_mode)
+ ix86_simplify_base_disp (&op, &addends[0], true);
}
}
while (GET_CODE (op) == PLUS);
@@ -11816,7 +11858,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
disp = NULL_RTX;
if (TARGET_X32 && reload_completed)
- ix86_simplify_base_disp (&base, &disp);
+ ix86_simplify_base_disp (&base, &disp, false);
base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
index 1e0dd89..c57f5ca 100644
--- a/gcc/testsuite/ChangeLog.x32
+++ b/gcc/testsuite/ChangeLog.x32
@@ -1,3 +1,8 @@
+2011-03-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/47744
+ * gcc.dg/torture/pr47744-3.c: New.
+
2011-02-19 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/47364
diff --git a/gcc/testsuite/gcc.dg/torture/pr47744-3.c b/gcc/testsuite/gcc.dg/torture/pr47744-3.c
new file mode 100644
index 0000000..5a5dd33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr47744-3.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+
+typedef union rtunion_def {
+ struct rtx_def *rtx;
+} rtunion;
+typedef struct rtx_def {
+ unsigned short code;
+ rtunion fld[1];
+} *rtx;
+extern rtx recog_operand[];
+extern rtx *recog_operand_loc[];
+extern int reload_n_operands;
+extern void find_dummy_reload (int, int);
+extern int asm_noperands (rtx);
+extern int n_occurrences (char **);
+char operands_match[10][10];
+void find_reloads (rtx insn, int n_alternatives, int commutative)
+{
+ register int i, j;
+ int noperands;
+ char *constraints[10];
+ int address_reloaded[10];
+ int this_alternative[10];
+ char this_alternative_win[10];
+ int this_alternative_matches[10];
+ int this_alternative_number;
+ rtx body = ((insn)->fld[3].rtx);
+ int operand_mode[10];
+ if (body->code == 1)
+ {
+ reload_n_operands = noperands = asm_noperands (body);
+ n_alternatives = n_occurrences (constraints);
+ }
+ for (this_alternative_number = 0;
+ this_alternative_number < n_alternatives;
+ this_alternative_number++)
+ for (i = 0;
+ i < noperands;
+ i++)
+ {
+ register char *p = constraints[i];
+ register int win = 0;
+ int badop = 1;
+ int c;
+ register rtx operand = recog_operand[i];
+ int force_reload = 0;
+ this_alternative_win[i] = 0;
+ this_alternative[i] = 1;
+ while (*p && (c = *p++) != ',')
+ switch (c)
+ {
+ case '4':
+ c -= '0';
+ this_alternative_matches[i] = c;
+ if ((c != commutative
+ || i != commutative + 1)
+ && operands_match[c][i])
+ win = this_alternative_win[c];
+ else
+ find_dummy_reload (operand_mode[i], this_alternative[c]);
+ if (! win || force_reload)
+ for (j = 0; j < i; j++)
+ if (this_alternative_matches[j]
+ == this_alternative_matches[i])
+ badop = 1;
+ break;
+ case '<':
+ if (operand->code == 2
+ && ! address_reloaded[i]
+ && operand->fld[0].rtx->code == 3)
+ win = 1;
+ }
+ }
+}