* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
@ 2013-05-15 18:14 ` pinskia at gcc dot gnu.org
2013-05-15 18:22 ` umbricola at gmail dot com
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-05-15 18:14 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I think you are wrong in how many registers that inline-asm uses. It uses 4
registers, two each to hold y and x which have to be loaded into a register
from the stack.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
2013-05-15 18:14 ` [Bug inline-asm/57299] " pinskia at gcc dot gnu.org
@ 2013-05-15 18:22 ` umbricola at gmail dot com
2013-05-15 18:24 ` pinskia at gcc dot gnu.org
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: umbricola at gmail dot com @ 2013-05-15 18:22 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #2 from Chris Mihelich <umbricola at gmail dot com> ---
The asm statement uses only two registers. Of the six inputs and outputs, only
"r" (p) and "r" (q) are registers; the four "=m" and "m" entries only declare
that memory is read or written in the assembly code. See the part of
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html about memory operands
(search for "If your assembler instructions access memory").
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
2013-05-15 18:14 ` [Bug inline-asm/57299] " pinskia at gcc dot gnu.org
2013-05-15 18:22 ` umbricola at gmail dot com
@ 2013-05-15 18:24 ` pinskia at gcc dot gnu.org
2013-05-15 18:44 ` umbricola at gmail dot com
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-05-15 18:24 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Chris Mihelich from comment #2)
> The asm statement uses only two registers. Of the six inputs and outputs,
> only "r" (p) and "r" (q) are registers; the four "=m" and "m" entries only
> declare that memory is read or written in the assembly code. See the part
> of http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html about memory operands
> (search for "If your assembler instructions access memory").
Since the value of y and x are stored on the stack as they are arguments to the
function, their values need to be loaded into a regsiter first before passing
it on to the inline-asm.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (2 preceding siblings ...)
2013-05-15 18:24 ` pinskia at gcc dot gnu.org
@ 2013-05-15 18:44 ` umbricola at gmail dot com
2013-05-15 18:53 ` pinskia at gcc dot gnu.org
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: umbricola at gmail dot com @ 2013-05-15 18:44 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #4 from Chris Mihelich <umbricola at gmail dot com> ---
Yes indeed, x is loaded from the stack into edi, and y is loaded from the stack
into esi, as the register variable declarations specified. That's two
registers. Where are the other two?
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (3 preceding siblings ...)
2013-05-15 18:44 ` umbricola at gmail dot com
@ 2013-05-15 18:53 ` pinskia at gcc dot gnu.org
2013-05-15 19:20 ` umbricola at gmail dot com
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-05-15 18:53 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Chris Mihelich from comment #4)
> Yes indeed, x is loaded from the stack into edi, and y is loaded from the
> stack into esi, as the register variable declarations specified. That's two
> registers. Where are the other two?
Simple, "m"(*x) cannot use either edi or esi. Likewise for "m"(*y). You can
change the *y to *q and *x to *p, it will work.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (4 preceding siblings ...)
2013-05-15 18:53 ` pinskia at gcc dot gnu.org
@ 2013-05-15 19:20 ` umbricola at gmail dot com
2013-05-15 20:16 ` pinskia at gcc dot gnu.org
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: umbricola at gmail dot com @ 2013-05-15 19:20 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #6 from Chris Mihelich <umbricola at gmail dot com> ---
Ah, but "=m" and "m" operands shouldn't need any register at all: their purpose
is just to declare that a specific piece of memory is written or read in the
assembly code, a declaration that helps the optimizer avoid mistakes. The GCC
manual sketches this pattern thus:
Note that in the following example the memory input is necessary, otherwise GCC
might optimize the store to x away:
int foo ()
{
int x = 42;
int *y = &x;
int result;
asm ("magic stuff accessing an 'int' pointed to by '%1'"
: "=&d" (r) : "a" (y), "m" (*y));
return result;
}
Clearly this code is not trying to put the pointer y into a second register
that it doesn't use. The point is to prevent the initialization of x with 42
from being deleted as (apparently) useless. There is no indication in the
manual that this "m" (*y) would occupy a register, nor is there any good reason
for a register to be consumed in this case.
I agree with your interpretation in this one sense: GCC appears to be assigning
registers to the "m" and "=m" values as you suggest. That makes my test case
need six registers (not four) instead of the two it really needs. That is the
defect I was trying to describe.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (5 preceding siblings ...)
2013-05-15 19:20 ` umbricola at gmail dot com
@ 2013-05-15 20:16 ` pinskia at gcc dot gnu.org
2013-05-15 21:57 ` umbricola at gmail dot com
2013-05-15 21:59 ` pinskia at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-05-15 20:16 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution|--- |INVALID
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Chris Mihelich from comment #6)
> I agree with your interpretation in this one sense: GCC appears to be
> assigning registers to the "m" and "=m" values as you suggest. That makes
> my test case need six registers (not four) instead of the two it really
> needs. That is the defect I was trying to describe.
Actually it only needs 4 (and not 6) due to holding of the pointer of y and x
can happen with only 2 registers. And you can use the operands of the m inside
the inline-asm which is why it needs to store the pointer in a register.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (6 preceding siblings ...)
2013-05-15 20:16 ` pinskia at gcc dot gnu.org
@ 2013-05-15 21:57 ` umbricola at gmail dot com
2013-05-15 21:59 ` pinskia at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: umbricola at gmail dot com @ 2013-05-15 21:57 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #8 from Chris Mihelich <umbricola at gmail dot com> ---
(In reply to Andrew Pinski from comment #7)
> Actually it only needs 4 (and not 6) due to holding of the pointer of y and
> x can happen with only 2 registers.
That's not what GCC is doing, actually. When I take out -fPIC and compile, the
disassembly looks like this:
00000000 <f>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 57 push %edi
4: 56 push %esi
5: 53 push %ebx
6: 8b 7d 08 mov 0x8(%ebp),%edi
9: 8b 75 0c mov 0xc(%ebp),%esi
c: 8b 45 08 mov 0x8(%ebp),%eax
f: 8b 5d 0c mov 0xc(%ebp),%ebx
12: 8b 55 08 mov 0x8(%ebp),%edx
15: 8b 4d 0c mov 0xc(%ebp),%ecx
18: 5b pop %ebx
19: 5e pop %esi
1a: 5f pop %edi
1b: 5d pop %ebp
1c: c3 ret
You can see that six registers, not four, are being loaded in the body of f.
> And you can use the operands of the m inside the inline-asm which is why it
> needs to store the pointer in a register.
If I gave the "m" operand a name and used the name, or if I referred to, say,
%0 inside the body of the asm statement, you would be correct. But I didn't.
There is no reason to give a register to a "m" or "=m" operand that is not
referenced in the asm body, and this is the common case for "m" operands.
Their main purpose is to prevent incorrect optimizations, not to pass values to
the assembly code.
The spurious register allocation makes "m" operands unusable in most complex
asm statements. It doesn't take too many memory dependencies to exhaust the
stingy x86 general-purpose register set.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug inline-asm/57299] Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures
2013-05-15 18:08 [Bug inline-asm/57299] New: Inline assembly memory dependencies produce spurious loads, register pressure, compilation failures umbricola at gmail dot com
` (7 preceding siblings ...)
2013-05-15 21:57 ` umbricola at gmail dot com
@ 2013-05-15 21:59 ` pinskia at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-05-15 21:59 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57299
--- Comment #9 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Oh without optimization 6 registers will be used rather than the 4 that GCC can
do with optimizations turned on.
^ permalink raw reply [flat|nested] 10+ messages in thread