[PATCH] Improve -Ofast vectorization of std::sin etc. (PR libstdc++/81706)

Jonathan Wakely jwakely@redhat.com
Mon Aug 7 21:58:00 GMT 2017


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.



More information about the Libstdc++ mailing list