Commit a12f68f4 by Doug Evans

reload1.c (eliminate_regs, case MINUS): Canonicalize (minus (plus reg const)…

reload1.c (eliminate_regs, case MINUS): Canonicalize (minus (plus reg const) reg) to (plus (minus reg reg) const).

	* reload1.c (eliminate_regs, case MINUS): Canonicalize
	(minus (plus reg const) reg) to (plus (minus reg reg) const).
	* reload.c (find_reloads_address): Treat (plus (minus reg reg) const)
	the same as (plus (plus reg reg) const).

From-SVN: r13539
parent e454beb7
...@@ -4368,7 +4368,9 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) ...@@ -4368,7 +4368,9 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
/* If we have an indexed stack slot, there are three possible reasons why /* If we have an indexed stack slot, there are three possible reasons why
it might be invalid: The index might need to be reloaded, the address it might be invalid: The index might need to be reloaded, the address
might have been made by frame pointer elimination and hence have a might have been made by frame pointer elimination and hence have a
constant out of range, or both reasons might apply. constant out of range, or the address is the result of register
elimination and (plus (plus reg reg) const), which has been
canonicalized from (plus (plus reg const) reg), isn't a valid address.
We can easily check for an index needing reload, but even if that is the We can easily check for an index needing reload, but even if that is the
case, we might also have an invalid constant. To avoid making the case, we might also have an invalid constant. To avoid making the
...@@ -4395,7 +4397,11 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) ...@@ -4395,7 +4397,11 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
innermost PLUS. */ innermost PLUS. */
else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
&& GET_CODE (XEXP (ad, 0)) == PLUS && (GET_CODE (XEXP (ad, 0)) == PLUS
/* MINUS can happen as a result of register elimination of
(minus eliminable reg) which gets canonicalized as
(plus (minus reg reg) const). */
|| GET_CODE (XEXP (ad, 0)) == MINUS)
&& (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
|| XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
...@@ -4406,7 +4412,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) ...@@ -4406,7 +4412,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
|| XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx) || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
&& ! memory_address_p (mode, ad)) && ! memory_address_p (mode, ad))
{ {
*loc = ad = gen_rtx (PLUS, GET_MODE (ad), *loc = ad = gen_rtx (GET_CODE (XEXP (ad, 0)), GET_MODE (ad),
plus_constant (XEXP (XEXP (ad, 0), 0), plus_constant (XEXP (XEXP (ad, 0), 0),
INTVAL (XEXP (ad, 1))), INTVAL (XEXP (ad, 1))),
XEXP (XEXP (ad, 0), 1)); XEXP (XEXP (ad, 0), 1));
......
...@@ -2853,7 +2853,7 @@ eliminate_regs (x, mem_mode, insn) ...@@ -2853,7 +2853,7 @@ eliminate_regs (x, mem_mode, insn)
context. context.
If we have (plus (eliminable) (reg)), we want to produce If we have (plus (eliminable) (reg)), we want to produce
(plus (plus (replacement) (reg) (const))). If this was part of a (plus (plus (replacement) (reg)) (const)). If this was part of a
normal add insn, (plus (replacement) (reg)) will be pushed as a normal add insn, (plus (replacement) (reg)) will be pushed as a
reload. This is the desired action. */ reload. This is the desired action. */
...@@ -2892,6 +2892,28 @@ eliminate_regs (x, mem_mode, insn) ...@@ -2892,6 +2892,28 @@ eliminate_regs (x, mem_mode, insn)
} }
return x; return x;
case MINUS:
/* If we have (minus (eliminable) (reg)), we want to produce
(plus (minus (replacement) (reg)) (const)). The main reason being
to be consistent with what is done for PLUS. find_reloads_address
assumes that we do this. */
{
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
{
if (GET_CODE (new0) == PLUS)
return gen_rtx (PLUS, GET_MODE (x),
gen_rtx (MINUS, GET_MODE (x),
XEXP (new0, 0), new1),
XEXP (new0, 1));
else
return gen_rtx (MINUS, GET_MODE (x), new0, new1);
}
}
return x;
case MULT: case MULT:
/* If this is the product of an eliminable register and a /* If this is the product of an eliminable register and a
constant, apply the distribute law and move the constant out constant, apply the distribute law and move the constant out
...@@ -2920,7 +2942,6 @@ eliminate_regs (x, mem_mode, insn) ...@@ -2920,7 +2942,6 @@ eliminate_regs (x, mem_mode, insn)
case CALL: case CALL:
case COMPARE: case COMPARE:
case MINUS:
case DIV: case UDIV: case DIV: case UDIV:
case MOD: case UMOD: case MOD: case UMOD:
case AND: case IOR: case XOR: case AND: case IOR: case XOR:
......
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