[llvm-dev] Placement new and TBAA

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Sat Nov 26 08:11:33 PST 2016


----- Original Message -----
> From: "Daniel Berlin via llvm-dev" <llvm-dev at lists.llvm.org>
> To: "Sanjoy Das" <sanjoy at playingwithpointers.com>, "Mehdi Amini" <mehdi.amini at apple.com>
> Cc: "llvm-dev" <llvm-dev at lists.llvm.org>
> Sent: Saturday, November 26, 2016 12:03:01 AM
> Subject: Re: [llvm-dev] Placement new and TBAA
> 
> The position most compilers take is the the access must be visibly
> through a union if you want it to work. Otherwise, it's not possible
> to use tbaa really at all. Move your function f to another file, for
> example, and you simply could never tell. Some will give you a
> little more, but you are pushing your luck
> 
> This was discussed in depth in the thread I quoted, and has GCC
> mailing list threads going back to before llvm existed :).
> Note that there are rules about touching members in a union other
> than the first one you set, but pretty much everyone guarantees type
> punning through unions to work.
> 

I think that the wording in 3.10 reflects this. It says that you need to access the data through a glvalue of the union type in this case.

 -Hal

> 
> 
> On Fri, Nov 25, 2016, 9:07 PM Sanjoy Das <
> sanjoy at playingwithpointers.com > wrote:
> 
> 
> Hi,
> 
> On Sat, Nov 26, 2016 at 9:53 AM, Mehdi Amini < mehdi.amini at apple.com
> > wrote:
> > The PR says "passes with -fno-strict-aliasing”, my understanding is
> > that it
> > is failing only with the TBAA indeed.
> > 
> > You don’t need the main and the union to reproduce, extracting
> > foo() alone
> > in its single own file is enough:
> > 
> > void *operator new(decltype(sizeof 0), void *) noexcept;
> > float *qq;
> > void foo(int *p, int *q, long unk) {
> > for (long i = 0; i < unk; ++i) {
> > ++*p;
> > qq = new (static_cast<void *>(&q[i])) float(42);
> > }
> > }
> > 
> > LICM will get the store to p out of the loop, conceptually turning
> > it into:
> > 
> > void foo(int *p, int *q, long unk) {
> > for (long i = 0; i < unk; ++i) {
> > qq = new (static_cast<void *>(&q[i])) float(42);
> > }
> > ++*p;
> > }
> > 
> > 
> > Now I don’t know if the use of placement new in this example is
> > legal in the
> > first place. I thought calling delete before using placement new
> > was
> > mandatory.
> 
> So if you:
> 
> 1. override operator delete to do nothing for that type (so that the
> placement new actually has unfreed backing storage to re-use).
> 2. have an empty destructor.
> 
> and have the source program be
> 
> void *operator new(decltype(sizeof 0), void *) noexcept;
> float *qq;
> void foo(int *p, int *q, long unk) {
> // unk = 1
> for (long i = 0; i < unk; ++i) {
> ++*p;
> delete &q[i]; // since i is only ever 0, this does not
> // delete a derived pointer
> qq = new (static_cast<void *>(&q[i])) float(42);
> }
> }
> 
> then I suspect we'll have the same problem after the destructor and
> the operator delete for that type has been inlined away.
> 
> > CC Sanjoy, since he looked into TBAA recently and it reminds me a
> > similar
> > test case he mentioned, not with placement new but with a call to a
> > function
> > taking int * and float *, and passing the same address (call site
> > was
> > union).
> 
> The case I was talking about was something like:
> 
> // C11 source file.
> 
> union S {
> int i;
> float f;
> };
> 
> void f(int* i, float *f) {
> *i = 20;
> *f = 40.0;
> }
> 
> void g() {
> union S s;
> f(&s.i, &s.f);
> }
> 
> 
> At least cursorily this looked well defined in C++ to me -- f should
> first write int(20) and then float(40.0) to the same location
> legally.
> However clang emits tbaa such that LLVM concludes that in f, the
> store
> to i and the store to f don't alias.
> 
> However, I'm not very confident in the "this looked well defined"
> reading. I did not consult the standard, but instead relied on second
> hand stackoverflow answers, so I won't be surprised to hear that I
> was
> wrong about this. Actually I'm never surprised to hear that I'm
> wrong, but I'll be especially less surprised in this case. :)
> 
> Thanks!
> -- Sanjoy
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> 

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory


More information about the llvm-dev mailing list