[LLVMdev] noalias locals

Kenneth Uildriks kennethuil at gmail.com
Sun Nov 14 11:37:44 PST 2010


On Sun, Nov 14, 2010 at 11:45 AM, Reid Kleckner <reid.kleckner at gmail.com> wrote:
> On Sun, Nov 14, 2010 at 11:17 AM, Kenneth Uildriks <kennethuil at gmail.com> wrote:
>> To fix that and compile C++ correctly while aggressively
>> devirtualizing it, we would need to apply "noalias" to the result of
>> placement-new in all cases, even when placement-new is inlined.  More
>> generally, when inlining any function with a "noalias" return, the
>> inlined result needs to have "noalias" applied to it.
>
> Is that the right way to go?  It seems like that might cause other
> optimizers to introduce invalid transformations.  For example, if the
> instruction scheduler knows that those pointers don't alias, it might
> reschedule a store to the memory after the constructor call from the
> placement new.
>
> struct Foo {
>  int a;
>  Foo(int a) : a(a) {}
> };
>
> int main(void) {
>  Foo f;
>  f.a = 1;
>  Foo *p = new (&f) Foo(2);
>  // what does p->a contain?  1 or 2?
> }
>
> There's a lot of problems with this example, but I don't know enough
> optimizer details to construct a better one.
>
> Can you get by with a MayAlias?  It seems like you can divirtualize
> everything that MustAlias and ignore the rest.

I see what you mean.  If the placement new result mayalias its
original pointer, we can hold both vptrs invariant and have everything
else reloaded from memory as appropriate.  Now if the placement-new is
known to place an object of a different type from the original object,
the front-end can NoAlias them instead because pointers to the old
object become invalid according to the standard and any use of them
while the new object is in that memory slot is allowed to cause
undefined behavior.  So I guess we need to be able to force either
MayAlias or NoAlias as appropriate.

The trouble comes if placement-new overlays an object of a different
type, we allow the result of placement-new to MustAlias the input to
placement-new (which they most certainly will if placement-new is
inlined), and we try to hold the vptrs invariant.  In that case, the
optimizer might assume that the new vptr is equal to the original
vptr, which is *not* a valid assumption to make.

>
> If I understood the last discussion on this, the reason you don't need
> to worry about placement new getting called within callees is that you
> have to use the pointer returned by placement new, or you get
> undefined behavior, so you can safely assume the vptr is immutable.
>
> Reid
>
You're allowed to safely assume the vptr is immutable every time you
reuse a given pointer to the object.  The trouble comes when AA can
prove that two different pointers to two different objects actually
point to the same address - the standard allows both pointers to
coexist and both objects to exist in that memory at different times,
as long as a pointer to one object is never used when the memory
contains the other object - and AA can't (currently) prove any such
thing with respect to a pointer returned from a callee.




More information about the llvm-dev mailing list