Hi all,
I stumbled upon either a bug, or we are emitting wrong inline asm code.
The testcase is:
source_filename = "testcase.d"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
define void @_D7asanasm3fooFZv() {
%a = alloca [4 x i32], align 32
call void asm sideeffect "movl %ebx, 4+$0", "=*m,~{memory}"([4 x i32]* %a)
ret void
}
When I try to compile this to assembly code with llc, llc errors.
llc testcase.ll -o testcase.s -O0
:1:16: error: unknown token in expression
movl %ebx, 4+(%rsp)
^
The explicit -O0
is required for the error to arise.
The error is gone after removing (or reducing) the alignment of %a
. This makes me believe that our inline asm syntax is correct to add an offset to a pointer: " 4+$0 ".
Is this a bug in the asm parser?
Thanks,
Johan
The AT&T syntax for a displaced address doesn't have the '+'; it's
just "4(%rsp)" so you should change the IR to "4$0".
LLVM appears to be optimizing the addressing mode, and the optimizer
is being more lenient on this detail so you're getting lucky when the
+4 can be combined with an existing %rsp offset.
Cheers.
Tim.
I thought I had tested exactly that and observed wrong behaviour. But now I
see it works well... confused.
Thanks!
Johan
Things break down when part of the offset is a linktime constant:
source_filename = "asanasm.d"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
@globVar = global [2 x i32] [i32 66051, i32 66051]
define void @_D7asanasm8offconstFZv() {
call void asm sideeffect "movdqa 4$0, %xmm7", "*m,~{xmm7}"([2 x i32]*
@globVar)
ret void
}
results in:
<inline asm>:1:10: error: unexpected token in argument list
movdqa 4globVar(%rip), %xmm7
So in that case, I do have to add the '+' to make it work ("4+$0").
So depending on the pointer argument, I need to write a + or without +,
complicating automatic codegen.
Thanks for the help,
Johan
FWIW we do support:
4+4(%rsp)
as 8(%rsp)
we just don’t support
4+(%rsp)
but do support
4+0(%rsp)
as 4(%rsp)
oddly enough gas does support the 4+(%rsp) but I’ve never had time to go try to fix it in the assembler.
-eric
2017-08-03 8:58 GMT-07:00 Johan Engelen via llvm-dev <
llvm-dev@lists.llvm.org>:
> The error is gone after removing (or reducing) the alignment of `%a`.
This
> makes me believe that our inline asm syntax is correct to add an offset
to a
> pointer: " 4+$0 ".
The AT&T syntax for a displaced address doesn't have the '+'; it's
just "4(%rsp)" so you should change the IR to "4$0".
LLVM appears to be optimizing the addressing mode, and the optimizer
is being more lenient on this detail so you're getting lucky when the
+4 can be combined with an existing %rsp offset.
Things break down when part of the offset is a linktime constant:
...
So depending on the pointer argument, I need to write a + or without +,
complicating automatic codegen.
The problem is worse. The following code is accepted depending on PIC or
non-PIC compilation:
source_filename = "asanasm.d"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-linux-gnu"
@_D7asanasm9constantsG2k = global [2 x i32] [i32 66051, i32 66051]
define void @_D7asanasm8offconstFZv() {
call void asm sideeffect "movdqa 4$0, %xmm7", "*m,~{xmm7}"([2 x i32]*
@_D7asanasm9constantsG2k)
ret void
}
I get no errors with PIC:
llc test.ll -o test.s -O0 -relocation-model=pic
The asm output:
movq _D7asanasm9constantsG2k@GOTPCREL(%rip), %rax
#InlineASM
movdqa 4(%rax), %xmm7
But without PIC:
llc test.ll -o test.s -O0 -relocation-model=static
<inline asm>:1:10: error: unexpected token in argument list
movdqa 4_D7asanasm9constantsG2k(%rip), %xmm7
^
So it appears that applying an offset to a pointer variable will break
using either "4+$0" or "4$0", and you have to be lucky to guess correctly
what's going to happen with the pointer argument passed into the inline asm
call. (my problem would be solved when "4+$0" would always be accepted)
I now feel this is a bug in LLVM, do you agree?
Unfortunately, I do not know how to work around the current problem.
Thanks,
Johan
Oh I haven’t disagreed with you at all. Sorry I wasn’t clear 
Mostly the x86 asm parser needs work to support this. I -think- it’s just a matter of typing, but I haven’t really tried to fix it.
You might be able to use a register constraint to put the address into a register and go from there. It’s not ideal, but might work.
-eric