------- Additional Comments From matz at suse dot de 2005-04-12 19:05 -------
The problem is in reload.c:find_dummy_reload. It tries to use the input reg
as reload register for an in-out reload and has certain conditions when it
can't do so:
/* Consider using IN if OUT was not acceptable
or if OUT dies in this insn (like the quotient in a divmod insn).
We can't use IN unless it is dies in this insn,
which means we must know accurately which hard regs are live.
Also, the result can't go in IN if IN is used within OUT,
or if OUT is an earlyclobber and IN appears elsewhere in the insn. */
if (hard_regs_live_known
&& REG_P (in)
&& REGNO (in) < FIRST_PSEUDO_REGISTER
&& (value == 0
|| find_reg_note (this_insn, REG_UNUSED, real_out))
&& find_reg_note (this_insn, REG_DEAD, real_in)
&& !fixed_regs[REGNO (in)]
&& HARD_REGNO_MODE_OK (REGNO (in),
But this doesn't check if IN is used uninitialized. In that case it also
can't be used. It's not immediately clear to me how to check for this,
as nowhere is it noted that this or that pseudo is actually uninitialized
and only therefore got a register by global.c. One could look at the
global_live_at_start of the first block, if it mentions the original pseudo
number of the IN operand.
The problem of course being that at this point the hardregs already are
substituted into the REG expressions. So one would have to trust the
original regnos noted there. And it's not clear that this is the only
place in reload which is confused by hardregs corresponding to uninitialized
pseudos.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20973