https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570

--- Comment #5 from kargls at comcast dot net ---
(In reply to kargls from comment #4)
> 
> ... here.  If it can be assumed that ieee_next_after, which is
> mapped to nextafter (on x86_64-*-freebsd) is already IEEE-754
> compliant, then the calls to _entry and _exit are redundant 
> so gfortran need not emit them.  That is, 
> 
> subroutine foo(x, y)
>    use ieee_arithmetic
>    real x
>    x = ieee_next_after(x, 10.)
> end subroutine foo
> 
> would be translated to
> 
> __attribute__((fn spec (". w w ")))
> void foo (real(kind=4) & restrict x, real(kind=4) & restrict y)
> {
>   c_char fpstate.0[33];
> 
>   try
>     {
>       // Needed for 1 and 2 above on entry into foo
>       _gfortran_ieee_procedure_entry ((void *) &fpstate.0);
>       {
>          // This is 3 above, i.e., execution of procedure
>          *x = __builtin_nextafterf (*x, 1.0e+1);
>       }
>     }
>   finally
>     {
>       // Needed for 4 and 5 above on exit from foo
>       _gfortran_ieee_procedure_exit ((void *) &fpstate.0);
>     }
> }

Replying to self.

Indeed, it looks like gfortran is being conservative.

% git log -r 3b7ea188c045
Author:     Francois-Xavier Coudert <fxcoud...@gcc.gnu.org>
AuthorDate: Thu Oct 9 09:47:25 2014 +0000
Commit:     François-Xavier Coudert <fxcoud...@gcc.gnu.org>
CommitDate: Thu Oct 9 09:47:25 2014 +0000

% more trans-intrinsic.cc
...
/* Generate code for IEEE_NEXT_AFTER.  */

static void
conv_intrinsic_ieee_next_after (gfc_se * se, gfc_expr * expr)
{
  tree args[2], decl, call, fpstate;
  int argprec;

  conv_ieee_function_args (se, expr, args, 2);

  /* Result has the characteristics of first argument.  */
  args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
  argprec = TYPE_PRECISION (TREE_TYPE (args[0]));
  decl = builtin_decl_for_precision (BUILT_IN_NEXTAFTER, argprec);

  /* Save floating-point state.  */
  fpstate = gfc_save_fp_state (&se->pre);

  /* Make the function call.  */
  call = build_call_expr_loc_array (input_location, decl, 2, args);
  se->expr = fold_convert (TREE_TYPE (args[0]), call);

  /* Restore floating-point state.  */
  gfc_restore_fp_state (&se->post, fpstate);
}

It's been 14 years.  I know I reviewed some FX's patches
for IEEE support, but not all of them.   I do not recall
if we ever discussed whether the saving and restoring
state was necessary.  Looking at FreeBSD's libm implementation
of nextafter shows that everything is done in fix point
integer arithmetic and appropriate exceptions are raised
(if the fpu supports exceptions).  I suspect that we can
remove the save/restore in the above.

Reply via email to