public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15
@ 2015-03-16 12:46 adam at consulting dot net.nz
  2015-03-16 14:01 ` [Bug inline-asm/65436] " jakub at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: adam at consulting dot net.nz @ 2015-03-16 12:46 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 65436
           Summary: Max number of extended asm +input operands currently
                    limited to 15
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: adam at consulting dot net.nz

<https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html> states:
"The total number of input + output + goto operands is limited to 30."

It appears a "+" input operand is internally counted as a dual input plus
output operand which limits the total number of such registers to 15:

30_operands.c:
#include <stdint.h>

typedef uint8_t u8x16_t __attribute__ ((vector_size (16)));

int main(void) {
  register uint64_t rdi asm ("rdi");
  register uint64_t rsi asm ("rsi");
  register uint64_t r10 asm ("r10");
  register uint64_t r11 asm ("r11");
  register uint64_t rbx asm ("rbx");
  register uint64_t rbp asm ("rbp");
  register uint64_t r12 asm ("r12");
  register uint64_t r14 asm ("r14");
  register uint64_t r15 asm ("r15");
  register uint64_t r13 asm ("r13");
  register u8x16_t xmm2 asm ("xmm2");
  register u8x16_t xmm3 asm ("xmm3");
  register u8x16_t xmm4 asm ("xmm4");
  register u8x16_t xmm5 asm ("xmm5");
  register u8x16_t xmm6 asm ("xmm6");
  register u8x16_t xmm7 asm ("xmm7");

  //15 operands is OK
  asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
             "+r" (r12),   "+r" (r14),   "+r" (r15),   "+r" (r13),   "+x"
(xmm2),  "+x" (xmm3),
             "+x" (xmm4),  "+x" (xmm5),  "+x" (xmm6));

  //16 operands
  asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
             "+r" (r12),   "+r" (r14),   "+r" (r15),   "+r" (r13),   "+x"
(xmm2),  "+x" (xmm3),
             "+x" (xmm4),  "+x" (xmm5),  "+x" (xmm6),  "+x" (xmm7));

  register u8x16_t xmm8 asm ("xmm8");
  register u8x16_t xmm9 asm ("xmm9");
  register u8x16_t xmm10 asm ("xmm10");
  register u8x16_t xmm11 asm ("xmm11");
  register u8x16_t xmm12 asm ("xmm12");
  register u8x16_t xmm13 asm ("xmm13");
  register u8x16_t xmm14 asm ("xmm14");
  register u8x16_t xmm15 asm ("xmm15");

  //24 operands
  asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
             "+r" (r12),   "+r" (r14),   "+r" (r15),   "+r" (r13),   "+x"
(xmm2),  "+x" (xmm3),
             "+x" (xmm4),  "+x" (xmm5),  "+x" (xmm6),  "+x" (xmm7),  "+x"
(xmm8),  "+x" (xmm9),
             "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x"
(xmm14), "+x" (xmm15));

  register u8x16_t xmm0 asm ("xmm0");
  register u8x16_t xmm1 asm ("xmm1");
  register uint64_t rax asm ("rax");
  register uint64_t rcx asm ("rcx");
  register uint64_t rdx asm ("rdx");
  register uint64_t r8 asm ("r8");
  register uint64_t r9 asm ("r9");

  //31 operands
  asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
             "+r" (r12),   "+r" (r14),   "+r" (r15),   "+r" (r13),   "+x"
(xmm2),  "+x" (xmm3),
             "+x" (xmm4),  "+x" (xmm5),  "+x" (xmm6),  "+x" (xmm7),  "+x"
(xmm8),  "+x" (xmm9),
             "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x"
(xmm14), "+x" (xmm15),
             "+x" (xmm0),  "+x" (xmm1),  "+r" (rax),   "+r" (rcx),   "+r"
(rdx),   "+r" (r8),
             "+r" (r9));

  register uint64_t mmx0 asm ("mm0");
  register uint64_t mmx1 asm ("mm1");
  register uint64_t mmx2 asm ("mm2");
  register uint64_t mmx3 asm ("mm3");
  register uint64_t mmx4 asm ("mm4");
  register uint64_t mmx5 asm ("mm5");
  register uint64_t mmx6 asm ("mm6");
  register uint64_t mmx7 asm ("mm7");

  //39 operands
  asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
             "+r" (r12),   "+r" (r14),   "+r" (r15),   "+r" (r13),   "+x"
(xmm2),  "+x" (xmm3),
             "+x" (xmm4),  "+x" (xmm5),  "+x" (xmm6),  "+x" (xmm7),  "+x"
(xmm8),  "+x" (xmm9),
             "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x"
(xmm14), "+x" (xmm15),
             "+x" (xmm0),  "+x" (xmm1),  "+r" (rax),   "+r" (rcx),   "+r"
(rdx),   "+r" (r8),
             "+r" (r9),    "+y" (mmx0),  "+y" (mmx1),  "+y" (mmx2),  "+y"
(mmx3),  "+y" (mmx4),
             "+y" (mmx5),  "+y" (mmx6),  "+y" (mmx7));

  return 0;
}

$ gcc-snapshot.sh -O3 30_operands.c
30_operands.c: In function 'main':
30_operands.c:29:3: error: more than 30 operands in 'asm'
   asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
   ^
30_operands.c:43:3: error: more than 30 operands in 'asm'
   asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
   ^
30_operands.c:57:3: error: more than 30 operands in 'asm'
   asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
   ^
30_operands.c:74:3: error: more than 30 operands in 'asm'
   asm volatile ("" : "+r" (rdi),   "+r" (rsi),   "+r" (r10),   "+r" (r11),  
"+r" (rbx),   "+r" (rbp),
   ^

CLANG compiles the program:
$ clang-3.6 -Wall -O3 30_operands.c
$

Due to the double counting of +input operands it would be sensible for the
operand limit to be at least twice the number of architecture registers. For
x64 the minimum should be 2*(16 GPR + 16 XMM + 8 MMX) = 80 operands. This
minimum does not include provision for goto operands.


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

* [Bug inline-asm/65436] Max number of extended asm +input operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
@ 2015-03-16 14:01 ` jakub at gcc dot gnu.org
  2015-03-17 21:59 ` gccbugzilla at limegreensocks dot com
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2015-03-16 14:01 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Bumping this is very expensive, there are lots of data structures with
MAX_RECOG_OPERANDS sized arrays and some even MAX_RECOG_OPERANDS x
MAX_RECOG_OPERANDS arrays.


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

* [Bug inline-asm/65436] Max number of extended asm +input operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
  2015-03-16 14:01 ` [Bug inline-asm/65436] " jakub at gcc dot gnu.org
