-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Description
Starting in LLVM 21 the following test case produces invalid x86-64 assembly output:
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@"$dollarsymbol" = external global [1 x i32]
define i32 @foo() {
%r = load i32, ptr @"$dollarsymbol", align 4
ret i32 %r
}
The llc output is as follows:
https://godbolt.org/z/3jnrcTeqW
$ llc -O0 --x86-asm-syntax=att bug.ll -o bug.s
foo: # @foo
movq $dollarsymbol@GOTPCREL(%rip), %rax
movl (%rax), %eax
retq
This asm output is rejected by both the GNU assembler and LLVM:
https://godbolt.org/z/1cra7v3rd
$ /usr/bin/as -o bug.o bug.s
<source>: Assembler messages:
<source>: Warning: end of file not at end of a line; newline inserted
<source>:2: Error: junk `(%rip)' after expression
<source>:2: Error: junk `(%rip)' after expression
Compiler returned: 1
https://godbolt.org/z/xhbGjan45
$ clang -o bug.o bug.s
<source>:2:39: error: unexpected token in argument list
movq $dollarsymbol@GOTPCREL(%rip), %rax
^
Compiler returned: 1
The issue does not occur when using the integrated assembler, e.g.:
$ llc -O0 --filetype=obj bug.ll -o bug.o # this is successful
We originally encountered the issue when emitting AT&T assembly syntax. For Intel syntax, it appears that GNU binutils accepts the Intel asm output but LLVM still rejects it, e.g.:
https://godbolt.org/z/TK77d8MsK
$ llc -O0 --x86-asm-syntax=intel bug.ll -o bug.intel.s
foo: # @foo
mov rax, qword ptr [rip + $dollarsymbol@GOTPCREL]
mov eax, dword ptr [rax]
ret
GNU binutils accepts the resulting Intel asm: https://godbolt.org/z/qKbEnPoYr
But LLVM rejects the resulting Intel asm: https://godbolt.org/z/681jWshGz
We are encountering this issue with our closed source Fortran front-end, which uses LLVM as a backend and produces many symbols beginning with $
dollar symbols. It appears that this commit caused the initial issue: