public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input
@ 2020-11-03 19:58 bp at alien8 dot de
  2020-11-03 20:10 ` [Bug inline-asm/97708] " pinskia at gcc dot gnu.org
                   ` (29 more replies)
  0 siblings, 30 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-03 19:58 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 97708
           Summary: Inline asm does not use the local register asm
                    specified with register ... asm() as input
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: inline-asm
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bp at alien8 dot de
  Target Milestone: ---

Building the below on x86-64 with gcc9, gcc10 and Segher built with gcc11
20201015:

---
int main(void)
{

        register float foo asm ("xmm0") = 0.99f;

        asm volatile("movl %0, %%r8d\n\t"
                      "vmcall\n\t"
                      :: "g" (foo));

        return 0;
}
---

results in gcc not using the xmm0 register directly as the input register to
the asm statement but does something funky:

0000000000001125 <main>:
    1125:       55                      push   %rbp
    1126:       48 89 e5                mov    %rsp,%rbp
    1129:       f3 0f 10 05 d3 0e 00    movss  0xed3(%rip),%xmm0        # 2004
<_IO_stdin_used+0x4>
    1130:       00 
    1131:       66 0f 7e c0             movd   %xmm0,%eax
    1135:       41 89 c0                mov    %eax,%r8d
    1138:       0f 01 c1                vmcall 

by loading through the %eax GPR and producing wrong code without even a
warning. I'm not saying this example is supposed to make sense but this should
fail instead by trying to compile:

$ cat xmm1.s
        movl %xmm0,%eax

$ x86_64-linux-as xmm1.s -o xmm1.o
xmm1.s: Assembler messages:
xmm1.s:1: Error: unsupported instruction `mov'

and fail the build because plain MOV cannot use an XMM reg as a source.

Thx.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
@ 2020-11-03 20:10 ` pinskia at gcc dot gnu.org
  2020-11-03 20:16 ` bp at alien8 dot de
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: pinskia at gcc dot gnu.org @ 2020-11-03 20:10 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
"g" constraint won't work here:
‘g’
Any register, memory or immediate integer operand is allowed, except for
registers that are not general registers.
---- CUT ---
Notice the last part: "registers that are not general register".
You need to use the "x" constraint here which is for sse register.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
  2020-11-03 20:10 ` [Bug inline-asm/97708] " pinskia at gcc dot gnu.org
