[libc-commits] [PATCH] D76723: [libc] Generate math.h instead of the static file it is currently.

Siva Chandra via Phabricator via libc-commits libc-commits at lists.llvm.org
Wed Mar 25 10:50:40 PDT 2020


sivachandra marked an inline comment as done.
sivachandra added inline comments.


================
Comment at: libc/config/linux/api.td:79
+    #define math_errhandling 0
+    #elif defined __NO_MATH_ERRNO__
+    #define math_errhandling (MATH_ERREXCEPT)
----------------
PaulkaToast wrote:
> I think some of this might be gcc/glibc specific stuff and should be thought over. See:
> 
> * https://gcc.gnu.org/legacy-ml/gcc-patches/2014-11/msg01079.html
> * https://github.com/bminor/glibc/commit/3c7d03129498e7426855b5d4cdd5b7109ecc2172
> 
> `0` is actually not a value allowed by the C2011 standard for `math_errhandling`. See this excerpt:
> 
> > The macros 
> > **MATH_ERRNO**
> > **MATH_ERREXCEPT**
> > expand to the integer constants `1` and `2`, respectively; the macro
> > `math_errhandling` expands to an expression that has type int and the value
> > `MATH_ERRNO`, `MATH_ERREXCEPT`, or the bitwise OR of both.
> 
> > For all functions, a domain error occurs if an input argument is outside the domain over
> > which the mathematical function is defined. The description of each function lists any
> > required domain errors; an implementation may define additional domain errors, provided
> > that such errors are consistent with the mathematical definition of the function.228) On a
> > domain error, the function returns an implementation-defined value; if the integer
> > expression `math_errhandling & MATH_ERRNO` is nonzero, the integer expression
> > `errno` acquires the value `EDOM`; if the integer expression `math_errhandling & MATH_ERREXCEPT`
> > is nonzero, the ‘‘invalid’’ floating-point exception is raised.
> 
> `__NO_MATH_ERRNO__` in particular is very gcc specific and clang doesn't set it regardless of `-ffast-math` or `-fno-math-errno`. This leads to this case where `sqrt(-1.0)` will not set `errno` despite us setting `math_errhandling` to `MATH_ERRNO | MATH_ERREXCEPT`: https://godbolt.org/z/ZhMT_z
> 
> For now it might be better just to define this conservatively as
> 
>   lang=c
>   #define math_errhandling (MATH_ERREXCEPT)
> 
> since it seems a little tough to determine whether math functions will set `errno` across both gcc and clang, but it is known that they will set the floating point exceptions.
There is a lot of information here so let me try to answer in parts.

Before I start, I would like to point out that a libc can itself be compiled with different values of `math_errhandling`. So, the options `-ffast-math` and/or `-fno-math-errno` are only applicable to your translation unit and not to your entire program in case of your godbolt examples.

About `-ffast-math` and `-fno-math-errno`: These are compiler options wherein the compilers are saying that irrespective of what the libc does, we will try to make your code run faster. The speed might come at the cost of non-compliance with standards. For example, `-ffast-math` implies `-fno-math-errno` and `-funsafe-math-optimizations`. The documentation for `-funsafe-math-optimizations` says, "Allow optimizations for floating-point arithmetic that (a) assume that arguments and results are valid and (b) may violate IEEE or ANSI standards." So, under `-ffast-math`, compilers *might* generate code which does not give any error information. Some instructions generated by the compilers can still set the floating point exceptions. But, in general, user code cannot except that any error information will be available. The way to surface this to the user code is to set `math_errhandling` to 0 under `__FAST_MATH__`.

Coming to the differences between clang and gcc you are seeing in your `sqrt` examples, it is because gcc and clang use different interpretations of the options and has nothing to do with the under lying libc they use if at all. After all, `-ffast-math` and `-fno-math-errno` are compiler options, and also best effort options. If you notice, both clang and gcc do not call `sqrt` at all when `-ffast-math` is used. Likewise, gcc chooses to call `sqrt` with or without `-fno-math-errno`. On the other hand, clang does not call `sqrt` even when `-fno-math-errno` is used. The important point is that these differences do not reflect or dictate what the underlying libc does or should do.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76723/new/

https://reviews.llvm.org/D76723





More information about the libc-commits mailing list