summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/function.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/gcc/function.c b/gcc/function.c
index ba1265b3ace..6dfc17cac1d 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2675,7 +2675,7 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
/* Handle special case of virtual register plus constant. */
if (CONSTANT_P (XEXP (x, 1)))
{
- rtx old;
+ rtx old, new_offset;
/* Check for (plus (plus VIRT foo) (const_int)) first. */
if (GET_CODE (XEXP (x, 0)) == PLUS)
@@ -2722,18 +2722,26 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
return 1;
}
- old = XEXP (x, 0);
- XEXP (x, 0) = new;
- new = plus_constant (XEXP (x, 1), offset);
+ new_offset = plus_constant (XEXP (x, 1), offset);
- /* If the new constant is zero, try to replace the sum with its
- first operand. */
- if (new == const0_rtx
- && validate_change (object, loc, XEXP (x, 0), 0))
+ /* If the new constant is zero, try to replace the sum with just
+ the register. */
+ if (new_offset == const0_rtx
+ && validate_change (object, loc, new, 0))
return 1;
- /* Next try to replace constant with new one. */
- if (!validate_change (object, &XEXP (x, 1), new, 0))
+ /* Next try to replace the register and new offset.
+ There are two changes to validate here and we can't assume that
+ in the case of old offset equals new just changing the register
+ will yield a valid insn. In the interests of a little efficiency,
+ however, we only call validate change once (we don't queue up the
+ changes and then call apply_change_group). */
+
+ old = XEXP (x, 0);
+ if (offset == 0
+ ? ! validate_change (object, &XEXP (x, 0), new, 0)
+ : (XEXP (x, 0) = new,
+ ! validate_change (object, &XEXP (x, 1), new_offset, 0)))
{
if (! extra_insns)
{
@@ -2744,15 +2752,16 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
/* Otherwise copy the new constant into a register and replace
constant with that register. */
temp = gen_reg_rtx (Pmode);
+ XEXP (x, 0) = new;
if (validate_change (object, &XEXP (x, 1), temp, 0))
- emit_insn_before (gen_move_insn (temp, new), object);
+ emit_insn_before (gen_move_insn (temp, new_offset), object);
else
{
/* If that didn't work, replace this expression with a
register containing the sum. */
- new = gen_rtx (PLUS, Pmode, XEXP (x, 0), new);
XEXP (x, 0) = old;
+ new = gen_rtx (PLUS, Pmode, new, new_offset);
start_sequence ();
temp = force_operand (new, NULL_RTX);
OpenPOWER on IntegriCloud