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