From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17585 invoked by alias); 16 Oct 2013 09:42:22 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 17496 invoked by uid 48); 16 Oct 2013 09:42:18 -0000 From: "paulo@matos-sorge.com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/48885] missed optimization with restrict qualifier? Date: Wed, 16 Oct 2013 09:42:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 4.6.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: trivial X-Bugzilla-Who: paulo@matos-sorge.com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2013-10/txt/msg00946.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48885 --- Comment #5 from Paulo J. Matos --- (In reply to Marc Glisse from comment #4) > (In reply to Paulo J. Matos from comment #3) > > My understanding is that for restrict optimization to take effect, variable > > a has also to be restrict. Otherwise in the first assignment *a = *v;, a > > could point to the same memory as v > > No, the standard is quite clear that restrict is only needed on one variable > to ensure it doesn't alias the other. > > "During each execution of B, let L be any lvalue that has &L based on P. If > L is used to access the value of the object X that it designates, and X is > also modified (by any means), then the following requirements apply: T shall > not be const-qualified. Every other lvalue used to access the value of X > shall also have its address based on P" > > v points to X > P is v > L is *v > a is not based on v (if I write v=0, that doesn't change the value of the > pointer a), so the lvalue *a cannot be used to access X. > > There is even an example where restrict is not specified on all variables: > > "EXAMPLE 1 The file scope declarations > int * restrict a; > int * restrict b; > extern int c[]; > assert that if an object is accessed using one of a, b, or c, and that > object is modified anywhere in the program, then it is never accessed using > either of the other two." > > > > A separate remark, for the case with no "restrict" at all: > - if *a and *v are disjoint, we don't need the second load; > - if a == v, we don't need the second load either; > - the only case where we could need a reload is if *a and *v partially > overlap, I don't know if that's ever legal. I would love to say I am convinced but I am not [yet]. In the example c is extern so it's not really defining an object. All other examples in the standard have restrict being applied to all the pointers. But I am not terribly convinced I am right either. Extern seems to have special meaning given the sentence from the standard: "2 If D appears inside a block and does not have storage class extern, let B denote the block. If D appears in the list of parameter declarations of a function definition, let B denote the associated block. Otherwise, let B denote the block of main (or the block of whatever function is called at program startup in a freestanding environment)." My initial comments were based on this explanation: http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html First I do understand this is not the standard but it sounded much clear: "In this case, I promise that the pointer declared along with the restrict qualifier is not aliased. I certify that writes through this pointer will not effect the values read through any other pointer available in the same context which is also declared as restricted."