This is a continuation of an interesting tangent in the Poll thread.
Here is a short program that tests whether the compiler (processor) automatically resets the underflow mode upon return from a subprogram.
program ieee
use, intrinsic :: iso_fortran_env, wp=>real32
use, intrinsic :: ieee_arithmetic
implicit none
real(wp) :: x
if ( .not. ieee_support_underflow_control(x) ) then
write(*,*) 'underflow control is not supported for kind(x)=', kind(x)
stop
endif
write(*,*) 'underflow control is supported for kind(x)=', kind(x)
x = tiny(x) * 1.e-5_wp
call print_stuff('default',x)
call toggle_mode()
x = tiny(x) * 1.e-5_wp
call print_stuff('first toggle',x)
call toggle_mode()
x = tiny(x) * 1.e-5_wp
call print_stuff('second toggle',x)
contains
subroutine print_stuff(title,x)
! print ieee info about x.
character(*), intent(in) :: title
real(wp), intent(in) :: x
write(*,*) '==== ', title, ' ===='
write(*,*) 'x=', x
write(*,*) 'ieee_support_datatype(x)=', ieee_support_datatype(x)
write(*,*) 'ieee_support_subnormal(x)=', ieee_support_subnormal(x)
write(*,*) 'subnormal test =', (ieee_class(x) == ieee_positive_subnormal)
return
end subroutine print_stuff
subroutine toggle_mode()
! toggle the underflow mode.
logical :: gradual
call ieee_get_underflow_mode( gradual )
write(*,*) 'toggle: input underflow mode is ', gradual
call ieee_set_underflow_mode( gradual = (.not. gradual) )
call ieee_get_underflow_mode( gradual )
write(*,*) 'toggle: new underflow mode is ', gradual
end subroutine toggle_mode
end program ieee
$ gfortran ieee.f90 && a.out
underflow control is supported for kind(x)= 4
==== default ====
x= 1.17709071E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
toggle: input underflow mode is T
toggle: new underflow mode is F
==== first toggle ====
x= 0.00000000
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = F
toggle: input underflow mode is F
toggle: new underflow mode is T
==== second toggle ====
x= 1.17709071E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
$ flang ieee.f90 && a.out
underflow control is supported for kind(x)= 4
==== default ====
x= 1.18E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
toggle: input underflow mode is F
toggle: new underflow mode is F
==== first toggle ====
x= 1.18E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
toggle: input underflow mode is F
toggle: new underflow mode is F
==== second toggle ====
x= 1.18E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
$ nagfor ieee.f90 && a.out
NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7203
[NAG Fortran Compiler normal termination]
underflow control is supported for kind(x)= 1
==== default ====
x= 1.1770907E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
toggle: input underflow mode is T
toggle: new underflow mode is F
==== first toggle ====
x= 1.1770907E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
toggle: input underflow mode is T
toggle: new underflow mode is F
==== second toggle ====
x= 1.1770907E-43
ieee_support_datatype(x)= T
ieee_support_subnormal(x)= T
subnormal test = T
This is on MacOS with arm64 hardware. Gfortran behaves as I had expected. Namely, the programmer can reset the underflow mode in a subroutine, and that reset sticks after return for the rest of the program. Is this standard conforming behavior?
Flang for some reason does not allow the underflow mode to be changed, despite saying that it can be changed with the ieee_support_underflow_control(x) function. The result of ieee_get_underflow_mode() seems to be incorrect. Otherwise, the other ieee tests on the value seem to work correctly. Maybe I’m doing something wrong in the toggle_mode() subroutine? BTW, flang also prints some run time warning messages about the underflows to stderr, which I did not include in the above output.
The NAG fortran compiler does seem to reset the underflow mode upon return from toggle_mode(). If you move the ieee_set_underflow_mode() call to the main program instead of the subroutine, then the mode toggles as expected. This is the opposite of my expectations. On the downside however, when you do that the subnormal test prints T when the argument is 0.0, so I don’t think that part is right. However, I’m still unsure if I’m doing that test correctly.