Specifying the hard registers used by the 'return' pattern (such as the one
holding the return address) via the EPILOGUE_USES() macro has an effect
similar to the presence of global register variables; consequently, DF
information for these registers is attached to the entire function body
before register allocation even takes place.  This makes it extremely diffi-
cult to assign these registers to pseudos for other purposes within the
function body.

While this behavior is desirable when the machine instruction for returning
from a function requires exclusive use of those registers, it is undesirable
for the Xtensa ISA under the CALL0 ABI configuration, which permits the hard
register holding the return address to be repurposed for other uses.

This patch effectively reverts an earlier commit (384c6aef
"xtensa: Small changes to 'return' insn pattern") that had changed the speci-
fication of the A0 hard register (used for holding the return address) from
a USE RTX attached to the 'return' pattern to the EPILOGUE_USES() macro.

gcc/ChangeLog:

        * config/xtensa/xtensa.h (EPILOGUE_USES): Remove.
        * config/xtensa/xtensa.md (return):
        Resurrect '(use (reg:SI A0_REG))' to the template description.
        (sibcall_epilogue): Revive emitting '(use (reg:SI A0_REG))'.

gcc/testsuite/ChangeLog:

        * gcc.target/xtensa/regA0-allocatability.c: New test.
---
 gcc/config/xtensa/xtensa.h                            |  4 ----
 gcc/config/xtensa/xtensa.md                           |  4 +++-
 .../gcc.target/xtensa/regA0-allocatability.c          | 11 +++++++++++
 3 files changed, 14 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/xtensa/regA0-allocatability.c

diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 99243486a6a..5bf1645033c 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -539,10 +539,6 @@ typedef struct xtensa_args
 /* Stack pointer value doesn't matter at exit.  */
 #define EXIT_IGNORE_STACK 1
-/* The "return" pattern requires A0 register as return address, and is
-   also required so that restoring A0 in the epilogue is not dead code.  */
-#define EPILOGUE_USES(REGNO) ((REGNO) == A0_REG)
-
 /* Size in bytes of the trampoline, as an integer.  Make sure this is
    a multiple of TRAMPOLINE_ALIGNMENT to avoid -Wpadded warnings.  */
 #define TRAMPOLINE_SIZE (TARGET_WINDOWED_ABI ? \
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 753f23412be..9df4fbe9218 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2640,7 +2640,8 @@
    (set_attr "length"        "3")])
(define_insn "return"
-  [(return)]
+  [(return)
+   (use (reg:SI A0_REG))]
   "TARGET_WINDOWED_ABI
    || compute_frame_size (get_frame_size ()) == 0
    || epilogue_completed"
@@ -2707,6 +2708,7 @@
   "!TARGET_WINDOWED_ABI"
 {
   xtensa_expand_epilogue ();
+  emit_use (gen_rtx_REG (SImode, A0_REG));
   DONE;
 })
diff --git a/gcc/testsuite/gcc.target/xtensa/regA0-allocatability.c b/gcc/testsuite/gcc.target/xtensa/regA0-allocatability.c
new file mode 100644
index 00000000000..e712fc3b826
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/regA0-allocatability.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -mabi=call0 -fdump-rtl-reload" } */
+
+void test(void)
+{
+  asm volatile ("# clobber a2~a15, reg %0" : : "r"(0) :
+               "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9",
+               "a10", "a11", "a12", "a13", "a14", "a15");
+}
+
+/* { dg-final { scan-rtl-dump-not "Changing spilled pseudos to memory in insn #" 
"reload" } } */
--
2.39.5

Reply via email to