https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570
kargls at comcast dot net changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |kargls at comcast dot net
--- Comment #2 from kargls at comcast dot net ---
Unfortunately, gfortran must adhere to the requirements
of the Fortran standard.
Fortran 2023, page 467
If a flag is signaling on entry to a procedure other than
IEEE_GET_FLAG or IEEE_GET_STATUS, the processor will set
it to quiet on entry and restore it to signaling on return.
If a flag signals during execution of a procedure, the
processor shall not set it to quiet on return.
Consider,
program foo
real, parameter :: z = nearest(tiny(1.), -1.)
real x, y
x = 4 * z
call bar(x)
y = 4 * z
call bah(y)
if (y /= x) stop 1
contains
subroutine bar(x)
x = 1.234 * x
x = nearest(x, -1.) / 2
end subroutine bar
subroutine bah(y)
use ieee_arithmetic
y = 1.234 * y
y = ieee_next_after(y, -1.) / 2
end subroutine bah
end program foo
Compile with the -fdump-tree-original options allows one
to examine the initial internal representation of the code.
% gfcx -o z a.f90 -fdump-tree-original
For subroutine bar(), one observes
__attribute__((fn spec (". w ")))
void bar (real(kind=4) & restrict x)
{
*x = *x * 1.2339999675750732421875e+0;
*x = __builtin_nextafterf (*x, -Inf) / 2.0e+0;
}
IOW, gfortran does not case about IEEE-754 semantics. Now
let's look at subroutine bah() with comments inserted.
__attribute__((fn spec (". w ")))
void bah (real(kind=4) & restrict y)
{
c_char fpstate.0[33];
try
{
_gfortran_ieee_procedure_entry ((void *) &fpstate.0);
The above saves FPU state on entry into bah() and sets
the state to quiet for all flags.
*y = *y * 1.2339999675750732421875e+0;
The above is a FP operation that might alter FPU state.
{
c_char fpstate.1[33];
_gfortran_ieee_procedure_entry ((void *) &fpstate.1);
The above saves FPU state on entry into ieee_next_after()
and sets the state to quiet for all flags.
*y = __builtin_nextafterf (*y, -1.0e+0) / 2.0e+0;
The above may alter FPU state.
_gfortran_ieee_procedure_exit ((void *) &fpstate.1);
The above restores FPU state to that prior to the
ieee_next_after() call while preserving any state
change do to the previous expression.
}
}
finally
{
_gfortran_ieee_procedure_exit ((void *) &fpstate.0);
The above restores FPU to that on entry into bah() while
preserving any state change that occurred during the
execution of bah().
}
}