clang does not use sincos with -O2 but gcc does

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
https://godbolt.org/g/Y0sjoj

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)

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
On Thursday May 18 2017 10:09:14 Dennis Luehring via cfe-dev wrote:

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

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 :)

R.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
>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 :)

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

Am 18.05.2017 um 13:58 schrieb René J.V. Bertin:

> On Thursday May 18 2017 10:09:14 Dennis Luehring via cfe-dev wrote:
>
> >why do clang needs the -ffast-math option to use the sincos function here?
> >gcc uses the sincos function without -ffast-math
>
> 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 :)
>
> R.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
On Thursday May 18 2017 14:55:03 Dennis Luehring wrote:

>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.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
>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
----
#include <math.h>
int main(int argc, char* argv[])
{
   double x = argv[0][0];
   return (int)sin(x)+cos(x);
}
----

gcc -S test.c -O2 -lm
test.s
----
        .file "test.c"
        .section .text.unlikely,"ax",@progbits
.LCOLDB0:
        .section .text.startup,"ax",@progbits
.LHOTB0:
        .p2align 4,,15
        .globl main
        .type main, @function
main:
.LFB3:
        .cfi_startproc
        subq $24, %rsp
        .cfi_def_cfa_offset 32
        movq (%rsi), %rax
        pxor %xmm0, %xmm0
        leaq 8(%rsp), %rdi
        movq %rsp, %rsi
        movsbl (%rax), %eax
        cvtsi2sd %eax, %xmm0
        call sincos
        cvttsd2si 8(%rsp), %eax
        pxor %xmm0, %xmm0
        cvtsi2sd %eax, %xmm0
        addsd (%rsp), %xmm0
        addq $24, %rsp
        .cfi_def_cfa_offset 8
        cvttsd2si %xmm0, %eax
        ret
        .cfi_endproc
.LFE3:
        .size main, .-main
        .section .text.unlikely
.LCOLDE0:
        .section .text.startup
.LHOTE0:
        .ident "GCC: (Ubuntu 5.4.1-2ubuntu1~16.04) 5.4.1 20160904"
        .section .note.GNU-stack,"",@progbits
----

gcc-6 -S test.c -O2 -lm
test.s
----
        .file "test.c"
        .section .text.startup,"ax",@progbits
        .p2align 4,,15
        .globl main
        .type main, @function
main:
.LFB3:
        .cfi_startproc
        subq $24, %rsp
        .cfi_def_cfa_offset 32
        movq (%rsi), %rax
        pxor %xmm0, %xmm0
        leaq 8(%rsp), %rdi
        movq %rsp, %rsi
        movsbl (%rax), %eax
        cvtsi2sd %eax, %xmm0
        call sincos
        cvttsd2si 8(%rsp), %eax
        pxor %xmm0, %xmm0
        cvtsi2sd %eax, %xmm0
        addsd (%rsp), %xmm0
        addq $24, %rsp
        .cfi_def_cfa_offset 8
        cvttsd2si %xmm0, %eax
        ret
        .cfi_endproc
.LFE3:
        .size main, .-main
        .ident "GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901"
        .section .note.GNU-stack,"",@progbits

clang -S test.c -O2
test.s
----
        .text
        .file "test.c"
        .globl main
        .align 16, 0x90
        .type main,@function
main:                                   # @main
        .cfi_startproc
# BB#0:
        subq $24, %rsp
.Ltmp0:
        .cfi_def_cfa_offset 32
        movq (%rsi), %rax
        movsbl (%rax), %eax
        cvtsi2sdl %eax, %xmm0
        movsd %xmm0, 8(%rsp)          # 8-byte Spill
        callq sin
        cvttsd2si %xmm0, %eax
        xorps %xmm0, %xmm0
        cvtsi2sdl %eax, %xmm0
        movsd %xmm0, 16(%rsp)         # 8-byte Spill
        movsd 8(%rsp), %xmm0          # 8-byte Reload
                                         # xmm0 = mem[0],zero
        callq cos
        addsd 16(%rsp), %xmm0         # 8-byte Folded Reload
        cvttsd2si %xmm0, %eax
        addq $24, %rsp
        retq
.Lfunc_end0:
        .size main, .Lfunc_end0-main
        .cfi_endproc


        .ident "clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)"
        .section ".note.GNU-stack","",@progbits

clang -S test.c -O2 -ffast-math
test.s
----
        .text
        .file "test.c"
        .globl main
        .align 16, 0x90
        .type main,@function
main:                                   # @main
        .cfi_startproc
# BB#0:
        subq $24, %rsp
.Ltmp0:
        .cfi_def_cfa_offset 32
        movq (%rsi), %rax
        movsbl (%rax), %eax
        cvtsi2sdl %eax, %xmm0
        leaq 16(%rsp), %rdi
        leaq 8(%rsp), %rsi
        callq sincos
        cvttsd2si 16(%rsp), %eax
        xorps %xmm0, %xmm0
        cvtsi2sdl %eax, %xmm0
        addsd 8(%rsp), %xmm0
        cvttsd2si %xmm0, %eax
        addq $24, %rsp
        retq
.Lfunc_end0:
        .size main, .Lfunc_end0-main
        .cfi_endproc


        .ident "clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)"
        .section ".note.GNU-stack","",@progbits


Am 18.05.2017 um 16:20 schrieb René J.V. Bertin:

> On Thursday May 18 2017 14:55:03 Dennis Luehring wrote:
>
> >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.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
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 <cmath> functions can not marked constexpr :-/

IMHO, errno is an anachronism and should never have been included as a part of <cmath>. I would personally like the base <cmath> functions to be wholly ignorant of errno, and there to be a separate set of <cmath> 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.

- ½

On 18 May 2017 at 10:20, René J.V. Bertin via cfe-dev <[hidden email]> wrote:
On Thursday May 18 2017 14:55:03 Dennis Luehring wrote:

>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.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
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 :(

Dennis

Am 18.05.2017 um 17:12 schrieb Halfdan Ingvarsson:

> 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 <cmath> functions can not marked constexpr :-/
>
> IMHO, errno is an anachronism and should never have been included as a part
> of <cmath>. I would personally like the base <cmath> functions to be wholly
> ignorant of errno, and there to be a separate set of <cmath> 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.
>
> - ½
>
> On 18 May 2017 at 10:20, René J.V. Bertin via cfe-dev <
> [hidden email]> wrote:
>
> > On Thursday May 18 2017 14:55:03 Dennis Luehring wrote:
> >
> > >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.
> > _______________________________________________
> > cfe-dev mailing list
> > [hidden email]
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> >
>

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
On May 18, 2017, at 10:20 AM, René J.V. Bertin via cfe-dev <[hidden email]> wrote:

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.

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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang does not use sincos with -O2 but gcc does

Romanenkov Kirill via cfe-dev
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.

~Craig

On Thu, May 18, 2017 at 8:29 AM, Stephen Canon via cfe-dev <[hidden email]> wrote:
On May 18, 2017, at 10:20 AM, René J.V. Bertin via cfe-dev <[hidden email]> wrote:

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.

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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev