llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.08k stars 11.09k forks source link

Clang's call lowering often coerces pointers to ints, which blocks alias analysis #31072

Open rnk opened 7 years ago

rnk commented 7 years ago
Bugzilla Link 31724
Version unspecified
OS Windows NT

Extended Description

Consider this C code:

struct Handle { void *p; }; extern void g(struct Handle); void f(struct Handle o) { g(o); }

Here are three examples of clang coercing the 'p' field to an int:

$ clang -S -x c --target=ppc64-linux t.cpp -o - -emit-llvm | grep define define void @​f(i64 %o.coerce) #​0 {

$ clang -S -x c --target=x86_64-windows t.cpp -o - -emit-llvm | grep define define void @​f(i64 %o.coerce) #​0 {

$ clang -S -x c --target=mips-linux t.cpp -o - -emit-llvm | grep define define void @​f(i32 inreg %o.coerce) #​0 {

According to dannyb, this is bad, because the ptrtoint calls block alias analysis.

llvmbot commented 7 years ago

(and by special, i mean "only escape/etc as much as a pointer would, and not 'complete lost to the void'", which is usually how ptrtoint is treated)

llvmbot commented 7 years ago

In general, we can't do anything with pointer to int'd pointers. We can't tell where they point to. In an IPA analysis, we can't easily join them up, etc.

We also assume they escape.

BasicAA only handles bitcasts, it doesn't go back through ptrtoint/inttoptr to see if they are the same thing, unmodified (and doing so is expensive), so even inlining won't help until the inttoptr/ptrtoint pair is eliminated.

There are a couple ways to solve this.

Truthfully, the best way is to make them pointers again if possible.

If that really can't be solved, we should add metadata saying they are special, and really pointers, and include the real pointer address expression somewhere, but this seems .. hard.