------- 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

Reply via email to