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> 2015-04-18 Trevor Saunders <tsaunders@mozilla.com>
* hash-table.h: Remove version of hash_table that stored value_type *. * 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) ...@@ -533,7 +533,7 @@ get_equiv_with_elimination (rtx x, rtx_insn *insn)
if (x == res || CONSTANT_P (res)) if (x == res || CONSTANT_P (res))
return res; return res;
return lra_eliminate_regs_1 (insn, res, GET_MODE (res), return lra_eliminate_regs_1 (insn, res, GET_MODE (res),
0, false, false, true); false, false, 0, true);
} }
/* Set up curr_operand_mode. */ /* Set up curr_operand_mode. */
......
...@@ -318,7 +318,9 @@ get_elimination (rtx reg) ...@@ -318,7 +318,9 @@ get_elimination (rtx reg)
substitution if UPDATE_P, or the full offset if FULL_P, or substitution if UPDATE_P, or the full offset if FULL_P, or
otherwise zero. If FULL_P, we also use the SP offsets for otherwise zero. If FULL_P, we also use the SP offsets for
elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating 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 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 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, ...@@ -341,7 +343,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
const char *fmt; const char *fmt;
int copied = 0; 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) if (! current_function_decl)
return x; return x;
...@@ -366,11 +369,14 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -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; rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (update_p) if (update_sp_offset != 0)
return plus_constant (Pmode, to, {
ep->offset - ep->previous_offset if (ep->to_rtx == stack_pointer_rtx)
+ (ep->to_rtx == stack_pointer_rtx return plus_constant (Pmode, to, update_sp_offset);
? update_sp_offset : 0)); return to;
}
else if (update_p)
return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
else if (full_p) else if (full_p)
return plus_constant (Pmode, to, return plus_constant (Pmode, to,
ep->offset ep->offset
...@@ -395,16 +401,15 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -395,16 +401,15 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
if (! update_p && ! full_p) if (! update_p && ! full_p)
return gen_rtx_PLUS (Pmode, to, XEXP (x, 1)); return gen_rtx_PLUS (Pmode, to, XEXP (x, 1));
offset = (update_p if (update_sp_offset != 0)
? ep->offset - ep->previous_offset offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
+ (ep->to_rtx == stack_pointer_rtx else
? update_sp_offset : 0) offset = (update_p
: ep->offset); ? ep->offset - ep->previous_offset : ep->offset);
if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
offset -= lra_get_insn_recog_data (insn)->sp_offset; offset -= lra_get_insn_recog_data (insn)->sp_offset;
if (CONST_INT_P (XEXP (x, 1)) if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset)
&& INTVAL (XEXP (x, 1)) == -offset)
return to; return to;
else else
return gen_rtx_PLUS (Pmode, to, return gen_rtx_PLUS (Pmode, to,
...@@ -451,12 +456,18 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -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; 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, return plus_constant (Pmode,
gen_rtx_MULT (Pmode, to, XEXP (x, 1)), gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
(ep->offset - ep->previous_offset (ep->offset - ep->previous_offset)
+ (ep->to_rtx == stack_pointer_rtx
? update_sp_offset : 0))
* INTVAL (XEXP (x, 1))); * INTVAL (XEXP (x, 1)));
else if (full_p) else if (full_p)
{ {
...@@ -889,11 +900,12 @@ remove_reg_equal_offset_note (rtx insn, rtx what) ...@@ -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 If REPLACE_P is false, just update the offsets while keeping the
base register the same. If FIRST_P, use the sp offset for base register the same. If FIRST_P, use the sp offset for
elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If
Attach the note about used elimination for insns setting frame UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
pointer to update elimination easy (without parsing already and the previous offset. Attach the note about used elimination
generated elimination insns to find offset previously used) in for insns setting frame pointer to update elimination easy (without
future. */ parsing already generated elimination insns to find offset
previously used) in future. */
void void
eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, 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, ...@@ -940,6 +952,10 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
rtx src = SET_SRC (old_set); rtx src = SET_SRC (old_set);
rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx); 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 if (off != NULL_RTX
|| src == ep->to_rtx || src == ep->to_rtx
|| (GET_CODE (src) == PLUS || (GET_CODE (src) == PLUS
...@@ -1026,7 +1042,8 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -1026,7 +1042,8 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
if (! replace_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 (ep->to_rtx == stack_pointer_rtx)
{ {
if (first_p) if (first_p)
......
...@@ -461,7 +461,7 @@ remove_pseudos (rtx *loc, rtx_insn *insn) ...@@ -461,7 +461,7 @@ remove_pseudos (rtx *loc, rtx_insn *insn)
{ {
rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem, rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem,
GET_MODE (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); *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
} }
return; 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