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)