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

Reply via email to