On 07/08/17 23:02 +0200, Jakub Jelinek wrote:
On Mon, Aug 07, 2017 at 09:59:04PM +0100, Jonathan Wakely wrote:
> If it is outlined without the first 7 lines, i.e. just the body of if (b),
> then it could be duplicate_one_attribute (tree *, tree, const char *);
> called like if (b) duplicate_one_attribute (&DECL_ATTRIBUTES (b), s, "omp declare 
simd");
> If it is duplicated as whole, it should be called
> duplicate_one_attr_to_builtin or something similar.
> In any case, it could be in tree.c or attribs.c.
>
> The primary question is if we want this behavior, or if we should go the
> libstdc++ patch routine (and for Jonathan the question is if he knows
> why __builtin_XXXf has been used there rather than the ::XXXf).

I don't know for certain, but I suspect it's because sinf, cosf, powf
etc. were new in C99, so a strict libc might not declare them in C++98
mode.

By using __builtin_sinf we don't need a declaration of sinf, we only
require the definition to exist in libc or libm. If the function is
present, but not declared for C++98, then it works.

Ah, so if we go the libstdc++ patch route, we'd need to check in configure
for the prototypes in C++98 mode and guard the stuff with #ifdef
_GLIBCXX_HAVE_COSF or similar, right?  Or do this only for C++11 and above.

Yes. If we can assume that libc will declare those functions when
__cplusplus >= 201103L then we could do:

 inline _GLIBCXX_CONSTEXPR float
 cos(float __x)
 {
#if __cplusplus >= 201103L
   return ::cosf(__x);
#else
   return __builtin_cosf(__x);
#endif
 }

Alternatively we could check _GLIBCXX_USE_C99_MATH instead:

#if _GLIBCXX_USE_C99_MATH
   return ::cosf(__x);
#else
   return __builtin_cosf(__x);
#endif

That macro expands to either _GLIBCXX98_USE_C99_MATH or
_GLIBCXX11_USE_C99_MATH depending on the value of __cplusplus and
tells us if the C99 <math.h> functions are declared for the current
-std mode. The value of that macro depends on whether the following
are available in <math.h>:

       [i = fpclassify(d1);
        i = isfinite(d1);
        i = isinf(d1);
        i = isnan(d1);
        i = isnormal(d1);
        i = signbit(d1);
        i = isgreater(d1, d2);
        i = isgreaterequal(d1, d2);
        i = isless(d1, d2);
        i = islessequal(d1, d2);
        i = islessgreater(d1, d2);
        i = islessgreater(d1, d2);
        i = isunordered(d1, d2);

If it's possible that they could be declared but sinf/cosf/etc. are
not, then we'd need something like a new _GLIBCXX_HAVE_C99_MATH_FL
macro to say the C99 float and long double functions are present.

We may need that new macro anyway, to fix PR 79700.

Reply via email to