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/config/xtensa/xtensa.cc | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 254661c9e28..f4b1151d2e0 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;
--
2.39.5