On Sun, 17 Oct 2021, Raoni Fassina Firmino wrote: > First is the different arguments from the C99 functions. I think the > solution is a macro to correct this, like so: > > #define feclearexcept(excepts) \ > __builtin_feclearexcept(excepts, FE_DIVBYZERO, FE_INEXACT, \ > FE_INVALID, FE_OVERFLOW, FE_UNDERFLOW) > > That is automatically always included or included when fenv.h is > included. Does the preprocessor have this ability? If so, where > should I put it?
The compiler should not be adding such macros to libc headers. If libc wants to provide such optimizations based on built-in functions, they should go in libc headers with an appropriate condition on the compiler version. However, it's better to get things right automatically without needing any macros or other header additions at all. That is, define feclearexcept as a built-in function, *without* the extra arguments, and with the back end knowing about the FE_* values for the target libc. Then you can simply avoid expanding the function inline when the back end doesn't know both the FE_* values and how to use them. fpclassify is a fundamentally different case, because that's defined by the standard to be a *type-generic macro*, whereas feclearexcept is defined by the standard to be a *function*. The example of fpclassify should not be followed for feclearexcept, feraiseexcept or fegetround. > Second is the fallback of the expanders. When the expanders fail it > will leave the function call, which is great, but since the argument > list is different, well, it not is pretty. There is no execution If you define __builtin_X to have different arguments to X, it should also be defined so it's *always* expanded inline (on all architectures) and never falls back to a library function call to X. (This means, for example, not defining __builtin_X at all as a built-in function in cases, such as soft float, where you can't expand it inline, so that erroneous code trying to call __builtin_X in that case ends up with an undefined reference to the __builtin_X symbol.) Once you avoid having different arguments to the library function, you can simply avoid expanding inline whenever the back end lacks the relevant information; you don't need to do anything to avoid the built-in function existing. > +@deftypefn {Built-in Function} int __builtin_fegetround (int, int, int, int) > +This built-in implements the C99 fegetround functionality. The four int > +arguments should be the target library's notion of the possible FP rouding > +modes. They must be constant values and they must appear in this order: > +@code{FE_DOWNWARD}, @code{FE_TONEAREST}, @code{FE_TOWARDZERO}, > +@code{FE_UPWARD}. In other words: Some architectures have more rounding modes (e.g. FE_TONEARESTFROMZERO). Some have fewer. I think that illustrates the essential flaw of defining these functions to take a fixed set of rounding mode macros as arguments. On the other hand, there is a use for a *different* built-in function to get the rounding mode for FLT_ROUNDS, using the fixed set of values for FLT_ROUNDS specified in the C standard, and *always expanding inline without ever introducing a dependency on libm*. See bug 30569 and <https://gcc.gnu.org/legacy-ml/gcc/2013-11/msg00317.html> regarding that. -- Joseph S. Myers jos...@codesourcery.com