This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Invalid CALL_INSN_FUNCTION_USAGE for certain libcalls
- From: Bernd Schmidt <bernds_cb1 at t-online dot de>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 28 Feb 2007 01:41:40 +0100
- Subject: Invalid CALL_INSN_FUNCTION_USAGE for certain libcalls
The Blackfin stores arguments in registers R0, R1, R2, and subsequent
ones on the stack. A function with two DImode args (e.g. __divdi3)
takes its first arg in R0/R1, and the second is split between R2 and the
stack. Unfortunately, for a library call, we emit a (use (reg:DI R2))
in the CALL_INSN_FUNCTION_USAGE, which means that R3 is considered live
in places where it really is dead. That caused spill failures when the
new multiplication patterns I added recently are used.
Fixed with the patch below, which transfers a bit of code from
load_register_parameters to emit_library_call_value_1 to make it take
partial regs into account.
Bootstrapped & regression tested on i686-linux, tested for a while in
our local Blackfin tree. Committed as 122396.
Bernd
--
This footer brought to you by insane German lawmakers.
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough
Index: ChangeLog
===================================================================
--- ChangeLog (revision 122395)
+++ ChangeLog (working copy)
@@ -1,3 +1,8 @@
+2007-02-28 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * calls.c (emit_library_call_value_1): Handle partial registers
+ correctly when building up CALL_INSN_FUNCTION_USAGE.
+
2007-02-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa/predicates.md (move_src_operand): Allow zero for mode.
Index: calls.c
===================================================================
--- calls.c (revision 122395)
+++ calls.c (working copy)
@@ -3774,7 +3774,18 @@ emit_library_call_value_1 (int retval, r
if (reg != 0 && GET_CODE (reg) == PARALLEL)
use_group_regs (&call_fusage, reg);
else if (reg != 0)
- use_reg (&call_fusage, reg);
+ {
+ int partial = argvec[count].partial;
+ if (partial)
+ {
+ int nregs;
+ gcc_assert (partial % UNITS_PER_WORD == 0);
+ nregs = partial / UNITS_PER_WORD;
+ use_regs (&call_fusage, REGNO (reg), nregs);
+ }
+ else
+ use_reg (&call_fusage, reg);
+ }
}
/* Pass the function the address in which to return a structure value. */