Optimization bugs

I found two optimization problems with version 13.7

First one in pgcc:

#include <stdio.h>
#include <math.h>
void main() {
  int skip,i,k,keep;
  double ulp,thr;
  unsigned char tab[65536];
  union {
    double dbl;
    short  i16[4];
  } share;
  ulp=2.0e-16;
  thr=1.0e-14;
  for(k=0; k<65536; k++) {
    share.dbl=0.0;
    share.i16[3]=(short)k;
    skip=0;
    for(i=0; i<6; i++) {
      if(fabs(ulp*share.dbl*255.0)<thr) skip++;
      else break;
      share.dbl=share.dbl*256.0;
    }
    if(skip>6) skip=6;
    tab[k]=8-skip;
  }
  printf("%u\n",tab[16000]);
}

which produces:

$ pgcc a.c ; ./a.out 
5

$ pgcc -O2 a.c ; ./a.out 
2

It can be avoided by adding “volatile” before the union.

Second one in pgf77:

      PROGRAM main
      INTEGER iR,nR
      REAL*8 x,Alpha,R(2,100)
      Alpha=1.322808287195543
      nR=75
      DO iR=1,nR-1
         x       = DBLE(iR)/DBLE(nR)
         R(1,iR) = Alpha * (x/(1.0D0-x))**2
         R(2,iR) = R(1,iR)**2 * 2.0D0 * Alpha * x / (1.0D0-x)**3
         R(2,iR) = R(2,iR) / DBLE(nR)
      END DO
      WRITE(6,*) R(2,30)
      END

which gives:

$ pgf77 a.f ; ./a.out 
   2.2578788536005461E-002

$ pgf77 -O2 a.f ; ./a.out 
    1.693409140200410

This one can be avoided by writing the R(2,iR) assignment in one line:

R(2,iR) = R(1,iR)**2 * 2.0D0 * Alpha * x / (1.0D0-x)**3 / DBLE(nR)

Thanks Ignacio Fdez. Galvan.

The first issue has to do with unrolling of the inner loop. Adding “-Mnounroll” or adding “volatile” to “skip” works around the problem. I reported this issue to engineering as TPR#19560.

The second issue has to do with vectorization. Adding “-Mnovect” works around the error. Reported as TPR#19562.

Best Regards,
Mat

TPRs 19560 and 19562 are fixed in the current 14.1 release.

thanks,
dave