This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
#include <assert.h> struct V2F { inline V2F() { } inline V2F(float x) { _v[1]=_v[0]=x; } inline V2F(float x,float y) { _v[0]=x; _v[1]=y; } float _v[2]; }; inline V2F operator + (const V2F& a,const V2F& b) { return V2F(a._v[0]+b._v[0],a._v[1]+b._v[1]); } inline bool operator == (const V2F& a,const V2F& b) { return a._v[0]==b._v[0] && a._v[1]==b._v[1]; } void test_restrict_v(V2F * __restrict__ v0, V2F * __restrict__ v1, V2F * __restrict__ v2) { (*v2)=(*v0); (*v2)=(*v2)+(*v1); assert((*v2)==(*v0)+(*v1)); } int main(int,char**) { V2F v0(1.0),v1(1.0),v2; test_restrict_v(&v0,&v1,&v2); return 0; } /* % g++ -W -Wall -O bug.cxx % ./a.out % g++ -W -Wall -O2 bug.cxx % ./a.out a.out: t.cxx:28: void test_restrict_v(V2F*, V2F*, V2F*): Assertion `(*v2)==(*v0)+(*v1)' failed. Looks like optimization mishandles const references to restricted data (here in 'operator +'). This code works in -O2 if any of 'const &', 'inline' ('operator +'), or '__restrict__' ('test_restrict_v') is removed. My system is Debian GNU/Linux (sarge) with g++ (GCC) 3.3.4 (Debian 1:3.3.4-2) Thanks for this great piece of software! JD */
Confirmed. This worked in 3.2, failed in 3.3 and 3.4, and seems to be fixed in mainline. W.
Add Gabby to CC as I moved the target to 3.4.2.
Here is something a little more obvious (maybe): ------------------ extern "C" void abort (); struct S { float u, dummy; }; inline S add (const S& a,const S& b) { return (S) { a.u+b.u, 0 }; } void foo(S * __restrict__ v0, S * __restrict__ v1, S * __restrict__ v2) { // add copy v2 of v0 and v1; write result // into v0 (*v2) = (*v0); (*v0) = add(*v2, *v1); if (v0->u != 2) abort (); } int main() { S v0={1}, v1={1}, v2; foo(&v0,&v1,&v2); } ---------------------------- g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -O2 x.cc ; ./a.out g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -O2 x.cc ; ./a.out Aborted W.
This seems to be fixed in gcc 3.4.1. Btw, here's something even shorter: ============================================= extern "C" void abort (); struct S { float u, dummy; }; inline S add (const S& a,const S& b) { return (S) { a.u+b.u, 0 }; } void foo(S * __restrict__ v0) { (*v0) = add(*v0, *v0); if (v0->u != 2) abort (); } int main() { S v0={1}; foo(&v0); } =============================================
The testcase in comment #3 fails with my 3.4-branch version from 20040612. Volker, what are you using? Maybe this narrows the range of patches in case someone wants to backport it to 3.3.x. W.
I'll do some regression hunting to identify the patch. Just one more: The C and C++ frontend show different behavior. The following testcase is valid C and C++. It should return 2. ==================================== typedef struct { int i, j; } A; inline A foo (const A* p, const A* q) { return (A){p->i+q->i}; } int bar(A* __restrict__ p) { (*p)=foo(p,p); return p->i; } int main() { A a={1}; return bar(&a); } ==================================== Compiled a C program we fail since gcc 3.0, with C++ since gcc 3.3. Both cases seem to be fixed with 3.4.1.
Created an attachment (id=6752) [edit] patch for 3.3 branch OK, here we are: The regression was fixed on the 3.4 branch and mainline by Mark's patch http://gcc.gnu.org/ml/gcc-cvs/2004-06/msg01078.html Apart from comments it's a 6-liner. Attached is an updated version that applies to the 3.3 branch and seems to solve the problems. I didn't do a full bootstrap, though.
Patch here: http://gcc.gnu.org/ml/gcc-patches/2004-07/msg01564.html
Subject: Bug 16536 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: reichelt@gcc.gnu.org 2004-07-16 00:21:18 Modified files: gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: restrict-1.c Log message: PR rtl-optimization/16536 * gcc.c-torture/execute/restrict-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.229&r2=1.3389.2.230 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/restrict-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 16536 CVSROOT: /cvs/gcc Module name: gcc Changes by: reichelt@gcc.gnu.org 2004-07-16 00:25:59 Modified files: gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: restrict-1.c Log message: PR rtl-optimization/16536 * gcc.c-torture/execute/restrict-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4007&r2=1.4008 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/restrict-1.c.diff?cvsroot=gcc&r1=1.1&r2=1.2
Gaby, do you want to include the patch from comment #7/#8 in gcc 3.3.5?
Subject: Re: [3.3 regression] Incorrect __restrict__ optimization in -O2 "reichelt at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | Gaby, do you want to include the patch from comment #7/#8 in gcc 3.3.5? I'll look into it. Thanks! -- Gaby
Adjust milestone
Subject: Bug 16536 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: reichelt@gcc.gnu.org 2004-12-10 17:25:07 Modified files: gcc : ChangeLog alias.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: restrict-1.c Log message: PR rtl-optimization/16536 Backport from mainline: 2004-06-25 Mark Mitchell <mark@codesourcery.com> * alias.c (get_alias_set): Adjust setting of DECL_POINTER_ALIAS_SET for pointers to aggregates. * gcc.c-torture/execute/restrict-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.1036&r2=1.16114.2.1037 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/alias.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.181.2.6&r2=1.181.2.7 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.2261.2.388&r2=1.2261.2.389 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/restrict-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.2.44.1
Fixed.