public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Improving math function wrappers
       [not found] <AM5PR0802MB2610AA7EDC518B39F6D7152683260@AM5PR0802MB2610.eurprd08.prod.outlook.com>
@ 2017-03-16 13:53 ` Wilco Dijkstra
  2017-03-16 14:39   ` Joseph Myers
  2017-03-16 21:22   ` Florian Weimer
  0 siblings, 2 replies; 12+ messages in thread
From: Wilco Dijkstra @ 2017-03-16 13:53 UTC (permalink / raw)
  To: Szabolcs Nagy, Joseph Myers, libc-alpha; +Cc: nd

Hi,

When looking at profiles of various benchmarks that use math functions, I noticed
that the wrappers that set errno have a significant overhead. This is particularly
noticeable when the wrapper tests the return value of the math function - this requires
the input operand(s) to be saved, creating a stack frame and several callee-saves.

While the wrappers may be bypassed when building with -Ofast, this uses C header
magic (ie. it doesn't work in languages other than C and C++). Given other languages
don't even have the concept of errno, C99 doesn't require it, and no application ever
reads errno, it is inefficient to force the use of the wrappers in almost all cases.

One way of improving this would be to reverse the current logic and default to the
unwrapped IEEE functions. The errno wrapper would then only be selected when the 
standard requires it (C89), on old (obsolete?) UNIX variants that assume errno is
always set, or if the user explicitly requests it.

Another possibility would be to merge the wrappers into their respective math functions.
This is feasible since the IEEE versions must check for the same exceptional cases
anyway. While this would increase complexity of math functions, it shouldn't affect the
critical path for the common cases. However it would mean errno is sometimes set
when it otherwise wouldn't be (with Ofast or when an IEEE math function is called
internally). Also on some odd systems it might even result in extra messages being
printed by __kernel_standard (can we obsolete that???).

What do you think?

Wilco    

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 13:53 ` Improving math function wrappers Wilco Dijkstra
@ 2017-03-16 14:39   ` Joseph Myers
  2017-03-16 14:41     ` Joseph Myers
  2017-03-16 18:07     ` Szabolcs Nagy
  2017-03-16 21:22   ` Florian Weimer
  1 sibling, 2 replies; 12+ messages in thread
From: Joseph Myers @ 2017-03-16 14:39 UTC (permalink / raw)
  To: Wilco Dijkstra; +Cc: Szabolcs Nagy, libc-alpha, nd

On Thu, 16 Mar 2017, Wilco Dijkstra wrote:

> Given other languages don't even have the concept of errno, C99 doesn't 
> require it, and no application ever reads errno, it is inefficient to 
> force the use of the wrappers in almost all cases.

C99 not requiring it was an incompatible quiet change from C90.

> Another possibility would be to merge the wrappers into their respective 
> math functions. This is feasible since the IEEE versions must check for 
> the same exceptional cases anyway. While this would increase complexity 
> of math functions, it shouldn't affect the critical path for the common 
> cases. However it would mean errno is sometimes set when it otherwise 
> wouldn't be (with Ofast or when an IEEE math function is called 
> internally). Also on some odd systems it might even result in extra 
> messages being printed by __kernel_standard (can we obsolete that???).

My view is that merging errno-setting into the main implementations of the 
various functions is reasonable - but it also involves a significant 
amount of architecture-specific work where architecture-specific 
implementations of those functions are involved, and it's quite likely the 
code to set the TLS errno might vary depending on PIC versus non-PIC, with 
the non-PIC case then not being well-tested.  The case for it is a lot 
more straightforward where there aren't any assembly implementations for 
particular architectures.  Adding *_noerrno exports for selected 
functions, based on performance evidence, would also be reasonable (GCC 5 
and above define __NO_MATH_ERRNO__ for -fno-math-errno, which can be used 
to select such variants; of course for non-C-family languages the compiler 
would need to know about such function variants).

(There may be cases where errno setting in the main implementations will 
require adding checks there not currently present, if e.g. the function 
does "return x - x;" in the non-finite argument case to return NaN and 
also raise "invalid" for Inf arguments - but such cases should not 
generally be significant for performance; the performance relevant cases 
are those involving finite arguments and results, not error cases or NaNs 
as arguments.)

