This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[dataflow or trunk?] PATCH: fix caller-save.c on sibcalls
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Kenneth Zadeck <zadeck at naturalbridge dot com>
- Date: Wed, 14 Feb 2007 09:06:08 +0100
- Subject: [dataflow or trunk?] PATCH: fix caller-save.c on sibcalls
Kenny sent me a testcase for which fwprop triggers an ICE on dataflow
branch. The ICE is in caller-save.c, so this is most likely a latent
bug in this file.
The problem is that the sibcall pattern on arm does not clobber the link
register; then, the link register happens to be live before and after
the sibcall and caller-save.c tries to spill it to the stack. This
crashes because the register isn't otherwise used in the function, and a
save area hasn't been reserved on the stack.
The attached mini patch seems to fix the problem, but I'm inexperienced
enough in reload and the related parts of GCC, that I'm not sure it's
just papering over the problem. It has been tested with an assembly
comparison of cc1 files on powerpc-apple-darwin on dataflow branch --
which gave no difference with or without the patch.
Does anybody think that this belongs to the trunk too, as the bug could
be latent there? I'll do a bootstrap on trunk too if it is approved for
there; in the meanwhile, the dataflow people may want to bootstrap the
branch with this patch on arm-elf, since the testcase showed the problem
on that platform.
Thanks,
Paolo
2007-02-14 Paolo Bonzini <bonzini@gnu.org>
* caller-save.c (save_call_clobbered_regs): Do not process sibcalls.
Index: caller-save.c
===================================================================
--- caller-save.c (revision 121891)
+++ caller-save.c (working copy)
@@ -408,7 +408,9 @@ save_call_clobbered_regs (void)
regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
}
- if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
+ if (code == CALL_INSN
+ && !SIBLING_CALL_P (insn)
+ && !find_reg_note (insn, REG_NORETURN, NULL))
{
unsigned regno;
HARD_REG_SET hard_regs_to_save;