On Fri, Dec 21, 2018 at 07:39:45PM +0000, Joseph Myers wrote:
> On Fri, 21 Dec 2018, Steve Kargl wrote:
> 
> > scalbln(double x, long n)
> > {
> > 
> >         return (scalbn(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n));
> > }
> > 
> > A search for glibc's libm locates https://tinyurl.com/ybcy8w4t
> > which is a bit-twiddling routine.  Not sure it's worth the
> > effort.  Joseph Myers might have an opinion.
> 
> Such comparisons are needed in the scalbn / scalbln implementations anyway 
> to deal with large exponents.  I suppose where there's a suitable scalbln 
> implementation, and you don't know if the arguments are within the range 
> of int, calling scalbln at least saves code size in the caller and avoids 
> duplicating those range checks.
> 

I was thinking along the lines of -ffast-math and whether 
__builtin_scalbn and __builtin_scalbln are then inlined.  
The comparisons may inhibit inlining __builtin_scalbn;
while, if gfortran used __builtin_scalbln, inlining would
occur.

As it is, for

   function foo(x,i)
     use ieee_arithmetic
     real(8) foo, c
     integer(8) i
     foo = ieee_scalb(c, i)
   end function foo

the options -ffast-math -O3 -fdump-tree-optimized give

  <bb 2> [local count: 1073741824]:
  _gfortran_ieee_procedure_entry (&fpstate.0);
  _8 = *i_7(D);
  _1 = MIN_EXPR <_8, 2147483647>;
  _2 = MAX_EXPR <_1, -2147483647>;
  _3 = (integer(kind=4)) _2;
  _4 = __builtin_scalbn (c_9(D), _3);
  _gfortran_ieee_procedure_exit (&fpstate.0);
  fpstate.0 ={v} {CLOBBER};
  return _4;

It seems this could be 

  <bb 2> [local count: 1073741824]:
  _gfortran_ieee_procedure_entry (&fpstate.0);
  _3 = (integer(kind=4)) *i_7(D);
  _4 = __builtin_scalbn (c_9(D), _3);
  _gfortran_ieee_procedure_exit (&fpstate.0);
  fpstate.0 ={v} {CLOBBER};

-- 
Steve

Reply via email to