This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: compiling refblas3 with gfortran 4.2
- From: Bart Oldeman <bartoldeman at users dot sourceforge dot net>
- To: fortran at gcc dot gnu dot org
- Cc: burnus at net-b dot de, kamaraju at bluebottle dot com, camm at enhanced dot com
- Date: Fri, 27 Jul 2007 12:20:18 +1200 (NZST)
- Subject: Re: compiling refblas3 with gfortran 4.2
Hi,
the problems with izamax come from the excess precision on the x87 FPU
stack. Essentially the code tries to find the absolute maximum of the
complex numbers 0.4+0.1i and 0.1+0.4i, where the norm is defined as the
sum of the absolute values of the imaginary and the real parts.
There was an attempt by Debian to work around the issue before:
double precision volatile dcabs1
This does not work: VOLATILE wasn't in the F77 standard.
Moreover, the above is interpreted as
double precision volatiledcabs1
This, due to implicit typing, causes dcabs1 to be real (single precision)
which is simply wrong!
Volatile is in F2003 and gfortran-4.3, but the syntax is different. It
also won't help (ie. 'double precision, volatile :: dcabs1').
Compiling izamax.f using -ffloat-store solves the test case failures.
The below patch also "works" (I use quotes because it's never going to be
very robust across different compilers and CPUs), because a statement
function is inlined so the excess precision is not lost and the
comparisons work as you'd expect.
--- src/izamax.f~ 2007-07-27 02:09:33.000000000 +1200
+++ src/izamax.f 2007-07-27 12:03:35.000000000 +1200
@@ -8,7 +8,9 @@
double complex zx(*)
double precision smax
integer i,incx,ix,n
- double precision volatile dcabs1
+ double complex zdum
+ double precision dcabs1
+ dcabs1(zdum) = abs(real(zdum)) + abs(aimag(zdum))
c
izamax = 0
if( n.lt.1 .or. incx.le.0 )return