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