[PATCH] D18986: [ThinLTO] Prevent importing of "llvm.used" values

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 18 21:38:11 PDT 2016


tejohnson added a comment.

In http://reviews.llvm.org/D18986#404640, @joker.eph wrote:

> Yes this was my tentative distinction 1) and 2) above, i.e. promoting a function present in llvm.used vs importing a function that contains inline ASM.


They are related: 1) (local value present on the llvm.used) means that 2) (importing a function with inline asm) has to be conservative as the inline asm may contain a reference to that local value.

> We should be able to always promote AFAICT, but not import the one that contains Inline ASM if it has a reference to a local function.


Except that you don't know which inline asm references which local function or variable from the llvm.used. For instance, the source code used to generate the example in this patch is:

static const unsigned char __attribute__((used)) __attribute__ ((aligned (1))) myvar = 1;
void foo(unsigned long int *v) {

  __asm__ volatile("movzbl     myvar(%%rip), %%eax\n\t"
                   "movq %%rax, %0\n\t"
                       : "=*m" (*v)
    :
    : "%eax"
    );

}

The inline asm string "movzbl myvar(..." is an opaque blob that the compiler doesn't AFAIK do any analysis on to decide what is a global value - the reason why the myvar ends up in llvm.used is only because of the __attribute__((used)) on the myvar def, not because the compiler detects the reference within an inline assembly string.

But what I could do, which is a bit smaller of a hammer, is to prevent importing of any function that has any inline asm in it, if the module also contains an llvm.used with local values. However, I thought that inline assembly would be rare enough to make this simpler workaround reasonable, especially since a longer term solution will be needed for the general issue on the LTO side (where this workaround won't help). I also have some concerns about getting it right if the decisions are more fine grained: e.g. if we decide to prevent importing for just those functions with inline assembly, do we suppress the importing by not emitting their summaries (might cause some complications if their linkage needs to be adjusted e.g. if they themselves are local and referenced by a different function that is imported thus requiring their promotion), or should they have summaries but mark them as no import somehow (in that case do their summaries need to conservatively reference all values in the llvm.used sets?), etc...haven't entirely thought through all the issues with implementing that approach.

I am not entirely sure what other cases will use llvm.used besides inline assembly, are there other cases where we need to be conservative in the presence of one, because we won't have visibility into where the uses actually are or be able to rename them?


http://reviews.llvm.org/D18986





More information about the llvm-commits mailing list