https://gcc.gnu.org/g:b6b9318ac9e72d6e3c9c400a98ce446846ed79d6

commit r17-2148-gb6b9318ac9e72d6e3c9c400a98ce446846ed79d6
Author: Oleg Endo <[email protected]>
Date:   Sun Jul 5 16:23:26 2026 +0900

    SH: Fix PR 67643
    
    gcc/ChangeLog:
            PR target/67643
            * config/sh/sh.cc (fpscr_set_from_mem): Specify a post-inc memory
            operand for lds_fpscr after RA.
    
    gcc/testsuite/ChangeLog:
            PR target/67643
            * gcc.target/sh/pr67643.c: New test.

Diff:
---
 gcc/config/sh/sh.cc                   | 24 ++++++++++++++++--------
 gcc/testsuite/gcc.target/sh/pr67643.c | 11 +++++++++++
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index 9e488bfe6abc..abc073c93354 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -8873,8 +8873,6 @@ fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
   enum attr_fp_mode norm_mode = ACTUAL_NORMAL_MODE (FP_MODE);
   int index = fp_mode == norm_mode;
 
-  rtx scratch = !can_create_pseudo_p () ? get_free_reg (regs_live) : NULL_RTX;
-
   if (fpscr_values == NULL)
     {
       tree t = build_index_type (integer_one_node);
@@ -8892,17 +8890,27 @@ fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
     }
 
   rtx src = DECL_RTL (fpscr_values);
-  if (!can_create_pseudo_p ())
+
+  if (can_create_pseudo_p ())
+    {
+      // Before RA the plain address can be used and RA will adjust it for
+      // the post-inc constraint.
+      src = adjust_address (src, SImode, index * 4);
+      emit_insn (gen_lds_fpscr (force_reg (SImode, src)));
+    }
+  else
     {
+      // After RA it needs the address with a post-inc mem or else it will
+      // result in an unrecognizable insn.
+      rtx scratch = get_free_reg ();
       emit_move_insn (scratch, XEXP (src, 0));
       if (index != 0)
        emit_insn (gen_addsi3 (scratch, scratch, GEN_INT (index * 4)));
-      src = adjust_automodify_address (src, SImode, scratch, index * 4);
+      src = adjust_automodify_address (src, SImode,
+                                      gen_rtx_POST_INC (Pmode, scratch),
+                                      index * 4);
+      add_reg_note (emit_insn (gen_lds_fpscr (src)), REG_INC, scratch);
     }
-  else
-    src = adjust_address (src, SImode, index * 4);
-
-  emit_insn (gen_lds_fpscr (src));
 }
 
 /* Is the given character a logical line separator for the assembler?  */
diff --git a/gcc/testsuite/gcc.target/sh/pr67643.c 
b/gcc/testsuite/gcc.target/sh/pr67643.c
new file mode 100644
index 000000000000..d2f04f89cf9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr67643.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-m4 -mfmovd -O1" } */
+/* { dg-final { scan-assembler "lds.l\t@r\[0-9\]+\\+,fpscr" } } */
+
+extern double g;
+
+void __attribute__ ((interrupt_handler))
+isr (void)
+{
+  g += 1.0;
+}

Reply via email to