https://gcc.gnu.org/g:499d3dc84e40849f607154bd76ed07d37d744cc1

commit r12-10848-g499d3dc84e40849f607154bd76ed07d37d744cc1
Author: Georg-Johann Lay <a...@gjlay.de>
Date:   Wed Dec 4 20:56:50 2024 +0100

    AVR: target/64242 - Copy FP to a local reg in nonlocal_goto.
    
    In nonlocal_goto sets, change hard_frame_pointer_rtx only after
    emit_stack_restore() restored SP.  This is needed because SP
    my be stored in some frame location.
    
    gcc/
            PR target/64242
            * config/avr/avr.md (nonlocal_goto): Don't restore
            hard_frame_pointer_rtx directly, but copy it to local
            register, and only set hard_frame_pointer_rtx from it
            after emit_stack_restore().
    
    (cherry picked from commit f7b5527d1b48b33d8ab633c1e9dcb9883667492a)

Diff:
---
 gcc/config/avr/avr.md | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index f76249340b8f..90ba2d0400e4 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -381,9 +381,14 @@
 
     emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
 
-    emit_move_insn (hard_frame_pointer_rtx, r_fp);
+    // PR64242: When r_sp is located in the frame, we must not
+    // change FP prior to reading r_sp.  Hence copy r_fp to a
+    // local register (and hope that reload won't spill it).
+    rtx r_fp_reg = copy_to_reg (r_fp);
     emit_stack_restore (SAVE_NONLOCAL, r_sp);
 
+    emit_move_insn (hard_frame_pointer_rtx, r_fp_reg);
+
     emit_use (hard_frame_pointer_rtx);
     emit_use (stack_pointer_rtx);

Reply via email to