<div dir="ltr"><div>Hi,<br><br></div>Please look at this c code:<br><div><br>typedef struct _PB {<br>  void* data;  /* required.*/<br>  int   f1_;<br>  float f2_;<br>} PB;<br><br>PB** bar(PB** t);<br><br>void qux(PB* c) {<br>  bar(&c);              /* c is escaped because of bar */<br>  c->f1_ = 0;<br>  c->f2_ = 0.f;<br>}<br><br>// gcc-5.2.1 with -fno-strict-aliasing -O2 on x86<br>call    bar<br>movq    8(%rsp), %rax<br>movl    $0, 8(%rax)<br>movl    $0x00000000, 12(%rax)<br><br></div><div>// llvm 3.9.0 with -fno-strict-aliasing -O2 on x86</div><div>callq    bar<br>movq    (%rsp), %rax<br>movl    $0, 8(%rax)<br>movq    (%rsp), %rax<br>movl    $0, 12(%rax)<br><br></div><div>You can see that llvm load "c" twice, but gcc only load "c" once.<br></div><div>Of course, in bar function, you may do something very dangerous, e.g.<br></div><div><br>PB** bar(PB** t) {<br></div><div>   *t = (PB*) t;<br></div><div>}<br><br></div><div>But gcc doesn't care bar's definition.<br></div><div><div>Is llvm too conservative, or gcc too aggressive in this pattern?<br></div></div><div><br>Thanks for your help.<br><br></div><div>CY<br></div><div><br><br></div></div>