Nvc 21.5 generates incorrect code on aarch64 at -O2

Let’s consider the quite trivial reproducer below, and compile it with -O2 on aarch64

#include <stdio.h>

#define N 10


double reduce(double * a, int n) {
    double res;
    for (int i=0; i< n; i++)
        res += a[i];
    return res;
}

int main(int argc, char *argv[]) {
   double a[N];
   int i;
   for (i=0; i<N; i++) {
       a[i] = i;
   }
   printf("%f\n", reduce(a, N));
   return 0;
}

The generated code for the reduce() subroutine is incorrect

00000000004008d0 <reduce>:
  4008d0:       d2efff08        mov     x8, #0x7ff8000000000000         // #9221120237041090560
  4008d4:       9e670100        fmov    d0, x8
  4008d8:       d65f03c0        ret
  4008dc:       d503201f        nop

and the outcome is wrong

$ nvc -O2 -o test_reduce test_reduce.c
$ ./test_reduce 
nan

fwiw, the generated code is ok when built with -O1

$ nvc -O1 -o test_reduce test_reduce.c 
$ ./test_reduce 
45.000000

“res” is uninitialized so may contain garbage values. To fix, set it to zero.

% cat reduce.c
#include <stdio.h>

#define N 10

double reduce(double * a, int n) {
    double res=0.0;
    for (int i=0; i< n; i++)
        res += a[i];
    return res;
}

int main(int argc, char *argv[]) {
   double a[N];
   int i;
   for (i=0; i<N; i++) {
       a[i] = i;
   }
   printf("%f\n", reduce(a, N));
   return 0;
}
% nvc -O2 reduce.c ; a.out
45.000000
1 Like

Thanks for the quick reply and my apology for this gross overlook!

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.