https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87600

--- Comment #3 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Here is an example for aarch64:

===
long f(long x)
{
        register long a asm("x0");
        asm("bla %0 %1" : "+&r"(a) : "r"(x));
        return a;
}
===

The first asm operand is a local register variable set to x0, so this one
should end up in x0.  But "x" is passed in x0 as function argument, and then
combined into the asm, making both asm operands hard register 0.  And then LRA
has the job of making things work (operand 0 is earlyclobber so not both args
can be hard reg 0), and LRA picks the wrong solution:

        bla x1 x0

Not letting combine combine the register moves that copy from the function
argument registers into pseudos fixes this.  But it costs 1%-5% of code size
on all targets (most are about 2%): most targets can usefully combine register
moves into other instructions, for example many targets have operations that
set a flags register as side effect.

I'm going to try to disallow combining the hard reg -> pseudo moves, because
that should help with the register alloc problems (it also gives better
register alloc!), but at the same time introducing an extra copy (from pseudo
to a new pseudo).  In theory this should be the best of both worlds.

Reply via email to