[Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input

segher at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Nov 5 20:34:40 GMT 2020


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

--- Comment #28 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #25)
> Even if we wanted to do something about it (which I disagree with, e.g.
> given that the implementation matches the documentation), you run into the
> problem that even GIMPLE nor RTL differentiates between:
> void
> foo (void)
> {
>   register int a __asm ("eax") = 1;
>   __asm ("# %0 " : : "c" (a+0));
>   __asm ("# %0 " : : "c" (a));
> }
> And "c" (a+0) unquestionably must be valid, it is just an expression that
> happens to be equal to a value of local register variable.

The documentation says

"""
The only supported use for this feature is to specify registers
for input and output operands when calling Extended @code{asm}-
(@pxref{Extended Asm}).  This may be necessary if the constraints for a-
particular machine don't provide sufficient control to select the desired-
register.  To force an operand into a register, create a local variable-
and specify the register name after the variable's declaration.  Then use-
the local variable for the @code{asm} operand and specify any constraint-
letter that matches the register:

@smallexample
register int *p1 asm ("r0") = @dots{};
register int *p2 asm ("r1") = @dots{};
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));
@end smallexample
"""

Note the "use the local variable *for* the asm operand".  Not *in* the asm
operand.  We really do care about the identity here (for all asm operands),
not the value contained in the operand.

So (a+0) is not valid.  It is of course likely this will be optimised to
just (a) and might even work, but that is not guaranteed.

(The documentation here could be much improved, of course.)


More information about the Gcc-bugs mailing list