After recent patches there were too many regressions of LRA on GCC
testsuite on x86 and x86-64.
The following patch fixes all of them.
It was successfully bootstrapped on x86/x86-64.
Committed as rev. 192637.
2012-10-20 Vladimir Makarov <vmaka...@redhat.com>
* lra.c (check_rtx): Don't check UNSPEC address. Fix typo with
comparing RTX_AUTOINC.
* lra-constraints.c (extract_local_address): Swap operands if
necessary. Assign to disp before extract_local_address call. Fix
typo with PLUS comparison. Use CONSTANT_P.
(simplify_operand_subreg): Put constant into memory for subreg
with mixed modes.
(process_alt_operands): Uncomment code for checking DEAD not for
early clobber.
* config/i386/i386.c (ix86_spill_class): Don't spill to SSE
regs when TARGET_MMX.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 192634)
+++ config/i386/i386.c (working copy)
@@ -40819,7 +40819,7 @@ ix86_autovectorize_vector_sizes (void)
static reg_class_t
ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
{
- if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL
+ if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX
&& hard_reg_set_subset_p (reg_class_contents[rclass],
reg_class_contents[GENERAL_REGS])
&& (mode == SImode || (TARGET_64BIT && mode == DImode)))
Index: lra-constraints.c
===================================================================
--- lra-constraints.c (revision 192634)
+++ lra-constraints.c (working copy)
@@ -524,6 +524,7 @@ extract_loc_address_regs (bool top_p, en
{
rtx *arg0_loc = &XEXP (x, 0);
rtx *arg1_loc = &XEXP (x, 1);
+ rtx *tloc;
rtx arg0 = *arg0_loc;
rtx arg1 = *arg1_loc;
enum rtx_code code0 = GET_CODE (arg0);
@@ -543,23 +544,34 @@ extract_loc_address_regs (bool top_p, en
code1 = GET_CODE (arg1);
}
+ if (CONSTANT_P (arg0)
+ || code1 == PLUS || code1 == MULT || code1 == ASHIFT)
+ {
+ tloc = arg1_loc;
+ arg1_loc = arg0_loc;
+ arg0_loc = tloc;
+ arg0 = *arg0_loc;
+ code0 = GET_CODE (arg0);
+ arg1 = *arg1_loc;
+ code1 = GET_CODE (arg1);
+ }
/* If this machine only allows one register per address, it
must be in the first operand. */
if (MAX_REGS_PER_ADDRESS == 1 || code == LO_SUM)
{
- extract_loc_address_regs (false, mode, as, arg0_loc, false, code,
- code1, modify_p, ad);
lra_assert (ad->disp_loc == NULL);
ad->disp_loc = arg1_loc;
+ extract_loc_address_regs (false, mode, as, arg0_loc, false, code,
+ code1, modify_p, ad);
}
/* Base + disp addressing */
- else if (code != PLUS && code0 != MULT && code0 != ASHIFT
+ else if (code0 != PLUS && code0 != MULT && code0 != ASHIFT
&& CONSTANT_P (arg1))
{
- extract_loc_address_regs (false, mode, as, arg0_loc, false, PLUS,
- code1, modify_p, ad);
lra_assert (ad->disp_loc == NULL);
ad->disp_loc = arg1_loc;
+ extract_loc_address_regs (false, mode, as, arg0_loc, false, PLUS,
+ code1, modify_p, ad);
}
/* If index and base registers are the same on this machine,
just record registers in any non-constant operands. We
@@ -575,14 +587,13 @@ extract_loc_address_regs (bool top_p, en
extract_loc_address_regs (false, mode, as, arg1_loc, true, PLUS,
code0, modify_p, ad);
}
- /* It might be index * scale + disp. */
- else if (code1 == CONST_INT || code1 == CONST_DOUBLE
- || code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
+ /* It might be [base + ]index * scale + disp. */
+ else if (CONSTANT_P (arg1))
{
lra_assert (ad->disp_loc == NULL);
ad->disp_loc = arg1_loc;
extract_loc_address_regs (false, mode, as, arg0_loc, context_p,
- PLUS, code1, modify_p, ad);
+ PLUS, code0, modify_p, ad);
}
/* If both operands are registers but one is already a hard
register of index or reg-base class, give the other the
@@ -624,11 +635,18 @@ extract_loc_address_regs (bool top_p, en
case MULT:
case ASHIFT:
- extract_loc_address_regs (false, mode, as, &XEXP (*loc, 0), true,
- outer_code, code, modify_p, ad);
- lra_assert (ad->index_loc == NULL);
- ad->index_loc = loc;
- break;
+ {
+ rtx *arg0_loc = &XEXP (x, 0);
+ enum rtx_code code0 = GET_CODE (*arg0_loc);
+
+ if (code0 == CONST_INT)
+ arg0_loc = &XEXP (x, 1);
+ extract_loc_address_regs (false, mode, as, arg0_loc, true,
+ outer_code, code, modify_p, ad);
+ lra_assert (ad->index_loc == NULL);
+ ad->index_loc = loc;
+ break;
+ }
case POST_MODIFY:
case PRE_MODIFY:
@@ -1408,6 +1426,17 @@ simplify_operand_subreg (int nop, enum m
alter_subreg (curr_id->operand_loc[nop], false);
return true;
}
+ /* Put constant into memory when we have mixed modes. It generates
+ a better code in most cases as it does not need a secondary
+ reload memory. It also prevents LRA looping when LRA is using
+ secondary reload memory again and again. */
+ if (CONSTANT_P (reg) && CONST_POOL_OK_P (reg_mode, reg)
+ && SCALAR_INT_MODE_P (reg_mode) != SCALAR_INT_MODE_P (mode))
+ {
+ SUBREG_REG (operand) = force_const_mem (reg_mode, reg);
+ alter_subreg (curr_id->operand_loc[nop], false);
+ return true;
+ }
/* Force a reload of the SUBREG_REG if this is a constant or PLUS or
if there may be a problem accessing OPERAND in the outer
mode. */
@@ -1415,7 +1444,7 @@ simplify_operand_subreg (int nop, enum m
&& REGNO (reg) >= FIRST_PSEUDO_REGISTER
&& (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
/* Don't reload paradoxical subregs because we could be looping
- having repeatedly final regno out of hard regs range. */
+ having repeatedly final regno out of hard regs range. */
&& (hard_regno_nregs[hard_regno][GET_MODE (reg)]
>= hard_regno_nregs[hard_regno][mode])
&& simplify_subreg_regno (hard_regno, GET_MODE (reg),
@@ -1757,10 +1786,10 @@ process_alt_operands (int only_alternati
clobber operand if the matching operand is
not dying in the insn. */
if (! curr_static_id->operand[m].early_clobber
- /*|| operand_reg[nop] == NULL_RTX
+ || operand_reg[nop] == NULL_RTX
|| (find_regno_note (curr_insn, REG_DEAD,
REGNO (operand_reg[nop]))
- != NULL_RTX)*/)
+ != NULL_RTX))
match_p = true;
}
if (match_p)
Index: lra.c
===================================================================
--- lra.c (revision 192634)
+++ lra.c (working copy)
@@ -2035,7 +2035,8 @@ check_rtl (bool final_p)
as legitimate. Although they are legitimate if
they satisfies the constraints and will be checked
by insn constraints which we ignore here. */
- && GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) == RTX_AUTOINC)
+ && GET_CODE (XEXP (op, 0)) != UNSPEC
+ && GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC)
fatal_insn_not_found (insn);
}
}