This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Aggressive load in gcc when accessing escaped pointer?
- From: Cy Cheng <cycheng dot buddhist at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Markus Trippelsdorf <markus at trippelsdorf dot de>, gcc at gcc dot gnu dot org
- Date: Sat, 19 Mar 2016 10:32:22 +0800
- Subject: Re: Aggressive load in gcc when accessing escaped pointer?
- Authentication-results: sourceware.org; auth=none
- References: <CAKB9r5rfUppm4LJgUHnT=q8N9dTe8JOtwS=A5Q1NhtL3GshWVg at mail dot gmail dot com> <20160318142637 dot GC312 at x4> <28502E69-8365-4753-8653-7BFFB923090E at gmail dot com>
:D
But I don't understand why &c - 8 is invalid? Which rule in C99 it volatile?
That's see the example again with some changes:
// Now, I make c point to &c - 8
PB** bar(PB** t) {
char* ptr = (char*)t;
*t = (PB*)(ptr-8);
}
void qux(PB* c) {
PB* cc;
bar(&c);
c->f1_ = 0; // invalid
cc = c;
cc->f1_ = 0; // valid or invalid?
}
My question is, if &c - 8 is an invalid address, then it looks like
cc->f1_ = 0 will be an invalid operation? Or &c - 8 is only invalid in
terms of c, not cc?
(By the way, we also discuss the pattern in llvm mailing list:
https://goo.gl/VHK0dN)
2016-03-19 2:46 GMT+08:00 Richard Biener <richard.guenther@gmail.com>:
> On March 18, 2016 3:26:37 PM GMT+01:00, Markus Trippelsdorf <markus@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.
>