[avr] PR64242: Fix failing nonlocal goto

Message ID ad67d911-5133-418f-b643-09fb4b78334a@gjlay.de
State New
Headers
Series [avr] PR64242: Fix failing nonlocal goto |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Georg-Johann Lay Dec. 4, 2024, 8:07 p.m. UTC
  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.

The only change to test results is that gcc.c-torture/execute/pr64242.c
is passing now.

Ok to apply?

Johann


--

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() restores 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().
  

Comments

Denis Chertykov Dec. 5, 2024, 9:35 a.m. UTC | #1
чт, 5 дек. 2024 г. в 00:07, Georg-Johann Lay <avr@gjlay.de>:
>
> 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.
>
> The only change to test results is that gcc.c-torture/execute/pr64242.c
> is passing now.
>
> Ok to apply?

Ok.

Denis
  

Patch

    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().

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 0c98318c03d..ea9f81d1bfb 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -411,9 +411,14 @@  (define_expand "nonlocal_goto"
 
     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);