@ 2015-03-17 21:59 ` gccbugzilla at limegreensocks dot com
  2015-03-17 22:05 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: gccbugzilla at limegreensocks dot com @ 2015-03-17 21:59 UTC (permalink / raw)
  To: gcc-bugs

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

David <gccbugzilla at limegreensocks dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |gccbugzilla@limegreensocks.
                   |                            |com

--- Comment #2 from David <gccbugzilla at limegreensocks dot com> ---
In fact, this effect of '+' is explicitly documented at
<https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>:

Operands using the '+' constraint modifier count as two operands (that is, both
as input and output) towards the total maximum of 30 operands per asm
statement.

Have you actually hit this limit?  Or is this a theoretical discussion?


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

* [Bug inline-asm/65436] Max number of extended asm +input operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
  2015-03-16 14:01 ` [Bug inline-asm/65436] " jakub at gcc dot gnu.org
  2015-03-17 21:59 ` gccbugzilla at limegreensocks dot com
@ 2015-03-17 22:05 ` pinskia at gcc dot gnu.org
  2015-03-17 22:31 ` [Bug inline-asm/65436] Max number of extended asm +output " adam at consulting dot net.nz
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2015-03-17 22:05 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Also for vectors should you not use intrinsics instead of the asm.
Also if you are writing to all of the registers, won't it be easier to write
the function in pure assembly code rather than writing the code partly in C and
partly in assembly code.

Clobbers don't count towards the total and should be used instead.


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

* [Bug inline-asm/65436] Max number of extended asm +output operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
                   ` (2 preceding siblings ...)
  2015-03-17 22:05 ` pinskia at gcc dot gnu.org
@ 2015-03-17 22:31 ` adam at consulting dot net.nz
  2015-03-17 22:33 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: adam at consulting dot net.nz @ 2015-03-17 22:31 UTC (permalink / raw)
  To: gcc-bugs

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

