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

Chuang-Yu Cheng via llvm-dev llvm-dev at lists.llvm.org
Fri Mar 18 08:33:08 PDT 2016


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
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160318/aed6d43f/attachment.html>


More information about the llvm-dev mailing list