gfortran does constant folding so aggressively that one has to be
careful when testing it. I have seen several instances lately
where it yields the correct answer if its constant folding
mechanism can come into play, but will be tripped up if not.
Another case in point:
C:\gfortran\james\cmplx>type test0.f90
module mykinds
implicit none
integer, parameter :: sp = selected_real_kind(6,37)
integer, parameter :: dp = selected_real_kind(15,307)
integer, parameter :: ep = selected_real_kind(18,4931)
integer, parameter :: qp_preferred = selected_real_kind(33,4931)
integer, parameter :: qp = (1+sign(1,qp_preferred))/2*qp_preferred+ &
(1-sign(1,qp_preferred))/2*ep
end module mykinds
subroutine sub(x1) ! constant folding permitted
!subroutine sub(x) ! constant folding forbidden
use mykinds
implicit none
integer x1 ! constant folding permitted
integer, parameter :: x = 1 ! constant folding permitted
! integer x ! constant folding forbidden
call xfinit
write(*,*) real(b'01000000001010010101001111111101',sp)
write(*,*) real(o'10012251775',sp)
write(*,*) real(z'402953FD',sp)
write(*,*) real(b'010000000000010100101010011111111010100&
&1110100101111100011101010',dp)
write(*,*) real(o'0400051247765164574352',dp)
write(*,*) real(z'40052A7FA9D2F8EA',dp)
write(*,*) real(b'010000000000000010101001010100111111110&
&10100111010010111110001110100110110111100',qp)
write(*,*) real(o'100001245237724722761646674',qp)
write(*,*) real(z'4000A953FD4E97C74DBC',qp)
write(*,*) cmplx(b'01000000001010010101001111111101',KIND=sp)
write(*,*) cmplx(o'10012251775',KIND=sp)
write(*,*) cmplx(z'402953FD',KIND=sp)
write(*,*) cmplx(b'01000000000001010010101001111111101010&
&01110100101111100011101010',KIND=dp)
write(*,*) cmplx(o'0400051247765164574352',KIND=dp)
write(*,*) cmplx(z'40052A7FA9D2F8EA',KIND=dp)
write(*,*) cmplx(b'01000000000000001010100101010011111111&
&010100111010010111110001110100110110111100',KIND=qp)
write(*,*) cmplx(o'100001245237724722761646674',KIND=qp)
write(*,*) cmplx(z'4000A953FD4E97C74DBC',KIND=qp)
write(*,*) cmplx(b'01000000001010010101001111111101',x,sp)
write(*,*) cmplx(o'10012251775',x,sp)
write(*,*) cmplx(z'402953FD',x,sp)
write(*,*) cmplx(b'01000000000001010010101001111111101010&
&01110100101111100011101010',x,dp)
write(*,*) cmplx(o'0400051247765164574352',x,dp)
write(*,*) cmplx(z'40052A7FA9D2F8EA',x,dp)
write(*,*) cmplx(b'01000000000000001010100101010011111111&
&010100111010010111110001110100110110111100',x,qp)
write(*,*) cmplx(o'100001245237724722761646674',x,qp)
write(*,*) cmplx(z'4000A953FD4E97C74DBC',x,qp)
write(*,*) cmplx(x,b'01000000001010010101001111111101',sp)
write(*,*) cmplx(x,o'10012251775',sp)
write(*,*) cmplx(x,z'402953FD',sp)
write(*,*) cmplx(x,b'0100000000000101001010100111111110101&
&001110100101111100011101010',dp)
write(*,*) cmplx(x,o'0400051247765164574352',dp)
write(*,*) cmplx(x,z'40052A7FA9D2F8EA',dp)
write(*,*) cmplx(x,b'0100000000000000101010010101001111111&
&1010100111010010111110001110100110110111100',qp)
write(*,*) cmplx(x,o'100001245237724722761646674',qp)
write(*,*) cmplx(x,z'4000A953FD4E97C74DBC',qp)
end subroutine sub
program test0
implicit none
integer x
x = 1
call sub(x)
end program test0
C:\gfortran\james\cmplx>gfortran test0.f90 finit.s -otest0
C:\gfortran\james\cmplx>test0
2.6457512
2.6457512
2.6457512
2.6457513110645907
2.6457513110645907
2.6457513110645907
2.6457513110645905904
2.6457513110645905904
2.6457513110645905904
( 2.6457512 , 0.0000000 )
( 2.6457512 , 0.0000000 )
( 2.6457512 , 0.0000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 2.6457512 , 1.00000000 )
( 2.6457512 , 1.00000000 )
( 2.6457512 , 1.00000000 )
( 2.6457513110645907 , 1.00000000000000000 )
( 2.6457513110645907 , 1.00000000000000000 )
( 2.6457513110645907 , 1.00000000000000000 )
( 2.6457513110645905904 , 1.00000000000000000000 )
( 2.6457513110645905904 , 1.00000000000000000000 )
( 2.6457513110645905904 , 1.00000000000000000000 )
( 1.00000000 , 2.6457512 )
( 1.00000000 , 2.6457512 )
( 1.00000000 , 2.6457512 )
( 1.00000000000000000 , 2.6457513110645907 )
( 1.00000000000000000 , 2.6457513110645907 )
( 1.00000000000000000 , 2.6457513110645907 )
( 1.00000000000000000000 , 2.6457513110645905904 )
( 1.00000000000000000000 , 2.6457513110645905904 )
( 1.00000000000000000000 , 2.6457513110645905904 )
So all is well, right? But if we comment out the lines that
say 'constant folding permitted' and uncomment the lines that
say 'constant folding forbidden', as in:
!subroutine sub(x1) ! constant folding permitted
subroutine sub(x) ! constant folding forbidden
use mykinds
implicit none
! integer x1 ! constant folding permitted
! integer, parameter :: x = 1 ! constant folding permitted
integer x ! constant folding forbidden
C:\gfortran\james\cmplx>gfortran test0.f90 finit.s -otest0
C:\gfortran\james\cmplx>test0
2.6457512
2.6457512
2.6457512
2.6457513110645907
2.6457513110645907
2.6457513110645907
2.6457513110645905904
2.6457513110645905904
2.6457513110645905904
( 2.6457512 , 0.0000000 )
( 2.6457512 , 0.0000000 )
( 2.6457512 , 0.0000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645907 , 0.0000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 2.6457513110645905904 , 0.0000000000000000000 )
( 1.07645030E+09, 1.00000000 )
( 1.07645030E+09, 1.00000000 )
( 1.07645030E+09, 1.00000000 )
( 4.61314012110932990E+018, 1.00000000000000000 )
( 4.61314012110932990E+018, 1.00000000000000000 )
( 4.61314012110932990E+018, 1.00000000000000000 )
( 3.02243656277986766270E+0023, 1.00000000000000000000 )
( 3.02243656277986766270E+0023, 1.00000000000000000000 )
( 3.02243656277986766270E+0023, 1.00000000000000000000 )
( 1.00000000 , 1.07645030E+09)
( 1.00000000 , 1.07645030E+09)
( 1.00000000 , 1.07645030E+09)
( 1.00000000000000000 , 4.61314012110932990E+018)
( 1.00000000000000000 , 4.61314012110932990E+018)
( 1.00000000000000000 , 4.61314012110932990E+018)
( 1.00000000000000000000 , 3.02243656277986766270E+0023)
( 1.00000000000000000000 , 3.02243656277986766270E+0023)
( 1.00000000000000000000 , 3.02243656277986766270E+0023)
We see that gfortran in this case has treated the BOZ literals as
integers and then converted the integers to reals. This incorrect
behavior can only be seen when gfortran can't do constant folding.
CMPLX has so many effective specific functions that you just knew
you could trip it up somewhere!
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


|