ldc icon indicating copy to clipboard operation
ldc copied to clipboard

LLVM does not accept generated inline assembly with variable+offset

Open JohanEngelen opened this issue 8 years ago • 6 comments
trafficstars

Testcase:

void foo()
{
    uint[4] a;
    asm pure nothrow @nogc {
        mov a, EAX;
        mov a+4, EBX;
    }
}

When compiled with ldc2 -c -fsanitize=address test.d, we get the error:

<inline asm>:1:16: error: unknown token in expression
        movl %ebx, 4+(%rcx)
                      ^
LLVM ERROR: Error parsing inline asm

Strangely, when I compile manually to LLVM IR and then use llc to obtain assembly output, everything works fine. So I can't reproduce it from LLVM IR onwards.

The inline asm looks like this in LLVM IR:

  call void asm sideeffect "movl %eax, $0\0A\09movl %ebx, 4+$1", "=*m,=*m,~{memory}"([4 x i32]* %3, [4 x i32]* %3)

without -fsanitize=address, the $1 resolves to ebp plus an offset; with -fsanitize=address, the $1 resolves to a register without any offset and that's invalid (i.e. "4+(%rcx)" is not valid but "4+32(%rcx)" is). At least that's what I think is what's going on.

JohanEngelen avatar Aug 03 '17 15:08 JohanEngelen

(btw, this prevents compilation of druntime with -fsanitize=address :()

JohanEngelen avatar Aug 03 '17 15:08 JohanEngelen

Note: to get equal assembly output from llc as from ldc2, llc must be called with -O0 explicit.

Edit: and with the explicit -O0, I can reproduce it with llc. Perhaps an LLVM bug. Edit: no, bug in our code: See https://lists.llvm.org/pipermail/llvm-dev/2017-August/116158.html

JohanEngelen avatar Aug 03 '17 15:08 JohanEngelen

Testcase without ASan:

void foo()
{
    align(32) uint[4] a;
    asm pure nothrow @nogc {
        mov a+4, EBX;
    }
}

JohanEngelen avatar Aug 03 '17 16:08 JohanEngelen

LLVM needs some work to support it: https://lists.llvm.org/pipermail/llvm-dev/2017-August/116244.html

JohanEngelen avatar Oct 03 '17 21:10 JohanEngelen

There's some inline assembly included by windows.h for 32-bit Windows that triggers this bug—which is a real drag, so I've been toying around with the code that translates DMD-style assembly to LLVM inline assembly, and I think I've come up with a bodge that workarounds the issue: https://github.com/ldc-developers/ldc/pull/4632

just-harry avatar Apr 22 '24 20:04 just-harry

There's some inline assembly included by windows.h for 32-bit Windows that triggers this bug

Note that similar problems wrt. missing (gcc) builtins and gcc-style inline assembly also happen on Posix platforms - if a .c file is compiled. Just importing a .c file is sufficient in many cases, when using a higher-level API only and only needing some function and struct declarations - all the inline functions aren't codegen'd nor analyzed in that case, making most problems go away.

kinke avatar Apr 23 '24 10:04 kinke