@ 2020-11-03 20:16 ` bp at alien8 dot de
  2020-11-03 20:39 ` segher at gcc dot gnu.org
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-03 20:16 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Boris <bp at alien8 dot de> ---
(In reply to Andrew Pinski from comment #1)
> "g" constraint won't work here:

So in that case gcc should fail the build. Which it does not.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
  2020-11-03 20:10 ` [Bug inline-asm/97708] " pinskia at gcc dot gnu.org
  2020-11-03 20:16 ` bp at alien8 dot de
@ 2020-11-03 20:39 ` segher at gcc dot gnu.org
  2020-11-03 20:41 ` pinskia at gcc dot gnu.org
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-03 20:39 UTC (permalink / raw)
  To: gcc-bugs

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

Segher Boessenkool <segher at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |---
             Status|RESOLVED                    |REOPENED
   Last reconfirmed|                            |2020-11-03
     Ever confirmed|0                           |1

--- Comment #3 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Yes, exactly.  GCC silently does the wrong thing, contradicting its
documentation.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (2 preceding siblings ...)
  2020-11-03 20:39 ` segher at gcc dot gnu.org
@ 2020-11-03 20:41 ` pinskia at gcc dot gnu.org
  2020-11-03 20:55 ` segher at gcc dot gnu.org
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: pinskia at gcc dot gnu.org @ 2020-11-03 20:41 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |INVALID

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #3)
> Yes, exactly.  GCC silently does the wrong thing, contradicting its
> documentation.

Whihc part:
Then use the local variable for the asm operand and specify any constraint
letter that matches the register:
?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (3 preceding siblings ...)
  2020-11-03 20:41 ` pinskia at gcc dot gnu.org
@ 2020-11-03 20:55 ` segher at gcc dot gnu.org
  2020-11-03 21:01 ` jakub at gcc dot gnu.org
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-03 20:55 UTC (permalink / raw)
  To: gcc-bugs

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

Segher Boessenkool <segher at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |---
             Status|RESOLVED                    |REOPENED

--- Comment #5 from Segher Boessenkool <segher at gcc dot gnu.org> ---
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:


Stop marking this as invalid.  It is not.


"r" *is* valid.  And even if it was not, the compiler should just error,
not silently do the wrong thing!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (4 preceding siblings ...)
  2020-11-03 20:55 ` segher at gcc dot gnu.org
@ 2020-11-03 21:01 ` jakub at gcc dot gnu.org
  2020-11-03 21:15 ` bp at alien8 dot de
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-03 21:01 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I agree with Andrew here, the compiler does what it is asked to do, so puts the
value into either memory or general purpose register.  Neither "r" nor "g"
allows putting the value into an SSE register.  Use "x" constraint for that.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (5 preceding siblings ...)
  2020-11-03 21:01 ` jakub at gcc dot gnu.org
@ 2020-11-03 21:15 ` bp at alien8 dot de
  2020-11-03 22:09 ` jakub at gcc dot gnu.org
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-03 21:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Boris <bp at alien8 dot de> ---
(In reply to Jakub Jelinek from comment #6)
> I agree with Andrew here, the compiler does what it is asked to do, so puts
> the value into either memory or general purpose register.  Neither "r" nor
> "g" allows putting the value into an SSE register.  Use "x" constraint for
> that.

Look at the documentation:

"‘g’ Any register, memory or immediate integer operand is allowed, except for
registers that are not general registers."

so this reads to me like "g" doesn't allow xmm registers. What gcc does is go
"around the corner" and stick it in a g-allowed register.

So that behavior should *at* *least* be documented so that people know what's
going on here. Because it is confusing...

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (6 preceding siblings ...)
  2020-11-03 21:15 ` bp at alien8 dot de
@ 2020-11-03 22:09 ` jakub at gcc dot gnu.org
  2020-11-04  8:29 ` rguenth at gcc dot gnu.org
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-03 22:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That is how GCC deals with all reloading, so I don't understand what is
surprising about it.
If you ask for something to be in register (or register class) xyz and it isn't
there, it is copied there.
Look at e.g.:
void
foo (void)
{
  register int a __asm ("eax") = 1;
  __asm ("# %0 " : : "r" (a));
  __asm ("# %0 " : : "a" (a));
  __asm ("# %0 " : : "c" (a));
//  __asm ("# %0 " : : "m" (a));
}

In the first case, "r" constraint allows the "eax" register in which the
(local) register variable lives, so it goes there.  In the second case
likewise, it is the only register in which it can go.  In the third case, you
ask for it to be passed in the ecx register and so the compiler does that.  The
commented out case errors out because "m" essentially requires taking the
address of the passed object, which is not valid for register variables.  But
e.g. "g" which doesn't require just mem can handle also non-mems and will be in
that case essentially treated just like "r", because the address of it can't be
taken.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (7 preceding siblings ...)
  2020-11-03 22:09 ` jakub at gcc dot gnu.org
@ 2020-11-04  8:29 ` rguenth at gcc dot gnu.org
  2020-11-04  8:51 ` jakub at gcc dot gnu.org
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-11-04  8:29 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |documentation

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Boris from comment #7)
> (In reply to Jakub Jelinek from comment #6)
> > I agree with Andrew here, the compiler does what it is asked to do, so puts
> > the value into either memory or general purpose register.  Neither "r" nor
> > "g" allows putting the value into an SSE register.  Use "x" constraint for
> > that.
> 
> Look at the documentation:
> 
> "‘g’ Any register, memory or immediate integer operand is allowed, except
> for registers that are not general registers."

I think the wording is ambiguous and thus this is a documentation issue.
This is not about what "values" are allowed but what registers _GCC_
is allowed to choose to put the value in during register allocation.  And
GCC will just choose on of the allowed places to put the value.  GCC will
even put a floating point value into a GPR if you ask for that.  Or fail
spectacularly if it doesn't manage to do.

I'm not a native speaker but maybe

"'g' The compiler can choose any register, memory or immediate integer operand
to put the value, except for registers that are not general registers."

is the behavior consistent with that wording?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (8 preceding siblings ...)
  2020-11-04  8:29 ` rguenth at gcc dot gnu.org
@ 2020-11-04  8:51 ` jakub at gcc dot gnu.org
  2020-11-04 12:13 ` bp at alien8 dot de
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04  8:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #9)
> I'm not a native speaker but maybe
> 
> "'g' The compiler can choose any register, memory or immediate integer
> operand
> to put the value, except for registers that are not general registers."
> 
> is the behavior consistent with that wording?

Me neither, but I wonder why it doesn't say
"‘g’ Any general register, memory or immediate integer operand is allowed."
or perhaps reordered such that the general register comes last (so one doesn't
read it as general memory or general immediate integer).

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (9 preceding siblings ...)
  2020-11-04  8:51 ` jakub at gcc dot gnu.org
@ 2020-11-04 12:13 ` bp at alien8 dot de
  2020-11-04 12:20 ` jakub at gcc dot gnu.org
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-04 12:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #11 from Boris <bp at alien8 dot de> ---
Drop "general":

"‘g’ Any register, memory or immediate integer operand is allowed."

because, as you guys say, it would stick it anywhere.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (10 preceding siblings ...)
  2020-11-04 12:13 ` bp at alien8 dot de
@ 2020-11-04 12:20 ` jakub at gcc dot gnu.org
  2020-11-04 12:36 ` bp at alien8 dot de
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 12:20 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Definitely not.  Because then it wouldn't describe what it actually does.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (11 preceding siblings ...)
  2020-11-04 12:20 ` jakub at gcc dot gnu.org
@ 2020-11-04 12:36 ` bp at alien8 dot de
  2020-11-04 12:44 ` jakub at gcc dot gnu.org
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-04 12:36 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #13 from Boris <bp at alien8 dot de> ---
Then you'd need to add a sentence saying that the register asm() specification
has lower prio and thus overridden by the input operand constraint. Which is
what we have here. And then refer to the text Segher posted in comment #5 to
state that it doesn't hold true in that case...

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (12 preceding siblings ...)
  2020-11-04 12:36 ` bp at alien8 dot de
@ 2020-11-04 12:44 ` jakub at gcc dot gnu.org
  2020-11-04 12:48 ` jakub at gcc dot gnu.org
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 12:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
No, why?  You ask it to go into a general register, so it goes there.  The
local register variable has no priority at all.  All it says the variable lives
in a particular register.  If the constraints allow that register, no reloading
is needed, so you get it there, but if they don't, you get the value moved
elsewhere.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (13 preceding siblings ...)
  2020-11-04 12:44 ` jakub at gcc dot gnu.org
@ 2020-11-04 12:48 ` jakub at gcc dot gnu.org
  2020-11-04 12:55 ` bp at alien8 dot de
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 12:48 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is exactly the same as if you have some variable that must live in memory
(e.g. address taken), if you use a constraint that allows memory, it will be
put there without reloading, if it does not, then the value of the variable
will be reloaded in whatever it is asked to be put into.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (14 preceding siblings ...)
  2020-11-04 12:48 ` jakub at gcc dot gnu.org
@ 2020-11-04 12:55 ` bp at alien8 dot de
  2020-11-04 12:58 ` jakub at gcc dot gnu.org
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-04 12:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from Boris <bp at alien8 dot de> ---
(In reply to Jakub Jelinek from comment #14)
> No, why?  You ask it to go into a general register, so it goes there.  The
> local register variable has no priority at all.

And where in the documentation does it say that it has no priority?

Not here:

https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html

AFAICT.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (15 preceding siblings ...)
  2020-11-04 12:55 ` bp at alien8 dot de
@ 2020-11-04 12:58 ` jakub at gcc dot gnu.org
  2020-11-04 13:08 ` bp at alien8 dot de
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 12:58 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is all documented exactly in the place you've linked:

Then use the local variable for the asm operand and specify any constraint
letter that matches the register
^^^^^^^^^^^^^^^^^^^^^^^^^

The g constraint letter does not match that register.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (16 preceding siblings ...)
  2020-11-04 12:58 ` jakub at gcc dot gnu.org
@ 2020-11-04 13:08 ` bp at alien8 dot de
  2020-11-04 17:39 ` segher at gcc dot gnu.org
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: bp at alien8 dot de @ 2020-11-04 13:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #18 from Boris <bp at alien8 dot de> ---
It would be awesome if this text continued:

"... and specify any constraint letter that matches the register. If the
operand constraint doesn't match the register, former has higher priority over
the local register specification and gcc will adhere to the constraint
specification."

I'll even put it in a patch and send it on...

:-)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (17 preceding siblings ...)
  2020-11-04 13:08 ` bp at alien8 dot de
@ 2020-11-04 17:39 ` segher at gcc dot gnu.org
  2020-11-04 17:40 ` jakub at gcc dot gnu.org
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-04 17:39 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #19 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Documenting that GCC behaves differently is just documenting a bug :-(

It should not be hard to detect this and give an error somewhere?

Saying "the user did something wrong" is true of course, but then
saying "so the compiler can do whatever" might be technically true,
but doesn't help the user, who would rather the compiler did not
silently do the opposite of what the user asked it to do!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (18 preceding siblings ...)
  2020-11-04 17:39 ` segher at gcc dot gnu.org
@ 2020-11-04 17:40 ` jakub at gcc dot gnu.org
  2020-11-04 17:52 ` segher at gcc dot gnu.org
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 17:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
But the user didn't do anything wrong, perhaps just had bad expectations.
The user asked put the value of this variable into a general purpose register
or memory.  So the compiler did that.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (19 preceding siblings ...)
  2020-11-04 17:40 ` jakub at gcc dot gnu.org
@ 2020-11-04 17:52 ` segher at gcc dot gnu.org
  2020-11-04 17:56 ` jakub at gcc dot gnu.org
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-04 17:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #21 from Segher Boessenkool <segher at gcc dot gnu.org> ---
        register float foo asm ("xmm0") = 0.99f;

        asm volatile("movl %0, %%r8d\n\t"
                      "vmcall\n\t"
                      :: "g" (foo));

The user said operands[0] should go in xmm0, but that hard reg is not
valid for its constraint.

"""
Then use the local variable for the asm operand and specify any constraint
letter that matches the register:
"""

Not following that rule, causing a reload, is the user error.  The reload
you get is diametrically opposite to what local register vars are *for*,
so it would be good if we could give an error.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (20 preceding siblings ...)
  2020-11-04 17:52 ` segher at gcc dot gnu.org
@ 2020-11-04 17:56 ` jakub at gcc dot gnu.org
  2020-11-04 18:17 ` segher at gcc dot gnu.org
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-04 17:56 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|REOPENED                    |RESOLVED

--- Comment #22 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #21)
>         register float foo asm ("xmm0") = 0.99f;
> 
>         asm volatile("movl %0, %%r8d\n\t"
>                       "vmcall\n\t"
>                       :: "g" (foo));
> 
> The user said operands[0] should go in xmm0, but that hard reg is not
> valid for its constraint.

No, the user didn't say that.  The user said put foo into something that
matches the "g" constraint.  The compiler did.
As documented, the register in which the var lives will (and can) be only
satisfied if the constraint allows that register.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (21 preceding siblings ...)
  2020-11-04 17:56 ` jakub at gcc dot gnu.org
@ 2020-11-04 18:17 ` segher at gcc dot gnu.org
  2020-11-05 10:30 ` amonakov at gcc dot gnu.org
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-04 18:17 UTC (permalink / raw)
  To: gcc-bugs

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

Segher Boessenkool <segher at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |FIXED

--- Comment #23 from Segher Boessenkool <segher at gcc dot gnu.org> ---
The user said that foo should be in xmm1 when used in an asm.  That is
what local register asm does, nothing more, nothing less.

Reloading it is never allowed.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (22 preceding siblings ...)
  2020-11-04 18:17 ` segher at gcc dot gnu.org
@ 2020-11-05 10:30 ` amonakov at gcc dot gnu.org
  2020-11-05 11:04 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: amonakov at gcc dot gnu.org @ 2020-11-05 10:30 UTC (permalink / raw)
  To: gcc-bugs

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

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amonakov at gcc dot gnu.org

--- Comment #24 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
Segher, did you really mean to mark the bug resolved/fixed?

FWIW, I think Jakub is using an overly broad interpretation of the intended
behavior. Stretching that logic, it's possible to argue that it's okay for GCC
to put an operand in a different register than its asm specification says as
long as the constraint matches. But that would lead to wrong code.

Given that the only supported use of local register variables is passing
operands to inline asm in specific registers, I really think that GCC shouldn't
silently change the operand's location like that. The mismatching constraint
could be a result of a typo (or something like a botched refactoring), and the
compiler should help the user catch such errors.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (23 preceding siblings ...)
  2020-11-05 10:30 ` amonakov at gcc dot gnu.org
@ 2020-11-05 11:04 ` jakub at gcc dot gnu.org
  2020-11-05 12:18 ` rguenth at gcc dot gnu.org
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-05 11:04 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #25 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
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.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (24 preceding siblings ...)
  2020-11-05 11:04 ` jakub at gcc dot gnu.org
@ 2020-11-05 12:18 ` rguenth at gcc dot gnu.org
  2020-11-05 16:02 ` segher at gcc dot gnu.org
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-11-05 12:18 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|FIXED                       |---
             Status|RESOLVED                    |NEW

--- Comment #26 from Richard Biener <rguenth 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.

So it would need to be diagnosed in the FE (only), making a + 0 valid and
a not.  Eh.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (25 preceding siblings ...)
  2020-11-05 12:18 ` rguenth at gcc dot gnu.org
@ 2020-11-05 16:02 ` segher at gcc dot gnu.org
  2020-11-05 20:34 ` segher at gcc dot gnu.org
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-05 16:02 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #27 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Alexander Monakov from comment #24)
> Segher, did you really mean to mark the bug resolved/fixed?

No, if I did that, I have no idea how :-)

> Given that the only supported use of local register variables is passing
> operands to inline asm in specific registers, I really think that GCC
> shouldn't silently change the operand's location like that.

Yes, exactly.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (26 preceding siblings ...)
  2020-11-05 16:02 ` segher at gcc dot gnu.org
@ 2020-11-05 20:34 ` segher at gcc dot gnu.org
  2020-11-05 20:38 ` segher at gcc dot gnu.org
  2020-11-06 13:23 ` amonakov at gcc dot gnu.org
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-05 20:34 UTC (permalink / raw)
  To: gcc-bugs

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (27 preceding siblings ...)
  2020-11-05 20:34 ` segher at gcc dot gnu.org
@ 2020-11-05 20:38 ` segher at gcc dot gnu.org
  2020-11-06 13:23 ` amonakov at gcc dot gnu.org
  29 siblings, 0 replies; 31+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-05 20:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #29 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #26)
> So it would need to be diagnosed in the FE (only), making a + 0 valid and
> a not.  Eh.

We do not *have* to diagnose anything, certainly not things that just
happen to work (if "a+0" is optimised to just "a", say).  But it would
be good if we could diagnose the obvious and certainly wrong cases we
do not do now -- like a register asm that does not match the operand
constraint!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Bug inline-asm/97708] Inline asm does not use the local register asm specified with register ... asm() as input
  2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
                   ` (28 preceding siblings ...)
  2020-11-05 20:38 ` segher at gcc dot gnu.org
@ 2020-11-06 13:23 ` amonakov at gcc dot gnu.org
  29 siblings, 0 replies; 31+ messages in thread
From: amonakov at gcc dot gnu.org @ 2020-11-06 13:23 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #30 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
Asm operand binding should work by looking at bound lvalue: "c"(a) binds an
lvalue so if 'a' is a register var the compiler must remember its associated
register; "c"(a+0) binds an rvalue, so what kind of variable 'a' is is
irrelevant.

The way it should work internally is at gimplification time the compiler should
produce an additional asm statement argument that stores the associated
register names for each operand. For example. for

  register int a asm("%eax");
  asm("" : "r"(a+0), "r"(a), "r"(0));

gcc could internally produce a string ",%eax," signifying that operand 1 is
bound to %eax and operands 0 and 2 are not bound to any particular register.

Then all passes up to IRA don't need to give any particular care for asm
operands, and IRA can use the string to place operands in appropriate registers
(and diagnose a mismatch).

This is also the only proper way to fix PR 87984 as far as I can tell.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2020-11-06 13:23 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-03 19:58 [Bug inline-asm/97708] New: Inline asm does not use the local register asm specified with register ... asm() as input bp at alien8 dot de
2020-11-03 20:10 ` [Bug inline-asm/97708] " pinskia at gcc dot gnu.org
2020-11-03 20:16 ` bp at alien8 dot de
2020-11-03 20:39 ` segher at gcc dot gnu.org
2020-11-03 20:41 ` pinskia at gcc dot gnu.org
2020-11-03 20:55 ` segher at gcc dot gnu.org
2020-11-03 21:01 ` jakub at gcc dot gnu.org
2020-11-03 21:15 ` bp at alien8 dot de
2020-11-03 22:09 ` jakub at gcc dot gnu.org
2020-11-04  8:29 ` rguenth at gcc dot gnu.org
2020-11-04  8:51 ` jakub at gcc dot gnu.org
2020-11-04 12:13 ` bp at alien8 dot de
2020-11-04 12:20 ` jakub at gcc dot gnu.org
2020-11-04 12:36 ` bp at alien8 dot de
2020-11-04 12:44 ` jakub at gcc dot gnu.org
2020-11-04 12:48 ` jakub at gcc dot gnu.org
2020-11-04 12:55 ` bp at alien8 dot de
2020-11-04 12:58 ` jakub at gcc dot gnu.org
2020-11-04 13:08 ` bp at alien8 dot de
2020-11-04 17:39 ` segher at gcc dot gnu.org
2020-11-04 17:40 ` jakub at gcc dot gnu.org
2020-11-04 17:52 ` segher at gcc dot gnu.org
2020-11-04 17:56 ` jakub at gcc dot gnu.org
2020-11-04 18:17 ` segher at gcc dot gnu.org
2020-11-05 10:30 ` amonakov at gcc dot gnu.org
2020-11-05 11:04 ` jakub at gcc dot gnu.org
2020-11-05 12:18 ` rguenth at gcc dot gnu.org
2020-11-05 16:02 ` segher at gcc dot gnu.org
2020-11-05 20:34 ` segher at gcc dot gnu.org
2020-11-05 20:38 ` segher at gcc dot gnu.org
2020-11-06 13:23 ` amonakov at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).