------- Comment #9 from matz at gcc dot gnu dot org 2007-05-21 07:45 ------- Richard, the problem isn't the compare or where to store the live values alen and blen (FYI, the store looks invalid, because reload will not immediately stop when it sees an invalid asm insn, but instead just patch it out, but it will leave the operands in a funny state, hence the compare insn looks incorrect).
The problem is the asm instruction itself, and it's actually the exact same bug as pr21291 , which was worked around by the outof-ssa change to coalesce both operand, which doesn't work anymore due to the change in forwprop. This could have happened also by some other random transformation, so forwprop isn't at fault. To recap, the problem goes like this: You start with int inout, orig; orig = inout; asm ("": "+mr" (inout)); use (orig); which is transformed very early to use explicit output and match operands (this in fact is the source of all evil, as far as reloads capabilities are concerned): asm ("": "=mr" (inout) : "0" (inout)); Now SSA form properly assigns a new SSA name for the output operand in the asm to inout, and some other transformation can now make use of the original SSA name of inout (in this case it's forwprop), so we have: asm ("": "=mr" (inout_2) : "0" (inout_1)); use (inout_1); Clearly inout_2 and inout_1 can't be coalesced easily anymore, as they represent two separate values, so they will get different pseudo registers during expansion. Pseudos are okay, as we indeed would accept registers at all in the constraint. But still from there everything goes downhill: Both operands need to match per the constraints, but use different pseudo registers, so they don't match. The only solution (for reload) is to register a reload for these operands. But reloads can only be satisfied by hardregs, not by memory, so we need a register for this reload, just because we are presented with non-matching operands. So, even though we allow memory for this operand, no memory can be used for it, because both operand parts don't match. That together with the other necessary registers will get us over the total limit of 6 available registers in the end. So it's a symptom of reload not being able to use memory for reloads (secondary reloads don't come into play here), a long standing problem. Alternatively it's also a symptom of both operands not coming into reload as matching (in which case the pseudo could go to memory just fine, as the alternative allows it, and no reload would be necessary). Extending reload to make use of memory for some reloads, where allowed, might be nice, but is unrealistic in its gory detail (even the secondary mem support doesn't really help here). So I think the only feasible fix or work-around is to present reload with matching operands, where required. Strictly it's required only if the alternative allows registers and memory and both operands are different pseudo regs, all other cases can be handled by reload equally well. That might still be done in tree form (what the old outof-ssa hack still tries but can't really work), or in RTL form shortly before reload. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32004