[LLVMdev] noalias locals

Reid Kleckner reid.kleckner at gmail.com
Sun Nov 14 11:52:32 PST 2010


On Sun, Nov 14, 2010 at 2:37 PM, Kenneth Uildriks <kennethuil at gmail.com> wrote:
> 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.

I don't think that was quite my meaning.  I'm saying that NoAlias
isn't what you want, because it allows other optimizations to make
invalid transformations.  In this example, with your suggestion after
inlining, my example might look like:

int main(void) {
  Foo f;
  f.a = 1;
  Foo *p = noalias(&f); // magic aliasing intrinsic
  p->a = 2;
}

Now, because &f must not alias p, it would be valid to perform this
transformation:

int main(void) {
  Foo f;
  Foo *p = noalias(&f); // magic aliasing intrinsic
  p->a = 2;
  f.a = 1;
}

If you use MayAlias, this transformation is not legal.  Like I said,
it's a bad example, because it's not clear why that transformation
could be profitable, but the point is that stores may be reordered
unsafely.  Using MayAlias forces other optimizations to be
conservative.  Devirtualization should still be able to work, because
you it will only fire if it sees a MustAlias.

Reid




More information about the llvm-dev mailing list