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

--- Comment #7 from Simon Willcocks <simon.willcocks at gmx dot de> ---
(In reply to Jakub Jelinek from comment #6)
> Moving the line is the right fix
Thanks for the confirmation.

> It is recommended to initialize normal automatic variables first and then
> only initialize register vars to those automatic variables right before the
> inline asm, with no other code in between.

In retrospect, I see that that is what this paragraph in
https://gcc.gnu.org/onlinedocs/gcc-10.3.0/gcc/Local-Register-Variables.html is
trying to say:

"Warning: In the above example, be aware that a register (for example r0) can
be call-clobbered by subsequent code, including function calls and library
calls for arithmetic operators on other variables (for example the
initialization of p2). In this case, use temporary variables for expressions
between the register assignments:"

For a coder to identify if they've encountered "this case" is very difficult
(at least, it took me several days), I think perhaps a hard-and-fast rule would
be more helpful? (With a change to the example to match.)

"Warning: any expression used to initialise a local register variable more
complex than a simple assignment from a local variable may involve a
compiler-generated function call that could invalidate previously initialised
register variables. Therefore, it is recommended that programs only initialize
register variables to the values of previously initialised automatic variables
just before the inline asm, with no other code in between."

    int *p1value = …;
    int *p2value = …;
    register int *p1 asm ("r0") = p1value;
    register int *p2 asm ("r1") = p2value;
    register int *result asm ("r0");
    asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));

(I would still like to see a warning like "local register variable may not be
used as expected", but there can't be all that many people using this feature.)

Reply via email to