As for __kernel_standard obsoletion, there are several useful steps that 
can be done towards that:

* We now have the new wrappers that avoid checking _LIB_VERSION or calling 
__kernel_standard, used for float128 to avoid matherr / _LIB_VERSION 
support ever being part of the ABI for new types.

* The next step would be to make _LIB_VERSION, matherr and the ia64 
variants matherrf, matherrl into compat symbols, so that new programs 
cannot use that functionality.  Documentation for matherr error handling 
would be removed.  libieee.a would no longer be installed.  Something 
would need to be done about the test for matherr support.  Things would be 
arranged so that new architectures no longer get exported symbols (even 
compat symbols) for _LIB_VERSION or matherr (although some related code 
might still be present internally).

* The next step after that would be to ensure that the new wrappers are 
used in static libm, and in shared libm when the minimum symbol version 
postdates the making of _LIB_VERSION into a compat symbol.  New 
architectures, and static libm would no longer have any __kernel_standard 
code or code related to _LIB_VERSION / matherr.

* An optional step would be to use the new wrappers also on existing 
architectures as new symbol versions for existing symbols that have 
_LIB_VERSION / matherr support at their old symbol versions.

* If a function is changed to set errno directly in all its 
implementations, so it no longer needs a wrapper except for legacy 
_LIB_VERSION / matherr support, of course in the above for "new wrappers" 
you can read "direct export of the main implementation without a wrapper" 
(and the compat symbols for _LIB_VERSION / matherr support would just end 
up setting errno redundantly in both the main implementation and the 
wrapper).

