NVC++ produces incorrect results for the following code at -O2 and -O3:
#include <cstdio>
#include <vector>
struct Pair { int value[2]; };
std::vector<Pair> make(int n, bool horizontal) {
std::vector<Pair> result(n);
int nx = horizontal ? n : 1, ny = horizontal ? 1 : n, k = 0;
for (int y = 1; y <= ny; ++y)
for (int x = 1; x <= nx; ++x) {
for (int i = 0; i < 2; ++i) result[k].value[i] = 0;
if (x == nx) result[k].value[0] = 1;
if (y == ny) result[k].value[1] = 1;
++k;
}
return result;
}
int main() {
auto result = make(2, false);
for (auto &p : result) std::printf("%d %d\n", p.value[0], p.value[1]);
}
> nvc++ -O0 example.cpp && ./a.out
1 0
1 1
> nvc++ -O2 example.cpp && ./a.out
0 0
1 0
Reproduced with 26.1, 26.3, 26.5 and 26.9 on aarch64, and 26.5 on x86-64. -O0 and -O1 produce the expected output. GCC also compiles this correctly.
The inner zeroing loop seems to play a role here: removing it produces the expected result. The vector constructor already initializes those values to zero. Adding -Mnoautoinline also produces the expected result at both -O2 and -O3.
Valgrind reports no errors on x86-64 with 26.5, even though the optimized program still prints the incorrect values.
Thanks!
Tom