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

            Bug ID: 125101
           Summary: [x86][i386][Intel asm] GCC 15 generates invalid
                    machine code when vector register names are used as
                    symbols
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: witbring at gmail dot com
  Target Milestone: ---

Description:
I found that GCC 15 can generate invalid machine code when compiling 32-bit PIE
code with Intel assembly syntax if a global variable has a name that matches an
AVX-512 register name such as ZMM8.

Minimal test case:

$ cat test.c
#include <stdio.h>

int ZMM8 = 42;

int main(void) {
  if (ZMM8 & 8)
    printf("Hello world\n");
  return 0;
}

Command line:

$ gcc-15 -O2 -m32 -masm=intel -pie -fpie test.c -o test

Actual result:
The generated executable contains invalid / unintended instructions around the
memory reference to ZMM8.

Relevant disassembly:

00001060 <main>:
    ...
    1079: 51                      push   ecx
    107a: 62                      (bad)
    107b: f4                      hlt
    107c: 04 0a                   add    al,0xa
    107e: f6 83 30 00 00 00 08    test   BYTE PTR [ebx+0x30],0x8
    1085: 75 0c                   jne    1093 <main+0x33>

The corresponding assembly emitted by GCC is:

    push    ecx
    test    BYTE PTR ZMM8@GOTOFF[ebx], 8
    jne     .L8

It looks like the assembler parses `ZMM8@GOTOFF[ebx]` as involving the register
name `ZMM8`, instead of treating `ZMM8` as a symbol. This results in unexpected
bytes in the output.
The issue is not limited to PIE builds. I can also reproduce the same problem
when compiling with `-no-pie`.

Expected result:
GCC should emit assembly that unambiguously refers to the global symbol named
`ZMM8`, or otherwise avoid generating assembly that is misparsed as a register
reference.

Affected names:
I observed this issue for global variable names in the range XMM8..XMM35 /
ZMM8..ZMM35. For example, replacing `ZMM8` with a non-register-like symbol name
avoids the issue.

Reproducer:
The issue can also be reproduced on Compiler Explorer:
https://godbolt.org/z/8rK95bj5o

Environment:
- GCC version: gcc-15 (Ubuntu 15.2.0-4ubuntu4) 15.2.0
- Target: x86 (32-bit)
- Assembler/binutils version: GNU assembler (GNU Binutils for Ubuntu) 2.45
- OS/distribution: Ubuntu 25.10

Reply via email to