https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97477
Bug ID: 97477 Summary: g++ doesn't accept __restrict keyword inside array function parameter Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: dwwork at gmail dot com Target Milestone: --- I was looking into how gcc treats the restrict keyword, when I discovered a case that g++ does not accept using the __restrict gnu extension keyword. The following function, compiled with gcc 10.2, and flags "-O3 -mavx", produces vectorized assembly: void func(const float a[restrict 3][8], const float b[restrict 3][8], float c[restrict 3][8]) { a = __builtin_assume_aligned(a,32); b = __builtin_assume_aligned(b,32); c = __builtin_assume_aligned(c,32); for(int i=0; i<8; i++) { c[0][i] = a[0][i] + b[0][i]; c[1][i] = a[1][i] + b[1][i]; c[2][i] = a[2][i] + b[2][i]; } } The restrict keyword inside the square brackets is legal according to cppreference: https://en.cppreference.com/w/c/language/restrict I then tested g++ 10.2, changing the restrict keyword to __restrict. This does not compile: void func(const float a[__restrict 3][8], const float b[__restrict 3][8], float c[__restrict 3][8]) { a = __builtin_assume_aligned(a,32); b = __builtin_assume_aligned(b,32); c = __builtin_assume_aligned(c,32); for(int i=0; i<8; i++) { c[0][i] = a[0][i] + b[0][i]; c[1][i] = a[1][i] + b[1][i]; c[2][i] = a[2][i] + b[2][i]; } } It gives me the following error (edited for brevity): error: expected primary-expression before '__restrict' error: expected ']' before '__restrict' error: expected ')' before '__restrict' error: expected initializer before numeric constant I can get g++ to output vectorized code if I change the types to a pointer of float[8]: void func(const float (* __restrict a)[8], const float (* __restrict b)[8], float (* __restrict c)[8]) { a = static_cast<const float (*)[8]>( __builtin_assume_aligned(a,32) ); b = static_cast<const float (*)[8]>( __builtin_assume_aligned(b,32) ); c = static_cast< float (*)[8]>( __builtin_assume_aligned(c,32) ); for(int i=0; i<8; i++) { c[0][i] = a[0][i] + b[0][i]; c[1][i] = a[1][i] + b[1][i]; c[2][i] = a[2][i] + b[2][i]; } } It's not a serious bug, but I do feel it is inconsistent. I did browse the source code a bit to investigate, but I was way over my head.