Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22228

`restrict` ignored unless function manually inlined

$
0
0

With GCC 9.4.0, the code

static inline double k(double const *restrict a) {    return a[-1] + a[0] + a[1];}static void f(double const *restrict a, double *restrict b, int n) {    for (int i = 0; i < n; ++i) {        b[i] = k(a);    }}static inline void swap(double **a, double **b) {    double *tmp = *a;    *a = *b;    *b = tmp;}void g(double * a, double * b, int n, int nt) {    for (int t = 0; t < nt; ++t) {        f(a, b, n);        swap(&a, &b);    }}

results in loop versioned for vectorization because of possible aliasing for the loop in f when compiled using gcc -march=native -Ofast -fopt-info-vec, suggesting that the restrict qualifiers in f are being ignored.

If I instead manually inline k into f:

static void f(double const *restrict a, double *restrict b, int n) {    for (int i = 0; i < n; ++i) {        b[i] = a[-1] + a[0] + a[1];    }}

the loop is vectorized without this versioning.

In both cases GCC reports that all of the functions are automatically inlined into each other.

The same occurs if I instead use __restrict and compile with g++.

Why does this happen? Is there a cleanly portable (using standard language features) way of causing GCC to respect the restrict qualifiers in the first case so that I can benefit from vectorization without versioning, without separating f and g into different translation units?


Viewing all articles
Browse latest Browse all 22228

Trending Articles