> 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 <mailto:hubert.reinterpretcast at gmail.com>> wrote:
> On Fri, Nov 25, 2016 at 1:42 AM, Daniel Berlin <dberlin at dberlin.org
<mailto: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/20161125/2592a7e6/attachment.html>