Adam Warner <adam at consulting dot net.nz> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Max number of extended asm  |Max number of extended asm
                   |+input operands currently   |+output operands currently
                   |limited to 15               |limited to 15

--- Comment #4 from Adam Warner <adam at consulting dot net.nz> ---
Yes I've hit the limit. A limit that your competition clang does not have.

This is not a theoretical discussion.


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

* [Bug inline-asm/65436] Max number of extended asm +output operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
                   ` (3 preceding siblings ...)
  2015-03-17 22:31 ` [Bug inline-asm/65436] Max number of extended asm +output " adam at consulting dot net.nz
@ 2015-03-17 22:33 ` pinskia at gcc dot gnu.org
  2015-03-18  1:21 ` adam at consulting dot net.nz
  2015-03-21 10:14 ` gccbugzilla at limegreensocks dot com
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2015-03-17 22:33 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Adam Warner from comment #4)
> Yes I've hit the limit. A limit that your competition clang does not have.
> 
> This is not a theoretical discussion.

What kind of inline-asm are you using this for?


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

* [Bug inline-asm/65436] Max number of extended asm +output operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
                   ` (4 preceding siblings ...)
  2015-03-17 22:33 ` pinskia at gcc dot gnu.org
@ 2015-03-18  1:21 ` adam at consulting dot net.nz
  2015-03-21 10:14 ` gccbugzilla at limegreensocks dot com
  6 siblings, 0 replies; 8+ messages in thread
From: adam at consulting dot net.nz @ 2015-03-18  1:21 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Adam Warner <adam at consulting dot net.nz> ---
Sorry, I did not mean to send my previous comment. I updated the title and a
hasty comment I was about to edit got added.

It is unfair to dismiss my enhancement request as invalid. I correctly
explained the current limitation (which happens to match the documentation!),
proposed raising the limit from 30 to 80+ (marked as an enhancement request),
and provided code which tests a limit up to 2x39=78 double-counted operands.

I'm told it is too costly to raise this limit due to the way gcc handles asm
operands internally. I think this is will-not-fix territory due to the current
architecture of gcc. How does clang manage to compile the same code?

I know of no public code where gcc's 15/30 asm operand limit has been a
problem. The limitations I'm hitting in private code are naturally not your
primary, secondary nor even tertiary concern. The limitation will only be
important if the technique is used in a popular project where benchmark
competition across compilers encourages gcc to remove the limitation.


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

* [Bug inline-asm/65436] Max number of extended asm +output operands currently limited to 15
  2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
                   ` (5 preceding siblings ...)
  2015-03-18  1:21 ` adam at consulting dot net.nz
@ 2015-03-21 10:14 ` gccbugzilla at limegreensocks dot com
  6 siblings, 0 replies; 8+ messages in thread
From: gccbugzilla at limegreensocks dot com @ 2015-03-21 10:14 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from David <gccbugzilla at limegreensocks dot com> ---
While I don't yet see a case here to justify making this change generally, it
may be useful to change this for private builds of gcc.  For those cases,
change this line in gcc/genconfig.c:

  max_recog_operands = 29;  /* We will add 1 later.  */

This generates MAX_RECOG_OPERANDS in insn-config.h, which controls the number
of parameters for asm statements.

Like Andrew, I would be interested to see what you are doing that modifies > 15
registers in inline asm on x86.  My gut says there's got to be a cleaner way
than throwing more parameters at it, but maybe not.


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

end of thread, other threads:[~2015-03-21  5:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-16 12:46 [Bug c/65436] New: Max number of extended asm +input operands currently limited to 15 adam at consulting dot net.nz
2015-03-16 14:01 ` [Bug inline-asm/65436] " jakub at gcc dot gnu.org
2015-03-17 21:59 ` gccbugzilla at limegreensocks dot com
2015-03-17 22:05 ` pinskia at gcc dot gnu.org
2015-03-17 22:31 ` [Bug inline-asm/65436] Max number of extended asm +output " adam at consulting dot net.nz
2015-03-17 22:33 ` pinskia at gcc dot gnu.org
2015-03-18  1:21 ` adam at consulting dot net.nz
2015-03-21 10:14 ` gccbugzilla at limegreensocks dot com

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