[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?

Daniel Berlin via llvm-dev llvm-dev at lists.llvm.org
Fri Mar 18 08:46:04 PDT 2016


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)



On Fri, Mar 18, 2016 at 8:24 AM, David Blaikie via llvm-dev <
llvm-dev at lists.llvm.org> 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/20160318/0a45d7dd/attachment.html>


More information about the llvm-dev mailing list