Chuang-Yu Cheng via llvm-dev
2016-Mar-15 14:58 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
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? Thanks for your help. CY -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160315/b6dbf5bd/attachment.html>
Chris Lattner via llvm-dev
2016-Mar-17 23:35 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
> 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. -Chris
Markus Trippelsdorf via llvm-dev
2016-Mar-18 08:28 UTC
[llvm-dev] Redundant load in llvm's codegen compares to gcc when accessing escaped pointer?
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
Reasonably Related 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?