Eric Astor via llvm-dev
2019-Dec-09 20:27 UTC
[llvm-dev] IR inline assembly: the x86 Intel "offset" operator
Hi all, I'm trying to land (a rebased version of) http://llvm.org/D37461 - which should make it possible to handle x86 Intel assembly like mov eax, offset Foo::ptr + 1 (Currently, omitting the +1 works... but offset doesn't work in compound expressions.) I'm having trouble figuring out what inline assembly I can emit into the LLVM IR that will work properly. So far, the closest I've gotten is call void asm sideeffect inteldialect "mov eax, offset $0 + $$1, "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @"?ptr at Foo@@2PAHA") But that expands to mov eax, offset [?ptr at Foo@@2PAHA] + 1 which ends up incorrectly dereferencing the address first. I haven't found a working combination of code & constraints that will expand to mov eax, offset ?ptr at Foo@@2PAHA + 1 Is this possible? Thanks, - Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191209/8011012f/attachment.html>
Eric Astor via llvm-dev
2019-Dec-10 22:01 UTC
[llvm-dev] IR inline assembly: the x86 Intel "offset" operator
Actually, there's more of a bug here than I realized: https://godbolt.org/z/fktmVn seems to show that LLVM's current handling of offset goes wrong with global variables... with a global `int Bar;`, inline assembly mov eax, offset Bar ends up as mov eax, dword ptr [Bar] which I'm pretty sure is not what's intended here. I've written LLVM IR that does produce an equivalent result (see the Compiler Explorer link above), but I'm not sure how to get X86Operand to produce a direct memory operand... I can't figure out where the memory constraint gets turned into an indirect memory constraint ("*m"). Anyone have any leads I can follow? Thanks, - Eric On Mon, Dec 9, 2019 at 3:27 PM Eric Astor <epastor at google.com> wrote:> Hi all, > > I'm trying to land (a rebased version of) http://llvm.org/D37461 - which > should make it possible to handle x86 Intel assembly like > mov eax, offset Foo::ptr + 1 > (Currently, omitting the +1 works... but offset doesn't work in compound > expressions.) > > I'm having trouble figuring out what inline assembly I can emit into the > LLVM IR that will work properly. So far, the closest I've gotten is > call void asm sideeffect inteldialect "mov eax, offset $0 + $$1, > "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @"?ptr at Foo@@2PAHA") > But that expands to > mov eax, offset [?ptr at Foo@@2PAHA] + 1 > which ends up incorrectly dereferencing the address first. > > I haven't found a working combination of code & constraints that will > expand to > mov eax, offset ?ptr at Foo@@2PAHA + 1 > Is this possible? > > Thanks, > - Eric >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191210/7d54e414/attachment.html>
Eric Astor via llvm-dev
2019-Dec-10 22:12 UTC
[llvm-dev] IR inline assembly: the x86 Intel "offset" operator
Argh. Apologies, found what I'd done wrong in the godbolt link. I'd forgotten to set the target triple to i386-pc-windows-msvc. This brings me back to my original question: is there anything I can write in LLVM IR inline assembly to get llc to emit mov eax, offset ?ptr at Foo@@2PAHA + 1 ? On Tue, Dec 10, 2019 at 5:01 PM Eric Astor <epastor at google.com> wrote:> Actually, there's more of a bug here than I realized: > > https://godbolt.org/z/fktmVn seems to show that LLVM's current handling > of offset goes wrong with global variables... with a global `int Bar;`, > inline assembly > mov eax, offset Bar > ends up as > mov eax, dword ptr [Bar] > which I'm pretty sure is not what's intended here. > > I've written LLVM IR that does produce an equivalent result (see the > Compiler Explorer link above), but I'm not sure how to get X86Operand to > produce a direct memory operand... I can't figure out where the memory > constraint gets turned into an indirect memory constraint ("*m"). Anyone > have any leads I can follow? > > Thanks, > - Eric > > On Mon, Dec 9, 2019 at 3:27 PM Eric Astor <epastor at google.com> wrote: > >> Hi all, >> >> I'm trying to land (a rebased version of) http://llvm.org/D37461 - which >> should make it possible to handle x86 Intel assembly like >> mov eax, offset Foo::ptr + 1 >> (Currently, omitting the +1 works... but offset doesn't work in compound >> expressions.) >> >> I'm having trouble figuring out what inline assembly I can emit into the >> LLVM IR that will work properly. So far, the closest I've gotten is >> call void asm sideeffect inteldialect "mov eax, offset $0 + $$1, >> "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @"?ptr at Foo@@2PAHA") >> But that expands to >> mov eax, offset [?ptr at Foo@@2PAHA] + 1 >> which ends up incorrectly dereferencing the address first. >> >> I haven't found a working combination of code & constraints that will >> expand to >> mov eax, offset ?ptr at Foo@@2PAHA + 1 >> Is this possible? >> >> Thanks, >> - Eric >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191210/1520d2c1/attachment.html>
Reid Kleckner via llvm-dev
2019-Dec-11 00:23 UTC
[llvm-dev] IR inline assembly: the x86 Intel "offset" operator
I think perhaps we want to make this LLVM IR asm string: call void asm sideeffect inteldialect "mov eax, $0", "i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @"?Bar@@3HA") #1, !srcloc !3 The key thing is the 'i' constraint. That ends up producing the wrong assembly right now, but maybe with your rebased patch, now it will do the right thing. If you change up the dialect and switch to an ELF triple, this inline asm will produce the expected instruction sequence: call void asm sideeffect "movl $0, %eax", "i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @"?Bar@@3HA") #1, !srcloc !3 Which is what makes me think this is the way to go. It's consistent with the AOK_Skip rewrite we do today to skip the "offset" text. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191210/cce14f3f/attachment.html>
Eric Astor via llvm-dev
2019-Dec-11 17:45 UTC
[llvm-dev] IR inline assembly: the x86 Intel "offset" operator
Interesting - the patch doesn't address this yet. It looks like we have a difference (maybe bug?) in how we handle Intel vs. AT&T inline assembly: https://godbolt.org/z/GQw9ED Suppose we're expanding an operand with an 'i' constraint, where the operand is given as, e.g. (i32* @Bar). If the inline assembly is in Intel dialect, this expands as "Bar" in AT&T syntax or "dword ptr [Bar]" in Intel syntax. If the inline assembly is in AT&T dialect, it expands as "$Bar" in AT&T syntax or "offset Bar" in Intel syntax. I'd like to try to reconcile this, but I haven't been able to track down where inline-assembly operands are expanded yet... anyone know where I should be looking? On Tue, Dec 10, 2019 at 7:23 PM Reid Kleckner <rnk at google.com> wrote:> I think perhaps we want to make this LLVM IR asm string: > call void asm sideeffect inteldialect "mov eax, $0", > "i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @"?Bar@@3HA") #1, !srcloc !3 > > The key thing is the 'i' constraint. That ends up producing the wrong > assembly right now, but maybe with your rebased patch, now it will do the > right thing. > > If you change up the dialect and switch to an ELF triple, this inline asm > will produce the expected instruction sequence: > call void asm sideeffect "movl $0, %eax", > "i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @"?Bar@@3HA") #1, !srcloc !3 > Which is what makes me think this is the way to go. > > It's consistent with the AOK_Skip rewrite we do today to skip the "offset" > text. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191211/ceea4d2f/attachment.html>