This is an archive of the discontinued LLVM Phabricator instance.

[Inline asm][GCC compatibility] Handle %v-prefixed code in inline assembly
Needs ReviewPublic

Authored by d.zobnin.bugzilla on Apr 1 2016, 10:16 AM.

Details

Reviewers
echristo
Summary

Handle an inline assembly feature of GCC: code prefixed with "%v", e. g. "%vpcmpestri" is transformed into "vpcmpestri" instruction if target supports AVX and into "pcmpestri" otherwise.

Given the code:

void f(void* arg)
{
  __asm__ ("%vpcmpestri $0, (%1), %2"
           : "=c"(arg)
           : "r"(arg), "x"(arg));
}

"gcc -c test.c -o test.o" produces

movq   -0x10(%rbp),%xmm0
pcmpestri $0x0,(%rax),%xmm0

While "gcc -c -march=corei7-avx test.c -o test.o" produces

vmovq  %rdx,%xmm0
vpcmpestri $0x0,(%rax),%xmm0

Diff Detail

Event Timeline

d.zobnin.bugzilla retitled this revision from to [Inline asm][GCC compatibility] Handle %v-prefixed code in inline assembly.
d.zobnin.bugzilla updated this object.
d.zobnin.bugzilla added a reviewer: echristo.
d.zobnin.bugzilla added a subscriber: cfe-commits.
echristo edited edge metadata.Apr 4 2016, 2:42 PM

That's fascinating and terrifying all at once.

Can you rename the test to avx-v-modifier-inline-asm.c please?

One inline comment as well.

Thanks!

-eric

lib/AST/Stmt.cpp
639

This should probably check the feature set based on the function rather than the feature set of the base compile yes? What does gcc do if you put it in an attribute((target("..."))) function?

d.zobnin.bugzilla edited edge metadata.

Eric, thank you for the review!

I've renamed the test, but have also made it a .cpp file for the reasons described below.

You are right -- GCC looks at "target" attribute applied to the function in which inline asm exists. But GCC seems to take into account lambda's attributes as well, if asm statement is inside a lambda. To be correct, GCC seems to collect all target features from command line, function and lambda's attributes, so such code:

void f8(void *x) __attribute__((__target__("no-avx")));
void f8(void *x) {
  auto g1 = [](void *arg) __attribute__((__target__("avx2"))) {
    auto g2 = [&arg]() __attribute__((__target__("no-mmx"))) {
      int a = 10, b;
      __asm__ ("%vmovq (%%rbp), %%xmm0" : "=r"(b) : "r"(a) : "%eax");
    };
    g2();
  };
  g1(x);
}

will produce "vmovq" instruction regardless of command line arguments because of g1's attribute.

I tried several approaches to implement this behavior and came up with this patch, please take a look!

d.zobnin.bugzilla marked an inline comment as done.Apr 19 2016, 4:48 AM

Friendly ping, please take a look.

Thank you,
Denis Zobnin

This is just a weekly friendly ping.
Please take a look at the new patch!

Thank you,
Denis Zobnin

Updated the patch after r266292 commit: [ASTImporter] Implement some expression-related AST node import.

Hi,

Couple of inline comments. The direction is getting there, but there's some overall architecture issues to sort out I think.

Thanks!

-eric

include/clang/AST/Stmt.h
1555

I'd prefer not to keep SupportsAVX cached, or pass it though, but rather look up what we need from the function if we need it. We can also cache the set of valid subtarget features on the Stmt if necessary from the Function.

lib/Sema/SemaStmtAsm.cpp
144–146

Hate to say, but this is the point that we now have 3 of these scattered around - can you take a look at what it will take to merge all of these in a way that we can look up the cached features?