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

commit r17-4272-gc66387c4b201e2576cbd06909e861ada1884685f
Author: Takayuki 'January June' Suwa <[email protected]>
Date:   Sun Sep 13 05:11:58 2026 +0900

    xtensa: Simplify xtensa_valid_move()
    
    The xtensa_valid_move() function, which is called from locations such as the
    condition clause of the "movsi_internal" MD insn pattern, was introduced in
    commit 71cc6aea
    (about 24 years ago) to prevent a non-register source from being directly
    assigned to the stack pointer when the "Windowed Register ABI" is configured
    (in such cases, the MOVSP instruction must be used via a scratch register).
    
    This is likely a workaround for the fact that Reload pass at the time was
    too lenient (or loose) with respect to the operand constraints of the insn
    pattern, and perhaps register allocation was performed under the assumption
    that non-register sources could be assigned to hard registers belonging to
    GENERAL_REGS (including the stack pointer in Xtensa).
    
    However, LRA has now replaced old Reload for the Xtensa target; since both
    instruction alternative selection and hard register allocation are performed
    in strict adherence to operand constraints, it is no longer necessary to
    employ workarounds like the one mentioned above.
    
    In this case, for example, since there is no alternative that simultaneously
    satisfies the constraints for the non-register source (such as a memory
    reference) and the stack pointer destination, LRA correctly recognizes and
    reloads the source into another scratch address (general-purpose) register.
    
    Therefore, this patch removes the workaround code mentioned above in
    xtensa_valid_move().
    
    gcc/ChangeLog:
    
            * config/xtensa/xtensa.cc (xtensa_valid_move):
            Remove code that rejects non-register sources when the destination
            is the stack pointer.
    
    gcc/testsuite:
    
            * gcc.target/xtensa/MOVSP.c: New test.

Diff:
---
 gcc/config/xtensa/xtensa.cc             | 24 +++++++-----------------
 gcc/testsuite/gcc.target/xtensa/MOVSP.c | 12 ++++++++++++
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 5ff0f25cc279..6b5d8d1099a9 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -581,27 +581,17 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
 
   if (register_operand (operands[0], mode))
     {
-      int dst_regnum = xt_true_regnum (operands[0]);
-
       if (xtensa_tls_referenced_p (operands[1]))
        return FALSE;
 
-      /* The stack pointer can only be assigned with a MOVSP opcode.  */
-      if (dst_regnum == STACK_POINTER_REGNUM)
-       return !TARGET_WINDOWED_ABI
-         || (mode == SImode
-             && register_operand (operands[1], mode)
-             && !ACC_REG_P (xt_true_regnum (operands[1])));
-
-      if (!ACC_REG_P (dst_regnum))
-       return true;
-    }
-  if (register_operand (operands[1], mode))
-    {
-      int src_regnum = xt_true_regnum (operands[1]);
-      if (!ACC_REG_P (src_regnum))
-       return true;
+      if (!ACC_REG_P (xt_true_regnum (operands[0])))
+       return TRUE;
     }
+
+  if (register_operand (operands[1], mode)
+      && !ACC_REG_P (xt_true_regnum (operands[1])))
+    return TRUE;
+
   return FALSE;
 }
 
diff --git a/gcc/testsuite/gcc.target/xtensa/MOVSP.c 
b/gcc/testsuite/gcc.target/xtensa/MOVSP.c
new file mode 100644
index 000000000000..d83f39bf04f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/MOVSP.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -mabi=windowed" } */
+
+void test(int *p)
+{
+  register int sp asm("sp") = 0;
+  asm volatile ("# %0"::""(sp));
+  sp = *p;
+  asm volatile ("# %0"::""(sp));
+}
+
+/* { dg-final { scan-assembler-times "movsp" 2 } } */

Reply via email to