Commit a6af1bf9 by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/65805 (Chromium gets miscompiled)

2015-04-19  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/65805
	* lra-eliminations.c (lra_eliminate_regs_1): Add new assert.
	Don't use difference of offset and previous offset if
	update_sp_offset is non-zero.
	(eliminate_regs_in_insn): Ditto.
	* lra-spills.c (remove_pseudos): Exchange 4th and 6th args in
	lra_eliminate_regs_1 call.
	* lra-constraints.c (get_equiv_with_elimination): Ditto.

From-SVN: r222223
parent 037524d6
2015-04-19 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/65805
* lra-eliminations.c (lra_eliminate_regs_1): Add new assert.
Don't use difference of offset and previous offset if
update_sp_offset is non-zero.
(eliminate_regs_in_insn): Ditto.
* lra-spills.c (remove_pseudos): Exchange 4th and 6th args in
lra_eliminate_regs_1 call.
* lra-constraints.c (get_equiv_with_elimination): Ditto.
2015-04-18 Trevor Saunders <tsaunders@mozilla.com>
* hash-table.h: Remove version of hash_table that stored value_type *.
......
......@@ -533,7 +533,7 @@ get_equiv_with_elimination (rtx x, rtx_insn *insn)
if (x == res || CONSTANT_P (res))
return res;
return lra_eliminate_regs_1 (insn, res, GET_MODE (res),
0, false, false, true);
false, false, 0, true);
}
/* Set up curr_operand_mode. */
......
......@@ -318,7 +318,9 @@ get_elimination (rtx reg)
substitution if UPDATE_P, or the full offset if FULL_P, or
otherwise zero. If FULL_P, we also use the SP offsets for
elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating
offsets of register elimnable to SP.
offsets of register elimnable to SP. If UPDATE_SP_OFFSET is
non-zero, don't use difference of the offset and the previous
offset.
MEM_MODE is the mode of an enclosing MEM. We need this to know how
much to adjust a register for, e.g., PRE_DEC. Also, if we are
......@@ -341,7 +343,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
const char *fmt;
int copied = 0;
gcc_assert (!update_p || !full_p);
lra_assert (!update_p || !full_p);
lra_assert (update_sp_offset == 0 || (!subst_p && update_p && !full_p));
if (! current_function_decl)
return x;
......@@ -366,11 +369,14 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
{
rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (update_p)
return plus_constant (Pmode, to,
ep->offset - ep->previous_offset
+ (ep->to_rtx == stack_pointer_rtx
? update_sp_offset : 0));
if (update_sp_offset != 0)
{
if (ep->to_rtx == stack_pointer_rtx)
return plus_constant (Pmode, to, update_sp_offset);
return to;
}
else if (update_p)
return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
else if (full_p)
return plus_constant (Pmode, to,
ep->offset
......@@ -395,16 +401,15 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
if (! update_p && ! full_p)
return gen_rtx_PLUS (Pmode, to, XEXP (x, 1));
offset = (update_p
? ep->offset - ep->previous_offset
+ (ep->to_rtx == stack_pointer_rtx
? update_sp_offset : 0)
: ep->offset);
if (update_sp_offset != 0)
offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
else
offset = (update_p
? ep->offset - ep->previous_offset : ep->offset);
if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
offset -= lra_get_insn_recog_data (insn)->sp_offset;
if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) == -offset)
if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset)
return to;
else
return gen_rtx_PLUS (Pmode, to,
......@@ -451,12 +456,18 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
{
rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (update_p)
if (update_sp_offset != 0)
{
if (ep->to_rtx == stack_pointer_rtx)
return plus_constant (Pmode,
gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
update_sp_offset * INTVAL (XEXP (x, 1)));
return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
}
else if (update_p)
return plus_constant (Pmode,
gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
(ep->offset - ep->previous_offset
+ (ep->to_rtx == stack_pointer_rtx
? update_sp_offset : 0))
(ep->offset - ep->previous_offset)
* INTVAL (XEXP (x, 1)));
else if (full_p)
{
......@@ -889,11 +900,12 @@ remove_reg_equal_offset_note (rtx insn, rtx what)
If REPLACE_P is false, just update the offsets while keeping the
base register the same. If FIRST_P, use the sp offset for
elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this.
Attach the note about used elimination for insns setting frame
pointer to update elimination easy (without parsing already
generated elimination insns to find offset previously used) in
future. */
elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If
UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
and the previous offset. Attach the note about used elimination
for insns setting frame pointer to update elimination easy (without
parsing already generated elimination insns to find offset
previously used) in future. */
void
eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
......@@ -940,6 +952,10 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
rtx src = SET_SRC (old_set);
rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx);
/* We should never process such insn with non-zero
UPDATE_SP_OFFSET. */
lra_assert (update_sp_offset == 0);
if (off != NULL_RTX
|| src == ep->to_rtx
|| (GET_CODE (src) == PLUS
......@@ -1026,7 +1042,8 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
if (! replace_p)
{
offset += (ep->offset - ep->previous_offset);
if (update_sp_offset == 0)
offset += (ep->offset - ep->previous_offset);
if (ep->to_rtx == stack_pointer_rtx)
{
if (first_p)
......
......@@ -461,7 +461,7 @@ remove_pseudos (rtx *loc, rtx_insn *insn)
{
rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem,
GET_MODE (pseudo_slots[i].mem),
0, false, false, true);
false, false, 0, true);
*loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
}
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment