https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86619
--- Comment #4 from Michael Veksler <mickey.veksler at gmail dot com> --- It is interesting to check the impact on numerical C++ benchmarks. Fortran has a conceptual restrict on all its parameter arrays, since aliasing is not allowed. void f(int * __restrict__ v1, int * __restrict__ v2, int n) { for (int i=0 ; i < n ; i++) v1[0] += v2[i]; } and Fortran: subroutine f(v1, v2, n) integer :: v1(100) integer :: v2(100) integer :: n DO i=1, n v1(1) = v1(1) + v2(i) END DO end subroutine f Generate the same loop: .L3: addl (%rdx), %eax addq $4, %rdx cmpq %rdx, %r8 jne .L3 But without restrict, as expected, g++ generates: .L8: addl (%rdx), %eax addq $4, %rdx cmpq %r8, %rdx movl %eax, (%rcx) jne .L8 Running both variants from a loop (in a separate translation unit, without whole program optimization) (g++ 7.2.0 with -O2 on 64 bit cygwin): #include <ctime> #include <iostream> void f(int * __restrict__ v1, int *__restrict__ v2, int SIZE); void g(int * v1, int * v2, int SIZE); constexpr int SIZE = 1'000'000; int v2[SIZE]; int main() { int v1; f(&v1, v2, SIZE); // Warm up cache auto start = std::clock(); constexpr int TIMES = 10'000; for (int i=0 ; i < TIMES; ++i) { v1 = 0; f(&v1, v2, SIZE); } auto t1 = std::clock(); for (int i=0 ; i < TIMES; ++i) { v1 = 0; g(&v1, v2, SIZE); } auto t2 = std::clock(); std::cout << "with restrict: " << double(t1 - start) / CLOCKS_PER_SEC << " sec\n"; std::cout << "without restrict: " << double(t2 - t1) / CLOCKS_PER_SEC << " sec\n"; } And the results are: with restrict: 4.477 sec without restrict: 5.756 sec Which clearly demonstrates the impact of good alias analysis. With plain C pointers, this is an unavoidable price. But unfortunately this also happens when passing pointers or references to arrays of different sizes, or when inheriting two different types from std::array, in order to mark the parameters as non-aliasing.