https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66702
Bug ID: 66702 Summary: #pragma omp declare simd uniform and linear issues Product: gcc Version: 5.1.1 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- void bar (int &a, int &b, int *&c, int &d) { volatile int x; int *volatile y; x = a; a = x; x = b; b = x; y = c; c = y; x = d; d = x; } void (*volatile barp) (int &, int &, int *&, int &) = bar; #pragma omp declare simd uniform(b, c) linear(d:2) aligned(c:32) notinbranch int foo (int a, int b, int *c, int d) { a++; b++; c += 8; d += 2; barp (a, b, c, d); return a + b + *c + d; } volatile int e = 5; int c[64] __attribute__((aligned (32))); int main () { int d = 7, r = 0; int b = e; for (int i = 0; i < 64; i++) c[i] = i; #pragma omp simd reduction(+:r) linear(d:2) for (int i = 0; i < 64; i++) { r += foo (i, b, c, d); d += 2; } if (r != 7584) __builtin_abort (); } is miscompiled with -O2 -fopenmp, because uniform and linear clauses were properly handled only for non-addressable variables of gimple type. For addressable vars (both linear and uniform) or for non-gimple types or C++ args passed by invisible reference (uniform only), if the arguments are modified in the function, we need to make a copy of the initial var and restore it for each VL.