mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/50063 (DSE: wrong code for gcc.dg/torture/pta-ptrarith-3.c)
PR rtl-optimization/50063 * config/avr/avr.md (movhi_sp_r): Handle -1 (unknown IRQ state) and 2 (8-bit SP) in operand 2. * config/avr/avr.c (avr_prologue_setup_frame): Adjust prologue setup to use movhi_sp_r instead of vanilla move to write SP. Adjust REG_CFA notes to superseed unspec. (expand_epilogue): Adjust epilogue setup to use movhi_sp_r instead of vanilla move. As function body might contain CLI or SEI: Use irq_state 0 (IRQ known to be off) only with TARGET_NO_INTERRUPTS. Never use irq_state 1 (IRQ known to be on) here. From-SVN: r184461
This commit is contained in:
parent
8d071654dc
commit
0b262c28c6
|
|
@ -1,3 +1,17 @@
|
|||
2012-02-22 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR rtl-optimization/50063
|
||||
* config/avr/avr.md (movhi_sp_r): Handle -1 (unknown IRQ state)
|
||||
and 2 (8-bit SP) in operand 2.
|
||||
* config/avr/avr.c (avr_prologue_setup_frame): Adjust prologue
|
||||
setup to use movhi_sp_r instead of vanilla move to write SP.
|
||||
Adjust REG_CFA notes to superseed unspec.
|
||||
(expand_epilogue): Adjust epilogue setup to use movhi_sp_r instead
|
||||
of vanilla move.
|
||||
As function body might contain CLI or SEI: Use irq_state 0 (IRQ
|
||||
known to be off) only with TARGET_NO_INTERRUPTS. Never use
|
||||
irq_state 1 (IRQ known to be on) here.
|
||||
|
||||
2012-02-21 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* ira.c (check_allocation): Use REG_WORDS_BIG_ENDIAN, not
|
||||
|
|
|
|||
|
|
@ -1062,8 +1062,8 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
|||
!frame_pointer_needed can only occur if the function is not a
|
||||
leaf function and thus X has already been saved. */
|
||||
|
||||
int irq_state = -1;
|
||||
rtx fp_plus_insns, fp, my_fp;
|
||||
rtx sp_minus_size = plus_constant (stack_pointer_rtx, -size);
|
||||
|
||||
gcc_assert (frame_pointer_needed
|
||||
|| !isr_p
|
||||
|
|
@ -1076,7 +1076,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
|||
if (AVR_HAVE_8BIT_SP)
|
||||
{
|
||||
/* The high byte (r29) does not change:
|
||||
Prefer SUBI (1 cycle) over ABIW (2 cycles, same size). */
|
||||
Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
|
||||
|
||||
my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
|
||||
}
|
||||
|
|
@ -1092,43 +1092,50 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
|||
the frame pointer subtraction is done. */
|
||||
|
||||
insn = emit_move_insn (fp, stack_pointer_rtx);
|
||||
if (!frame_pointer_needed)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
insn = emit_move_insn (my_fp, plus_constant (my_fp, -size));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
||||
gen_rtx_SET (VOIDmode, fp, sp_minus_size));
|
||||
gen_rtx_SET (VOIDmode, fp, stack_pointer_rtx));
|
||||
}
|
||||
|
||||
insn = emit_move_insn (my_fp, plus_constant (my_fp, -size));
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
||||
gen_rtx_SET (VOIDmode, fp,
|
||||
plus_constant (fp, -size)));
|
||||
}
|
||||
|
||||
/* Copy to stack pointer. Note that since we've already
|
||||
changed the CFA to the frame pointer this operation
|
||||
need not be annotated if frame pointer is needed. */
|
||||
|
||||
if (AVR_HAVE_8BIT_SP || AVR_XMEGA)
|
||||
{
|
||||
insn = emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
else if (TARGET_NO_INTERRUPTS
|
||||
|| isr_p
|
||||
|| cfun->machine->is_OS_main)
|
||||
{
|
||||
rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
|
||||
|
||||
insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
|
||||
fp, irqs_are_on));
|
||||
}
|
||||
else
|
||||
{
|
||||
insn = emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
need not be annotated if frame pointer is needed.
|
||||
Always move through unspec, see PR50063.
|
||||
For meaning of irq_state see movhi_sp_r insn. */
|
||||
|
||||
if (cfun->machine->is_interrupt)
|
||||
irq_state = 1;
|
||||
|
||||
if (TARGET_NO_INTERRUPTS
|
||||
|| cfun->machine->is_signal
|
||||
|| cfun->machine->is_OS_main)
|
||||
irq_state = 0;
|
||||
|
||||
if (AVR_HAVE_8BIT_SP)
|
||||
irq_state = 2;
|
||||
|
||||
insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
|
||||
fp, GEN_INT (irq_state)));
|
||||
if (!frame_pointer_needed)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
{
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
||||
gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
||||
plus_constant (stack_pointer_rtx,
|
||||
-size)));
|
||||
}
|
||||
|
||||
fp_plus_insns = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
|
|
@ -1143,9 +1150,13 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
|||
|
||||
start_sequence ();
|
||||
|
||||
insn = emit_move_insn (stack_pointer_rtx, sp_minus_size);
|
||||
insn = emit_move_insn (stack_pointer_rtx,
|
||||
plus_constant (stack_pointer_rtx, -size));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
||||
gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
||||
plus_constant (stack_pointer_rtx,
|
||||
-size)));
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
insn = emit_move_insn (fp, stack_pointer_rtx);
|
||||
|
|
@ -1376,7 +1387,8 @@ expand_epilogue (bool sibcall_p)
|
|||
if (size)
|
||||
{
|
||||
/* Try two methods to adjust stack and select shortest. */
|
||||
|
||||
|
||||
int irq_state = -1;
|
||||
rtx fp, my_fp;
|
||||
rtx fp_plus_insns;
|
||||
|
||||
|
|
@ -1406,23 +1418,15 @@ expand_epilogue (bool sibcall_p)
|
|||
emit_move_insn (my_fp, plus_constant (my_fp, size));
|
||||
|
||||
/* Copy to stack pointer. */
|
||||
|
||||
if (AVR_HAVE_8BIT_SP || AVR_XMEGA)
|
||||
{
|
||||
emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
else if (TARGET_NO_INTERRUPTS
|
||||
|| isr_p
|
||||
|| cfun->machine->is_OS_main)
|
||||
{
|
||||
rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
|
||||
|
||||
emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp, irqs_are_on));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
|
||||
if (TARGET_NO_INTERRUPTS)
|
||||
irq_state = 0;
|
||||
|
||||
if (AVR_HAVE_8BIT_SP)
|
||||
irq_state = 2;
|
||||
|
||||
emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
|
||||
GEN_INT (irq_state)));
|
||||
|
||||
fp_plus_insns = get_insns ();
|
||||
end_sequence ();
|
||||
|
|
|
|||
|
|
@ -583,23 +583,26 @@
|
|||
|
||||
;; Move register $1 to the Stack Pointer register SP.
|
||||
;; This insn is emit during function prologue/epilogue generation.
|
||||
;; $2 = 0: We know that IRQs are off
|
||||
;; $2 = 1: We know that IRQs are on
|
||||
;; Remaining cases when the state of the I-Flag is unknown are
|
||||
;; handled by generic movhi insn.
|
||||
;; $2 = 0: We know that IRQs are off
|
||||
;; $2 = 1: We know that IRQs are on
|
||||
;; $2 = 2: SP has 8 bits only, IRQ state does not matter
|
||||
;; $2 = -1: We don't know anything about IRQ on/off
|
||||
;; Always write SP via unspec, see PR50063
|
||||
|
||||
(define_insn "movhi_sp_r"
|
||||
[(set (match_operand:HI 0 "stack_register_operand" "=q,q,q")
|
||||
(unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r")
|
||||
(match_operand:HI 2 "const_int_operand" "L,P,LP")]
|
||||
[(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
|
||||
(unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
|
||||
(match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
|
||||
UNSPECV_WRITE_SP))]
|
||||
"!AVR_HAVE_8BIT_SP"
|
||||
""
|
||||
"@
|
||||
out __SP_H__,%B1\;out __SP_L__,%A1
|
||||
cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1
|
||||
out __SP_L__,%A1\;out __SP_H__,%B1"
|
||||
[(set_attr "length" "2,4,2")
|
||||
(set_attr "isa" "no_xmega,no_xmega,xmega")
|
||||
out %B0,%B1\;out %A0,%A1
|
||||
cli\;out %B0,%B1\;sei\;out %A0,%A1
|
||||
in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
|
||||
out %A0,%A1
|
||||
out %A0,%A1\;out %B0,%B1"
|
||||
[(set_attr "length" "2,4,5,1,2")
|
||||
(set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
|
||||
(set_attr "cc" "none")])
|
||||
|
||||
(define_peephole2
|
||||
|
|
|
|||
Loading…
Reference in New Issue