This is the mail archive of the
mailing list for the GCC project.
Re: gcc torture test pr52286.c
On Mon, 28 Aug 2017, Jeff Law wrote:
> I can't remember matching constraints ever working that way.
They do work exactly so. These uses are all correct, though they place
some random value into x:
int x, y, z;
y = z = init();
asm ("" : "=r" (x) : "r" (y+z));
asm ("" : "=r" (x) : "r" (z));
asm ("" : "=r" (x) : "r" (42));
(are we still agreeing on this? I'm having a problem understanding why
you think the above wouldn't work)
>From that follows that also these are correct:
asm ("" : "=r" (x) : "0" (y+z));
asm ("" : "=r" (x) : "0" (z));
asm ("" : "=r" (x) : "0" (42));
It follows from the above because "0" is exactly like "r" here, except
that the concrete register to use is the same as for the first operand.
> REgister allocation and reloading will first try to allocate the two
> objects to the same register and if that doesn't work it will emit
> copies to ensure they are the same register.
Not quite. Your use of "objects" muddles the issue. It doesn't allocate
two objects to the same register, it allocates the two _operands_ to the
same register. For output operands that's indeed an object (lvalue), for
input operands it's rvalues, not objects. It does indeed allocate both to
the same register, possibly using copies. If the rvalue happens to not be
already in a register it makes it so by loading it into a, well, register.
> But that doesn't work when one of the objects isn't a register.
> There's no allocno for the constant. It's just that, a constant.
Which is a perfectly fine rvalue. Input constraints never need lvalues
(or objects). Maybe you're confusing this all with one particularity that
_if_ the input rvalue stems from an object and that object happens to be
allocated to a hardreg (via an asm("regname") declaration) then this
hardreg will be used as input register? In that way some information
from lvalues also flows into input operands, but it's not generally the
case that they must be lvalues.
> > FWIW, the above is a "portable" way to get the value 0 into 'a' without
> > the compiler knowing.
> ?!? Mine is just as portable and should actually work :-)
Um, no? FWIW this was your example:
asm ("" : "=r" (a) : "n" (0));
So, we put 0 into an immedate operand before the asm. After the asm we
put some register into a. How do you suggest that the immediate asm
operand (which isn't mentioned in the asm template, in fact there are no
operations at all) would be placed into that output register? Answer:
it isn't, the above places a random value into 'a'.