[llvm-dev] Placement new and TBAA

Daniel Berlin via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 25 21:01:01 PST 2016


Yes, I misread, because I didn't think -O1 turned on strict aliasing and
missed that part

On Fri, Nov 25, 2016, 8:23 PM Mehdi Amini <mehdi.amini at apple.com> wrote:

>
> On Nov 25, 2016, at 4:17 PM, Daniel Berlin via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>
>
> On Fri, Nov 25, 2016 at 6:10 AM, Hubert Tong <
> hubert.reinterpretcast at gmail.com> wrote:
>
> On Fri, Nov 25, 2016 at 1:42 AM, Daniel Berlin <dberlin at dberlin.org>
> wrote:
>
> What is the purpose of the union there?
>
> The purpose of the union is to increase portability by ensuring that the
> placement new is not being performed on insufficiently sized or aligned
> memory.
>
> Gotcha
>
>
>
>
> I ask because pretty much no compiler will respecting the unioning without
> visible accesses  in all cases, because it would ruin most optimization[1]
>
> But i'm also not sure it's required in this testcase to make your testcase
> fail.
>
> It isn't. The program should be valid, without the union, on platforms
> where int and float have the same size an alignment.
>
>
> Right, so you need to debug that first, and see what's going wrong.
> Without TBAA info in the .ll file, this should just work.
>
>
>
>
>
> In practice, handling placement new properly in gcc required the
> equivalent of a new intrinsic (in gcc, it required adding
> CHANGE_DYNAMIC_TYPE_EXPR).
>
> Sure; my question is whether or not there is already a solution in the
> works for LLVM. If not, then I'll try to work with some folks to propose an
> intrinsic.
>
>
> I would first focus on understanding why the testcase fails without any
> TBAA info at all.
> In that case, i would expect it to work.
>
>
>
> 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.
>
> 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).
>
>
>> Mehdi
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161126/6b0aae53/attachment.html>


More information about the llvm-dev mailing list