Chuang-Yu Cheng via llvm-dev
2016-Mar-19 02:37 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
Agree, and I did : ) Please refer to this mailing list: https://gcc.gnu.org/ml/gcc/2016-03/msg00179.html On Sat, Mar 19, 2016 at 1:25 AM, Daniel Berlin <dberlin at dberlin.org> wrote:> I suspect you should just go ask #1 on the gcc mailing list and see what > the answer is. > We are basically trying to figure out their reasoning, but we should > instead just go ask what it is :) > > > On Fri, Mar 18, 2016 at 8:33 AM, Chuang-Yu Cheng via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> 1. Same question as David, why &c - 8 is invalid? Is it related to below >> statements In C99 standard? >> >> 6.5.3.3: >> "Among the invalid values for dereferencing a pointer by the unary * >> operator are a null pointer, an >> address inappropriately aligned for the type of object pointed to, and >> the address of an object after the >> end of its lifetime." >> >> 2. We are trying to preserve 1st load and remove other loads now, because >> our test pattern can not get rid of "-fno-strict-aliasing", and additional >> loads hurt performance. We did some change in SROA::runOnAlloca, we try to >> do something like this: >> >> void qux(PB* _c) { >> PB* c; <= insert this for original code >> bar(&_c); >> >> c = _c; <= insert this for original code >> c->f1_ = 0; >> c->f2_ = 0.f; >> } >> >> Any opinions please let us know. >> Thanks! >> >> CY >> >> On Fri, Mar 18, 2016 at 11:24 PM, David Blaikie <dblaikie at gmail.com> >> wrote: >> >>> Why would computing that pointer be invalid? >>> >>> (I could imagine, if there was no object behind c to point to it would >>> be invalid - but that's a dynamic property of the program that the >>> compiler, given this code, can't prove /isn't true/ (the programmer >>> might've constructed the caller such that it does always have an object >>> behind 'c' to point to)) >>> >>> On Fri, Mar 18, 2016 at 1:28 AM, Markus Trippelsdorf via llvm-dev < >>> llvm-dev at lists.llvm.org> wrote: >>> >>>> On 2016.03.17 at 16:35 -0700, Chris Lattner via llvm-dev wrote: >>>> > >>>> > > On Mar 15, 2016, at 7:58 AM, Chuang-Yu Cheng via llvm-dev < >>>> llvm-dev at lists.llvm.org> wrote: >>>> > > >>>> > > Hi, >>>> > > >>>> > > Please look at this c code: >>>> > > >>>> > > typedef struct _PB { >>>> > > void* data; /* required.*/ >>>> > > int f1_; >>>> > > float f2_; >>>> > > } PB; >>>> > > >>>> > > PB** bar(PB** t); >>>> > > >>>> > > void qux(PB* c) { >>>> > > bar(&c); /* c is escaped because of bar */ >>>> > > c->f1_ = 0; >>>> > > c->f2_ = 0.f; >>>> > > } >>>> > > >>>> > > // gcc-5.2.1 with -fno-strict-aliasing -O2 on x86 >>>> > > call bar >>>> > > movq 8(%rsp), %rax >>>> > > movl $0, 8(%rax) >>>> > > movl $0x00000000, 12(%rax) >>>> > > >>>> > > // llvm 3.9.0 with -fno-strict-aliasing -O2 on x86 >>>> > > callq bar >>>> > > movq (%rsp), %rax >>>> > > movl $0, 8(%rax) >>>> > > movq (%rsp), %rax >>>> > > movl $0, 12(%rax) >>>> > > >>>> > > You can see that llvm load "c" twice, but gcc only load "c" once. >>>> > > Of course, in bar function, you may do something very dangerous, >>>> e.g. >>>> > > >>>> > > PB** bar(PB** t) { >>>> > > *t = (PB*) t; >>>> > > } >>>> > > >>>> > > But gcc doesn't care bar's definition. >>>> > > Is llvm too conservative, or gcc too aggressive in this pattern? >>>> > >>>> > In my opinion, in the face of -fno-strict-aliasing, GCC is being too >>>> > aggressive. It would be interesting to hear what they think. >>>> >>>> We discussed this issue briefly on the #gcc IRC channel. >>>> Richard Biener pointed out that bar cannot make c point to &c - 8, >>>> because computing that pointer would be invalid. So c->f1_ cannot >>>> clobber c itself. >>>> >>>> -- >>>> Markus >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>> >>> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160319/31a52696/attachment.html>
Chuang-Yu Cheng via llvm-dev
2016-Mar-22 15:41 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
Reply from Michael: &x points to the start of object x, and &x - something (something != 0) points outside object x. 'c' was a complete object, so &c-8 points outside any object, hence the formation of that pointer is already invalid (as is its dereference). https://gcc.gnu.org/ml/gcc/2016-03/msg00185.html>>On Fri, Mar 18, 2016 at 8:46 AM, Daniel Berlin <dberlin at dberlin.org> wrote: >> >> I *think the argument* goes that this is a 20 or 24 byte object, so if you *could* put something of type PB at c-8, you'd illegally overlap with the object at c. >> >> Thus, there can't be an object of type PB at c-8. >> >> (IE any valid object must be sizeof(PB) away in either direction, which means it's not possible for c->f1_ to clobber c no matter what bar does)>>> We discussed this issue briefly on the #gcc IRC channel. >>> Richard Biener pointed out that bar cannot make c point to &c - 8, >>> because computing that pointer would be invalid. So c->f1_ cannot >>> clobber c itself. >>> >>> -- >>> Markus
Than McIntosh via llvm-dev
2016-Mar-23 18:20 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
The rationale given does not seem to square (IMHO) with the ubiquitous practice of having 0- or 1-length array at the end of a struct and then allocating additional elements for it using malloc, or the so-called "struct hack": http://c-faq.com/struct/structhack.html For example: typedef struct { enum inst_type type; unsigned num_ops; struct operand ops[1]; } inst; // allocate an instruction with specified number of operands int *allocate_inst(unsigned num_operands) { char *mem = malloc(sizeof(inst) + sizeof(struct operand) * (num_operands-1)); return (inst *) mem; } Or maybe the reasoning is that computing a pointer off the beginning of something (e.g. &c - X) is somehow worse than computing a pointer off the end of something (e.g. &c + X)? Than On Tue, Mar 22, 2016 at 11:41 AM, Chuang-Yu Cheng via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Reply from Michael: > > &x points to the start of object x, and &x - something (something != 0) > points outside object x. 'c' was a complete object, so &c-8 points > outside any object, hence the formation of that pointer is already > invalid (as is its dereference). > > https://gcc.gnu.org/ml/gcc/2016-03/msg00185.html > > >>On Fri, Mar 18, 2016 at 8:46 AM, Daniel Berlin <dberlin at dberlin.org> > wrote: > >> > >> I *think the argument* goes that this is a 20 or 24 byte object, so > if you *could* put something of type PB at c-8, you'd illegally overlap > with the object at c. > >> > >> Thus, there can't be an object of type PB at c-8. > >> > >> (IE any valid object must be sizeof(PB) away in either direction, > which means it's not possible for c->f1_ to clobber c no matter what bar > does) > > >>> We discussed this issue briefly on the #gcc IRC channel. > >>> Richard Biener pointed out that bar cannot make c point to &c - 8, > >>> because computing that pointer would be invalid. So c->f1_ cannot > >>> clobber c itself. > >>> > >>> -- > >>> Markus > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160323/4d066fb7/attachment.html>
Apparently Analagous Threads
- Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
- Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
- Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
- Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
- Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?