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().

    }
}

Reply via email to