Re: [PATCH] libm/math: Use __math_xflow in obsolete math code
Szabolcs Nagy <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
The 08/03/2020 11:07, Keith Packard wrote: > Szabolcs Nagy <[email protected]> writes: > > > note1: i used c99 code when i wrote the > > new math code and currently the old math > > code can be compiled with older compilers, > > this change might prevent that. > > Hrm. I just learned about "#pragma STDC FENV_ACCESS on" this morning and > am wondering if we shouldn't just patch the old math library to use that > instead of calling the __math_xflow functions. Would be a simpler patch > and provide precise compatibility with the previous version. i don't know of any c compiler that correctly implements that pragma and some compilers (clang) warn about it so i don't use it myself. but the correct iso c way is to use it on every code that may run in non-default fenv (non-nearest rounding mode) or may run between exception setting and getting operations. (i.e. not just for math code that has fenv functions in it). the drawback is that it means that any call may access the fenv (i.e. if you mark a function implementation with the pragma then any call within that function may change the rounding mode unless the compiler can prove otherwise), so all extern calls become floating-point barriers which prevents some useful optimizations (most calls don't change the rounding mode). and this still does not give complete fenv safety, because it's not clear if inline asm or other language extensions may access fenv or not and how compilers will deal with that: currently float operations are reordered across inline asm. > > Here's an example of how that works: > > #include <fenv.h> > #include <stdio.h> > > #pragma STDC FENV_ACCESS on > > int main(void) > { > double x; > int e; > feclearexcept(FE_ALL_EXCEPT); > x = 0.0 / 0.0; > e = fetestexcept(FE_ALL_EXCEPT); > printf("x %g e %x\n", x, e); > return 0; > } > > $ cc except.c -lm > $ ./a.out > x -nan e 1 > $ > > As you can see, even using constants still raise the appropriate > exception. either you got lucky or you use another compiler than i do. (gcc gets close to exception safe operation if you use -frounding-math: then it assumes the compiled code itself does not change the rounding mode, but its caller might, which e.g. means that constant folding is not allowed: inexact arithmetic operations are rounding mode dependent. so the generated code mostly preserves fenv exceptions, but this can break if the result does not depend on rounding: nextafter(DBL_MIN,0) should raise underflow but it may be const folded, or relational operations may not preserve exceptions)