* Given the different structure of ia64 libm, it seems plausible that 
while the making into compat symbols of _LIB_VERSION etc. should be done 
globally (to keep the API exported the same everywhere), some of the 
subsequent steps might only be applied to non-ia64 architectures.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 14:39   ` Joseph Myers
@ 2017-03-16 14:41     ` Joseph Myers
  2017-03-16 18:07     ` Szabolcs Nagy
  1 sibling, 0 replies; 12+ messages in thread
From: Joseph Myers @ 2017-03-16 14:41 UTC (permalink / raw)
  To: Wilco Dijkstra; +Cc: Szabolcs Nagy, libc-alpha, nd

On Thu, 16 Mar 2017, Joseph Myers wrote:

> * The next step after that would be to ensure that the new wrappers are 
> used in static libm, and in shared libm when the minimum symbol version 
> postdates the making of _LIB_VERSION into a compat symbol.  New 
> architectures, and static libm would no longer have any __kernel_standard 
> code or code related to _LIB_VERSION / matherr.

Also note care would be needed about testing at this point, as you'd then 
have significantly different code used in static libm (not well tested) 
from shared libm.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 14:39   ` Joseph Myers
  2017-03-16 14:41     ` Joseph Myers
@ 2017-03-16 18:07     ` Szabolcs Nagy
  2017-03-16 18:24       ` Joseph Myers
  1 sibling, 1 reply; 12+ messages in thread
From: Szabolcs Nagy @ 2017-03-16 18:07 UTC (permalink / raw)
  To: Joseph Myers, Wilco Dijkstra; +Cc: nd, libc-alpha

On 16/03/17 14:29, Joseph Myers wrote:
> On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
> 
>> Given other languages don't even have the concept of errno, C99 doesn't 
>> require it, and no application ever reads errno, it is inefficient to 
>> force the use of the wrappers in almost all cases.
> 
> C99 not requiring it was an incompatible quiet change from C90.
> 

i think glibc only has to set errno when user code is
compiled with c89 compatibility and even then only for
math functions that were defined in c89 and then only
guarantee correct errno setting in default rounding mode
(c89 code cannot access the fenv).

aiming for more math errno support has little use since
it is a non-portable and thus obsolete feature.

i think gcc should do this too: sqrt(x) should be
inlined as a single instruction by default, instead of
calling libc just in case it may want to set errno
(i.e. -std=c99 and -std=c11 can and thus should imply
-fno-math-errno). i saw various targets wanting this,
but it would be better to do this in general.
https://gcc.gnu.org/ml/gcc/2011-02/msg00095.html

>> Another possibility would be to merge the wrappers into their respective 
>> math functions. This is feasible since the IEEE versions must check for 
>> the same exceptional cases anyway. While this would increase complexity 
>> of math functions, it shouldn't affect the critical path for the common 
>> cases. However it would mean errno is sometimes set when it otherwise 
>> wouldn't be (with Ofast or when an IEEE math function is called 
>> internally). Also on some odd systems it might even result in extra 
>> messages being printed by __kernel_standard (can we obsolete that???).
> 
> My view is that merging errno-setting into the main implementations of the 
> various functions is reasonable - but it also involves a significant 
> amount of architecture-specific work where architecture-specific 
> implementations of those functions are involved, and it's quite likely the 
> code to set the TLS errno might vary depending on PIC versus non-PIC, with 
> the non-PIC case then not being well-tested.  The case for it is a lot 
> more straightforward where there aren't any assembly implementations for 
> particular architectures.  Adding *_noerrno exports for selected 
> functions, based on performance evidence, would also be reasonable (GCC 5 
> and above define __NO_MATH_ERRNO__ for -fno-math-errno, which can be used 
> to select such variants; of course for non-C-family languages the compiler 
> would need to know about such function variants).
> 
> (There may be cases where errno setting in the main implementations will 
> require adding checks there not currently present, if e.g. the function 
> does "return x - x;" in the non-finite argument case to return NaN and 
> also raise "invalid" for Inf arguments - but such cases should not 
> generally be significant for performance; the performance relevant cases 
> are those involving finite arguments and results, not error cases or NaNs 
> as arguments.)
> 

i don't think setting errno in asm would be necessary,
just turn "return x-x;" into "return specialcase1(x);"
where specialcase1 is generic c code shared by targets,
these are only called in cold code paths (if the errno
setting is in a hot path then wrapper vs no wrapper
does not make much difference and a wrapper can always
be in c)

one issue is that underflow/overflow thresholds can depend
on the rounding mode if errno is set based on inputs (instead
of based on the result in a wrapper), but i think errno
can be set spuriously in general so it should be possible
to choose one threshold covering all rounding modes or
alternatively only supporting errno in default rounding mode.

i think we need to decide to either (1) make it easy (default)
to call math functions without errno wrapper or (2) always
set errno, but optimize it so it does not affect performance
for common inputs (by merging the wrapper into the math code).

> As for __kernel_standard obsoletion, there are several useful steps that 
> can be done towards that:
> 
> * We now have the new wrappers that avoid checking _LIB_VERSION or calling 
> __kernel_standard, used for float128 to avoid matherr / _LIB_VERSION 
> support ever being part of the ABI for new types.
> 
> * The next step would be to make _LIB_VERSION, matherr and the ia64 
> variants matherrf, matherrl into compat symbols, so that new programs 
> cannot use that functionality.  Documentation for matherr error handling 
> would be removed.  libieee.a would no longer be installed.  Something 
> would need to be done about the test for matherr support.  Things would be 
> arranged so that new architectures no longer get exported symbols (even 
> compat symbols) for _LIB_VERSION or matherr (although some related code 
> might still be present internally).
> 
> * The next step after that would be to ensure that the new wrappers are 
> used in static libm, and in shared libm when the minimum symbol version 
> postdates the making of _LIB_VERSION into a compat symbol.  New 
> architectures, and static libm would no longer have any __kernel_standard 
> code or code related to _LIB_VERSION / matherr.
> 
> * An optional step would be to use the new wrappers also on existing 
> architectures as new symbol versions for existing symbols that have 
> _LIB_VERSION / matherr support at their old symbol versions.
> 
> * If a function is changed to set errno directly in all its 
> implementations, so it no longer needs a wrapper except for legacy 
> _LIB_VERSION / matherr support, of course in the above for "new wrappers" 
> you can read "direct export of the main implementation without a wrapper" 
> (and the compat symbols for _LIB_VERSION / matherr support would just end 
> up setting errno redundantly in both the main implementation and the 
> wrapper).
> 
> * Given the different structure of ia64 libm, it seems plausible that 
> while the making into compat symbols of _LIB_VERSION etc. should be done 
> globally (to keep the API exported the same everywhere), some of the 
> subsequent steps might only be applied to non-ia64 architectures.
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 18:07     ` Szabolcs Nagy
@ 2017-03-16 18:24       ` Joseph Myers
  2017-04-04 17:25         ` Szabolcs Nagy
  2017-04-04 17:41         ` Zack Weinberg
  0 siblings, 2 replies; 12+ messages in thread
From: Joseph Myers @ 2017-03-16 18:24 UTC (permalink / raw)
  To: Szabolcs Nagy; +Cc: Wilco Dijkstra, nd, libc-alpha

On Thu, 16 Mar 2017, Szabolcs Nagy wrote:

> On 16/03/17 14:29, Joseph Myers wrote:
> > On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
> > 
> >> Given other languages don't even have the concept of errno, C99 doesn't 
> >> require it, and no application ever reads errno, it is inefficient to 
> >> force the use of the wrappers in almost all cases.
> > 
> > C99 not requiring it was an incompatible quiet change from C90.
> 
> i think glibc only has to set errno when user code is
> compiled with c89 compatibility and even then only for
> math functions that were defined in c89 and then only
> guarantee correct errno setting in default rounding mode
> (c89 code cannot access the fenv).

Incompatible quiet change means a good idea to implement the compatible 
mode ((math_errhandling & MATH_ERRNO) != 0) as far as possible.  Just like 
it's a good idea to avoid size_t wider than unsigned long.

Compilers for non-C languages without the concept of these functions 
setting errno can of course default to -fno-math-errno by default (and 
built-in no-errno functions that can be used with -fmath-errno is 
otherwise enabled would also be desirable for fma, sqrt, etc.).

> > (There may be cases where errno setting in the main implementations will 
> > require adding checks there not currently present, if e.g. the function 
> > does "return x - x;" in the non-finite argument case to return NaN and 
> > also raise "invalid" for Inf arguments - but such cases should not 
> > generally be significant for performance; the performance relevant cases 
> > are those involving finite arguments and results, not error cases or NaNs 
> > as arguments.)
> 
> i don't think setting errno in asm would be necessary,
> just turn "return x-x;" into "return specialcase1(x);"
> where specialcase1 is generic c code shared by targets,
> these are only called in cold code paths (if the errno
> setting is in a hot path then wrapper vs no wrapper
> does not make much difference and a wrapper can always
> be in c)

Whether the asm code calls a special-case function or __errno_location or 
sets TLS errno directly doesn't make much difference, you still need lots 
of target-specific checks for NaNs / overflow etc.  (Some cases may 
already be inside cold paths, some, e.g. overflow / underflow where the 
exception is implicit from the calculation but errno needs an extra check, 
may not, although the value to check should at least already be in a 
register.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 13:53 ` Improving math function wrappers Wilco Dijkstra
  2017-03-16 14:39   ` Joseph Myers
@ 2017-03-16 21:22   ` Florian Weimer
  2017-03-16 21:36     ` Joseph Myers
  1 sibling, 1 reply; 12+ messages in thread
From: Florian Weimer @ 2017-03-16 21:22 UTC (permalink / raw)
  To: Wilco Dijkstra, Szabolcs Nagy, Joseph Myers, libc-alpha; +Cc: nd

On 03/16/2017 02:52 PM, Wilco Dijkstra wrote:
> While the wrappers may be bypassed when building with -Ofast, this uses C header
> magic (ie. it doesn't work in languages other than C and C++). Given other languages
> don't even have the concept of errno, C99 doesn't require it, and no application ever
> reads errno, it is inefficient to force the use of the wrappers in almost all cases.

What's the expensive part?  Computing what errno value to set, or 
obtaining the location of errno?

We have recently removed the PID cache from the TCB.  We could store the 
errno value there, instead of going through __errno_location.  (Code 
outside glibc would still use __errno_location, of course.)

Florian

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 21:22   ` Florian Weimer
@ 2017-03-16 21:36     ` Joseph Myers
  2017-03-16 22:49       ` Wilco Dijkstra
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph Myers @ 2017-03-16 21:36 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Wilco Dijkstra, Szabolcs Nagy, libc-alpha, nd

