clang does not use sincos with -O2 but gcc does

why do clang needs the -ffast-math option to use the sincos function here?
gcc uses the sincos function without -ffast-math

clang -O2 -march=native (call sin, call cos)
clang -O3 -march=native (call sin, call cos)
clang -O2 -march=native -ffast-math (call sincos)

gcc -O2 (call sincos)

It may have something to do with the fact that sincos() is a GNU extension to the standard math lib?

Also, I hope it doesn't expand to a call to the x87 FPU instruction, but IIRC that one is actually slower than 2 calls to modern sin() and cos() implementations :slight_smile:

R.

It may have something to do with the fact that sincos()
is a GNU extension to the standard math lib?

clang DOES use sincos if -ffast-math option is given
gcc use it even without -ffast-math

so the questions are:
-is gcc wrong in using sincos without -ffast-math
-is clang wrong in seeing sincos as to evil (only accepting it with -ffast-math)

is it because cos and sin can produce different (FPU)NaN/Exception-Results so
the flow is different when using the combined sincos?

Also, I hope it doesn't expand to a call to the x87 FPU instruction,
but IIRC that one is actually slower than 2 calls
to modern sin() and cos() implementations :slight_smile:

i don't think its the x87 opcode - because then LLVM would inline it - and not using a call

clang DOES use sincos if -ffast-math option is given
gcc use it even without -ffast-math

To make matters even more complex: on Mac the situation is the opposite, that is clang always uses a sincos library function provided by Apple.

i don't think its the x87 opcode - because then LLVM would inline it - and not using a call

That depends, LLVM cannot know how the sincos() function from libm is implemented.

R.

To make matters even more complex: on Mac the situation is the opposite

im on ubuntu 16.04 x64 only
gcc-5.4, gcc-6.2, clang 3.8.0 - they all should use the same stdlib
and i want to understand why gcc is using sincos (without -ffast-math) in
the 3 tested releases (5,6,7), and clang only when using -ffast-math
- this is not about platform differences

is it a missing clang optimization opportunity or is the gcc wrong in using sincos by default?

test.c

The answer lies inside of canCombineSinCosLibcall in lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:

// GNU sin/cos functions set errno while sincos does not. Therefore
// combining sin and cos is only safe if unsafe-fpmath is enabled.

unsafe-fpmath is enabled with -ffast-math.

I.e. folding to sincos is unlikely to be standard compliant. It’s also the reason why functions can not marked constexpr :-/

IMHO, errno is an anachronism and should never have been included as a part of . I would personally like the base functions to be wholly ignorant of errno, and there to be a separate set of functions that throw the appropriate exceptions for those rare cases where knowledge of domain errors is important.

I’ve yet to come across production code that checks errno in any capacity after calling a math function (language support libraries excepted). I feel that the errno requirement is a rare case that unfortunately affects the optimizability of a large portion of code that could benefit from its absence altogether.

Thank you

so GCCs folding to sincos is semi OK

>reason why <cmath> functions can not marked constexpr :-/

:o/

>I would personally like the base <cmath> functions
>to be wholly ignorant of errno

that would be great

>the errno requirement is a rare case that unfortunately
>affects the optimizability of a large portion of code

im currently doing a test-project and im freaking out
about all these low-level-but-not-optimizable stuff, and
every compiler/platform is more/less ignoring some parts

things getting even "better" when using the microsoft compiler :frowning:

Dennis

Right; Apple’s libm does not ever set errno, and defines math_errhandling to MATH_ERREXCEPT, so we don’t need to worry about errno on Apple platforms; further our sincos produces the same result as separate calls to sin and cos do, so this transform never perturbs observable results.

– Steve

A couple months ago, I filed this bug against gcc not recognizing that sincos sets errno. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80042

The x86 backend will use the fsincos instruction if both sin and cos are used in code and sse is disabled. I think this is independent of whether sincos function is used.