I am using GCC 4.3.2, but I tested this also with 4.3.4, 4.4.1, 4.4-latest and
4.5-latest. Most of the are compiled with "../configure --prefix=MYPREFIX
--enable-language=fortran"
>From Fortran docs: "If a variable is volatile, the processor is expected to
fetch the value from memory every time that the variable is referenced, even if
a value was previously fetched and there is no evident way for the value to
have changed in the interim."
In other words, variable should be stored and fetched every time it is
referenced. I am working on a "double precision, volatile :: x" and do not
understand, why GCC optimises it, when it should not. (I've seen most reported
bug #323, thanks). Simple code illustrating the problem:
=================================
file <test.F95> compiled with <gfortran -std=f2003 -O2 test.F95 -o test-F95>:
---------------------------------
program VolatileTest
double precision :: uA, uB
double precision, volatile :: a
double precision :: b
double precision :: c
! Enter 0.1 two times
read(*,*) uA, uB
a = uA*uA
b = uB*uB
c = a-b
! Nonzero value is correct
print *,c
end
=================================
file <test.F> compiled with <gfortran -std=f2003 -O2 test.F -o test-F>:
---------------------------------
PROGRAM VolatileTest
double precision :: uA, uB
volatile double precision a
double precision :: b
double precision :: c
C Enter 0.1 two times
READ(*,*) uA, uB
a = uA*uA
b = uB*uB
c = a-b
C Nonzero value is correct
PRINT *,c
END
=================================
If I compile test.F95, no effect of volatile is seen. Variable "a" is
optimised:
---------------------------------
0x08048715 <MAIN__+181>: fld QWORD PTR [ebp-0x18] # var a
0x08048718 <MAIN__+184>: fmul st,st(0) # a*a
0x0804871a <MAIN__+186>: fld QWORD PTR [ebp-0x20] # var b
0x0804871d <MAIN__+189>: fmul st,st(0) # b*b
0x0804871f <MAIN__+191>: fsubrp st(1),st # a-b
0x08048721 <MAIN__+193>: fstp QWORD PTR [ebp-0x10] # c = a-b
0x08048724 <MAIN__+196>: call 0x8048538 <_gfortran_st_wr...@plt>
---------------------------------
If I compile test.F, volatile variable is not optimised. This is what I expect:
---------------------------------
0x08048715 <MAIN__+181>: fld QWORD PTR [ebp-0x18] # a
0x08048718 <MAIN__+184>: fld QWORD PTR [ebp-0x20] # b
0x0804871b <MAIN__+187>: fxch st(1) # swap
0x0804871d <MAIN__+189>: fmul st,st(0) # a*a
0x0804871f <MAIN__+191>: fstp DWORD PTR [ebp-0x13c] # store a
0x08048725 <MAIN__+197>: fld DWORD PTR [ebp-0x13c] # fetch a (correct
!!!)
0x0804872b <MAIN__+203>: fxch st(1) # swap
0x0804872d <MAIN__+205>: fmul st,st(0) # b*b
0x0804872f <MAIN__+207>: fsubrp st(1),st # a-b
0x08048731 <MAIN__+209>: fstp QWORD PTR [ebp-0x10] # c = a-b
0x08048734 <MAIN__+212>: call 0x8048538 <_gfortran_st_wr...@plt>
---------------------------------
Also if in test.F I replace "volatile double precision a" with "double
precision, volatile :: a" I start getting incorrect result and "volatile"
attribute is discarded.
So is this a bug or a feature?
Denis
--
Summary: VOLATILE in Fortran does not take effect
Product: gcc
Version: 4.3.4
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libfortran
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: denis_scherbakov at yahoo dot com
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41335