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.
---
gcc/config/xtensa/xtensa.cc | 24 +++++++-----------------
gcc/testsuite/gcc.target/xtensa/MOVSP.c | 12 ++++++++++++
2 files changed, 19 insertions(+), 17 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/xtensa/MOVSP.c
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index f2aa08cc2ed..d8652891101 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 00000000000..d83f39bf04f
--- /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 } } */
--
2.39.5