From: Takayuki 'January June' Suwa <[email protected]>

When the target-specific implementation for the "-fzero-call-used-regs"
option was introduced in a previous commit (00e551bf "xtensa: Implement 
TARGET_ZERO_CALL_USED_REGS"),
it was assumed that at least one address (general-purpose) register would
always be cleared to zero, and that register was then used to wipe out
other non-GP registers.  However, it turns out that this approach fails
in very simple cases:

     /* example (-fzero-call-used-regs=used ; TARGET_HARD_FLOAT) */
     void test(void) {
       asm volatile("":::"f0");
     }

This patch resolves the issue by modifying the implementation so that,
if no address registers are cleared, the A9 register (already adopted
for various adjustments in the prologue/epilogue) is zeroed out instead
and used to clear other non-GP registers.

gcc/ChangeLog:

        * config/xtensa/xtensa.cc (xtensa_zero_call_used_regs):
        Change to assign 0 to the A9 register and then use it to clear
        other non-GP registers, instead of triggering a gcc_assert()
        failure when the address register is not zeroed out at all.

gcc/testsuite:
        * gcc.target/xtensa/zero-scratch-regs-1.c: New test.
---
Changes v1->v2:
- add test

 gcc/config/xtensa/xtensa.cc                   | 28 ++++++++-----------
 .../gcc.target/xtensa/zero-scratch-regs-1.c   | 20 +++++++++++++
 2 files changed, 31 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/xtensa/zero-scratch-regs-1.c

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 254661c9e28e..f4b1151d2e0e 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -5601,9 +5601,11 @@ xtensa_zero_call_used_regs (HARD_REG_SET selected_regs)
            zeroed_regno = regno;
          continue;
        }
+      if (zeroed_regno < 0)
+       emit_move_insn (gen_rtx_REG (SImode, zeroed_regno = A9_REG),
+                       const0_rtx);
       if (TARGET_BOOLEANS && BR_REG_P (regno))
        {
-         gcc_assert (zeroed_regno >= 0);
          argvec = rtvec_alloc (1);
          RTVEC_ELT (argvec, 0) = gen_rtx_REG (SImode, zeroed_regno);
          convec = rtvec_alloc (1);
@@ -5612,23 +5614,15 @@ xtensa_zero_call_used_regs (HARD_REG_SET selected_regs)
                                           "", 0, argvec, convec,
                                           rtvec_alloc (0),
                                           UNKNOWN_LOCATION));
-         continue;
-       }
-      if (TARGET_HARD_FLOAT && FP_REG_P (regno))
-       {
-         gcc_assert (zeroed_regno >= 0);
-         emit_move_insn (gen_rtx_REG (SFmode, regno),
-                         gen_rtx_REG (SFmode, zeroed_regno));
-         continue;
        }
-      if (TARGET_MAC16 && ACC_REG_P (regno))
-       {
-         gcc_assert (zeroed_regno >= 0);
-         emit_move_insn (gen_rtx_REG (SImode, regno),
-                         gen_rtx_REG (SImode, zeroed_regno));
-         continue;
-       }
-      CLEAR_HARD_REG_BIT (selected_regs, regno);
+      else if (TARGET_HARD_FLOAT && FP_REG_P (regno))
+       emit_move_insn (gen_rtx_REG (SFmode, regno),
+                       gen_rtx_REG (SFmode, zeroed_regno));
+      else if (TARGET_MAC16 && ACC_REG_P (regno))
+       emit_move_insn (gen_rtx_REG (SImode, regno),
+                       gen_rtx_REG (SImode, zeroed_regno));
+      else
+       CLEAR_HARD_REG_BIT (selected_regs, regno);
     }
 
   return selected_regs;
diff --git a/gcc/testsuite/gcc.target/xtensa/zero-scratch-regs-1.c 
b/gcc/testsuite/gcc.target/xtensa/zero-scratch-regs-1.c
new file mode 100644
index 000000000000..6cef35d667db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/zero-scratch-regs-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fzero-call-used-regs=used" } */
+
+void test_f0(void) {
+#if __XCHAL_HAVE_FP
+       asm volatile("":::"f0");
+#endif
+}
+
+void test_b0(void) {
+#if __XCHAL_HAVE_BOOLEANS
+       asm volatile("":::"b0");
+#endif
+}
+
+void test_acc(void) {
+#if __XCHAL_HAVE_MAC16
+       asm volatile("":::"acc");
+#endif
+}
-- 
2.47.3

Reply via email to