On March 18, 2016 3:26:37 PM GMT+01:00, Markus Trippelsdorf 
<mar...@trippelsdorf.de> wrote:
>On 2016.03.18 at 22:05 +0800, Cy Cheng 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      <= load pointer c
>> movl    $0, 8(%rax)
>> movl    $0x00000000, 12(%rax)
>> 
>> // intel-icc-13.0.1 with -fno-strict-aliasing -O2 on x86
>> call      bar(_PB**)
>> movq      (%rsp), %rdx      <= load pointer c
>> movl      %ecx, 8(%rdx)
>> movq      (%rsp), %rsi       <= load pointer c
>> movl      %ecx, 12(%rsi)
>> 
>> GCC only load pointer c once, but if I implement bar in such way:
>> PB** bar(PB** t) {
>>   char* ptr = (char*)t;
>>   *t = (PB*)(ptr-8);
>>    return t;
>> }
>> 
>> Does this volatile C99 standard rule
>> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):
>> 
>>    6.5.16 Assignment operators
>> 
>>    "3. ... The side effect of updating the stored value of the left
>operand
>>     shall occur between the previous and the next sequence point."
>
>No. We discussed this on IRC today and 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. 

Nice to see that only GCC gets this optimization opportunity :)

Richard.

Reply via email to