On Thu, 16 Mar 2017, Florian Weimer wrote:

> We have recently removed the PID cache from the TCB.  We could store the errno
> value there, instead of going through __errno_location.  (Code outside glibc
> would still use __errno_location, of course.)

Code in glibc's libraries should already be setting the TLS initial-exec 
errno variable directly (that's how __set_errno is defined in 
include/errno.h).  But any case that sets errno should not be 
performance-critical; the issue is the effects on performance of non-error 
cases with finite arguments (which should just be checking if the result 
is non-finite or zero, depending on the function - but the issue raised 
here was consequent need to save the arguments for subsequent checks in 
the unlikely case to see whether e.g. a NaN result was an error or from a 
NaN argument, and it's possible the code in the error case might have 
other prologue/epilogue effects that don't get shrink-wrapped away).

Most of the time the checks either duplicate ones already present in the 
main function implementation, or could be localized to an unlikely case 
within that implementation, hence the notion that setting errno in the 
main function implementation makes sense (along with avoiding extra stack 
frame setup etc.).

If we set errno in some main function implementations I think we should be 
clear that adding a wrapper is still a fine way to fix one of the 
remaining bugs about missing errno setting in cases where 
architecture-specific implementations are involved, with the option of 
optimizing later by moving away from that wrapper.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 21:36     ` Joseph Myers
@ 2017-03-16 22:49       ` Wilco Dijkstra
  0 siblings, 0 replies; 12+ messages in thread
From: Wilco Dijkstra @ 2017-03-16 22:49 UTC (permalink / raw)
  To: Joseph Myers, Florian Weimer; +Cc: Szabolcs Nagy, libc-alpha, nd

Joseph Myers <joseph@codesourcery.com> wrote:

> Code in glibc's libraries should already be setting the TLS initial-exec 
> errno variable directly (that's how __set_errno is defined in 
> include/errno.h).  But any case that sets errno should not be 
> performance-critical; the issue is the effects on performance of non-error 
> cases with finite arguments (which should just be checking if the result 
> is non-finite or zero, depending on the function - but the issue raised 
> here was consequent need to save the arguments for subsequent checks in 
> the unlikely case to see whether e.g. a NaN result was an error or from a 
> NaN argument, and it's possible the code in the error case might have 
> other prologue/epilogue effects that don't get shrink-wrapped away).

Setting errno is not in any way performance critical indeed - even a function
call would be fast enough. It is cases like this that show up as having a high
overhead:

double
__pow (double x, double y)
{
  double z = __ieee754_pow (x, y);
  if (__glibc_unlikely (!isfinite (z)))
     ...
  else if (__builtin_expect (z == 0.0, 0)
	   && isfinite (x) && x != 0 && isfinite (y)
	   && _LIB_VERSION != _IEEE_)
     ...

This means saving and restoring x and y across the call (ie. setting up a stack
frame with 3-4 callee-saves) and 2 if statements on the critical path - all
completely unnecessary.

Inlining __ieee754_pow would help but still keep the extra checks - so moving
them into existing checks for special cases is best if we can't remove errno support.

> If we set errno in some main function implementations I think we should be 
> clear that adding a wrapper is still a fine way to fix one of the 
> remaining bugs about missing errno setting in cases where 
> architecture-specific implementations are involved, with the option of 
> optimizing later by moving away from that wrapper.

Yes, we'd still have to keep the wrapper if there are any targets that require it.
It could be removed once such code has been updated or if the generic
implementation ends up faster (quite likely given this happened for several string
functions)...

Wilco
    

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 18:24       ` Joseph Myers
@ 2017-04-04 17:25         ` Szabolcs Nagy
  2017-04-04 17:34           ` Joseph Myers
  2017-04-07 15:54           ` Szabolcs Nagy
  2017-04-04 17:41         ` Zack Weinberg
  1 sibling, 2 replies; 12+ messages in thread
From: Szabolcs Nagy @ 2017-04-04 17:25 UTC (permalink / raw)
  To: Joseph Myers; +Cc: nd, Wilco Dijkstra, libc-alpha

On 16/03/17 18:24, Joseph Myers wrote:
> On Thu, 16 Mar 2017, Szabolcs Nagy wrote:
>> On 16/03/17 14:29, Joseph Myers wrote:
>>> On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
>>>
>>>> Given other languages don't even have the concept of errno, C99 doesn't 
>>>> require it, and no application ever reads errno, it is inefficient to 
>>>> force the use of the wrappers in almost all cases.
>>>
>>> C99 not requiring it was an incompatible quiet change from C90.
>>
>> i think glibc only has to set errno when user code is
>> compiled with c89 compatibility and even then only for
>> math functions that were defined in c89 and then only
>> guarantee correct errno setting in default rounding mode
>> (c89 code cannot access the fenv).
> 
> Incompatible quiet change means a good idea to implement the compatible 
> mode ((math_errhandling & MATH_ERRNO) != 0) as far as possible.  Just like 
> it's a good idea to avoid size_t wider than unsigned long.

i think this would be a valid argument if

 (math_errhandling & MATH_ERRNO) != 0

was the only way to get backward compatibility,
but that's not the case: errno can be clobbered
any time and thus c89 backward compatibility can
be maintained with

 (math_errhandling & MATH_ERRNO) == 0

in which case there is no requirement for non-c89
math functions to set errno (or getting errno
right in non-default fenv) and thus the wrapper
can be removed from all single and long double
precision functions (and kept for double prec
c89 functions if glibc cares about compatibility).

> Compilers for non-C languages without the concept of these functions 
> setting errno can of course default to -fno-math-errno by default (and 
> built-in no-errno functions that can be used with -fmath-errno is 
> otherwise enabled would also be desirable for fma, sqrt, etc.).

then fortran can only use no-errno functions
when those can be inlined, since extern calls
use the standard libc symbols which set errno
in glibc.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-04-04 17:25         ` Szabolcs Nagy
@ 2017-04-04 17:34           ` Joseph Myers
  2017-04-07 15:54           ` Szabolcs Nagy
  1 sibling, 0 replies; 12+ messages in thread
From: Joseph Myers @ 2017-04-04 17:34 UTC (permalink / raw)
  To: Szabolcs Nagy; +Cc: nd, Wilco Dijkstra, libc-alpha

On Tue, 4 Apr 2017, Szabolcs Nagy wrote:

> > Compilers for non-C languages without the concept of these functions 
> > setting errno can of course default to -fno-math-errno by default (and 
> > built-in no-errno functions that can be used with -fmath-errno is 
> > otherwise enabled would also be desirable for fma, sqrt, etc.).
> 
> then fortran can only use no-errno functions
> when those can be inlined, since extern calls
> use the standard libc symbols which set errno
> in glibc.

No, you should think of the implementation as a whole.  The Fortran 
compiler can know about what functions outside the standard are available 
in the C libm, and so generate calls to such nonstandard functions where 
appropriate.  That can either be hardcoded information about functions in 
particular glibc versions, or a system (e.g. file in the sysroot read by 
the compiler) for glibc to communicate such information to the Fortran 
compiler.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-03-16 18:24       ` Joseph Myers
  2017-04-04 17:25         ` Szabolcs Nagy
@ 2017-04-04 17:41         ` Zack Weinberg
  1 sibling, 0 replies; 12+ messages in thread
From: Zack Weinberg @ 2017-04-04 17:41 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

On Thu, Mar 16, 2017 at 2:24 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Thu, 16 Mar 2017, Szabolcs Nagy wrote:
>> On 16/03/17 14:29, Joseph Myers wrote:
>> > On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
>> >
>> >> Given other languages don't even have the concept of errno, C99 doesn't
>> >> require it, and no application ever reads errno, it is inefficient to
>> >> force the use of the wrappers in almost all cases.
>> >
>> > C99 not requiring it was an incompatible quiet change from C90.
>>
>> i think glibc only has to set errno when user code is
>> compiled with c89 compatibility and even then only for
>> math functions that were defined in c89 and then only
>> guarantee correct errno setting in default rounding mode
>> (c89 code cannot access the fenv).
>
> Incompatible quiet change means a good idea to implement the compatible
> mode ((math_errhandling & MATH_ERRNO) != 0) as far as possible.  Just like
> it's a good idea to avoid size_t wider than unsigned long.

In this case, I seriously question whether anyone _wants_ math
functions to set errno, ever, even in C89-era code.

Can we try to find out?  It ought to be possible to trawl
numerical-computation codebases for references to errno... (I don't
have anything like the time to do it, alas)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Improving math function wrappers
  2017-04-04 17:25         ` Szabolcs Nagy
  2017-04-04 17:34           ` Joseph Myers
@ 2017-04-07 15:54           ` Szabolcs Nagy
  1 sibling, 0 replies; 12+ messages in thread
From: Szabolcs Nagy @ 2017-04-07 15:54 UTC (permalink / raw)
  To: Joseph Myers; +Cc: nd, Wilco Dijkstra, libc-alpha

On 04/04/17 18:25, Szabolcs Nagy wrote:
> On 16/03/17 18:24, Joseph Myers wrote:
>> On Thu, 16 Mar 2017, Szabolcs Nagy wrote:
>>> On 16/03/17 14:29, Joseph Myers wrote:
>>>> On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
>>>>
>>>>> Given other languages don't even have the concept of errno, C99 doesn't 
>>>>> require it, and no application ever reads errno, it is inefficient to 
>>>>> force the use of the wrappers in almost all cases.
>>>>
>>>> C99 not requiring it was an incompatible quiet change from C90.
>>>
>>> i think glibc only has to set errno when user code is
>>> compiled with c89 compatibility and even then only for
>>> math functions that were defined in c89 and then only
>>> guarantee correct errno setting in default rounding mode
>>> (c89 code cannot access the fenv).
>>
>> Incompatible quiet change means a good idea to implement the compatible 
>> mode ((math_errhandling & MATH_ERRNO) != 0) as far as possible.  Just like 
>> it's a good idea to avoid size_t wider than unsigned long.
> 
> i think this would be a valid argument if
> 
>  (math_errhandling & MATH_ERRNO) != 0
> 
> was the only way to get backward compatibility,
> but that's not the case: errno can be clobbered
> any time and thus c89 backward compatibility can
> be maintained with
> 
>  (math_errhandling & MATH_ERRNO) == 0
> 
> in which case there is no requirement for non-c89
> math functions to set errno (or getting errno
> right in non-default fenv) and thus the wrapper
> can be removed from all single and long double
> precision functions (and kept for double prec
> c89 functions if glibc cares about compatibility).
> 

hm this was not correct: errno cannot be arbitrarily
clobbered, it either has to be set correctly or left
unchanged, but this does not change my argument:
backward compatibility can be maintained more easily
with (math_errhandling & MATH_ERRNO) == 0.

http://port70.net/~nsz/c/c11/n1570.html#7.12.1p7

>> Compilers for non-C languages without the concept of these functions 
>> setting errno can of course default to -fno-math-errno by default (and 
>> built-in no-errno functions that can be used with -fmath-errno is 
>> otherwise enabled would also be desirable for fma, sqrt, etc.).
> 
> then fortran can only use no-errno functions
> when those can be inlined, since extern calls
> use the standard libc symbols which set errno
> in glibc.
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-04-07 15:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <AM5PR0802MB2610AA7EDC518B39F6D7152683260@AM5PR0802MB2610.eurprd08.prod.outlook.com>
2017-03-16 13:53 ` Improving math function wrappers Wilco Dijkstra
2017-03-16 14:39   ` Joseph Myers
2017-03-16 14:41     ` Joseph Myers
2017-03-16 18:07     ` Szabolcs Nagy
2017-03-16 18:24       ` Joseph Myers
2017-04-04 17:25         ` Szabolcs Nagy
2017-04-04 17:34           ` Joseph Myers
2017-04-07 15:54           ` Szabolcs Nagy
2017-04-04 17:41         ` Zack Weinberg
2017-03-16 21:22   ` Florian Weimer
2017-03-16 21:36     ` Joseph Myers
2017-03-16 22:49       ` Wilco Dijkstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).