1; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_SINCOS 2; RUN: llc < %s -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_NOOPT 3; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mcpu=core2 | FileCheck %s --check-prefix=GNU_SINCOS 4; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNU_SINCOS_FASTMATH 5; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNU_SINCOS_FASTMATH 6; RUN: llc < %s -mtriple=x86_64-fuchsia -mcpu=core2 | FileCheck %s --check-prefix=GNU_SINCOS 7; RUN: llc < %s -mtriple=x86_64-fuchsia -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNU_SINCOS_FASTMATH 8; RUN: llc < %s -mtriple=x86_64-scei-ps4 -mcpu=btver2 | FileCheck %s --check-prefix=PS4_SINCOS 9 10; Combine sin / cos into a single call unless they may write errno (as 11; captured by readnone attrbiute, controlled by clang -fmath-errno 12; setting). 13; rdar://13087969 14; rdar://13599493 15 16define float @test1(float %x) nounwind { 17entry: 18; GNU_SINCOS-LABEL: test1: 19; GNU_SINCOS: callq sincosf 20; GNU_SINCOS: movss 4(%rsp), %xmm0 21; GNU_SINCOS: addss (%rsp), %xmm0 22 23; GNU_SINCOS_FASTMATH-LABEL: test1: 24; GNU_SINCOS_FASTMATH: callq sincosf 25; GNU_SINCOS_FASTMATH: movss 4(%{{[re]}}sp), %xmm0 26; GNU_SINCOS_FASTMATH: addss (%{{[re]}}sp), %xmm0 27 28; OSX_SINCOS-LABEL: test1: 29; OSX_SINCOS: callq ___sincosf_stret 30; OSX_SINCOS: movshdup {{.*}} xmm1 = xmm0[1,1,3,3] 31; OSX_SINCOS: addss %xmm1, %xmm0 32 33; OSX_NOOPT-LABEL: test1: 34; OSX_NOOPT: callq _sinf 35; OSX_NOOPT: callq _cosf 36 37; PS4_SINCOS-LABEL: test1: 38; PS4_SINCOS: callq sincosf 39; PS4_SINCOS: vmovss 4(%rsp), %xmm0 40; PS4_SINCOS: vaddss (%rsp), %xmm0, %xmm0 41 %call = tail call float @sinf(float %x) readnone 42 %call1 = tail call float @cosf(float %x) readnone 43 %add = fadd float %call, %call1 44 ret float %add 45} 46 47define float @test1_errno(float %x) nounwind { 48entry: 49; GNU_SINCOS-LABEL: test1_errno: 50; GNU_SINCOS: callq sinf 51; GNU_SINCOS: callq cosf 52 53; GNU_SINCOS_FASTMATH-LABEL: test1_errno: 54; GNU_SINCOS_FASTMATH: callq sinf 55; GNU_SINCOS_FASTMATH: callq cosf 56 57; OSX_SINCOS-LABEL: test1_errno: 58; OSX_SINCOS: callq _sinf 59; OSX_SINCOS: callq _cosf 60 61; OSX_NOOPT-LABEL: test1_errno: 62; OSX_NOOPT: callq _sinf 63; OSX_NOOPT: callq _cosf 64 65; PS4_SINCOS-LABEL: test1_errno: 66; PS4_SINCOS: callq sinf 67; PS4_SINCOS: callq cosf 68 %call = tail call float @sinf(float %x) 69 %call1 = tail call float @cosf(float %x) 70 %add = fadd float %call, %call1 71 ret float %add 72} 73 74define double @test2(double %x) nounwind { 75entry: 76; GNU_SINCOS-LABEL: test2: 77; GNU_SINCOS: callq sincos 78; GNU_SINCOS: movsd 16(%rsp), %xmm0 79; GNU_SINCOS: addsd 8(%rsp), %xmm0 80 81; GNU_SINCOS_FASTMATH-LABEL: test2: 82; GNU_SINCOS_FASTMATH: callq sincos 83; GNU_SINCOS_FASTMATH: movsd 16(%{{[re]}}sp), %xmm0 84; GNU_SINCOS_FASTMATH: addsd 8(%{{[re]}}sp), %xmm0 85 86; OSX_SINCOS-LABEL: test2: 87; OSX_SINCOS: callq ___sincos_stret 88; OSX_SINCOS: addsd %xmm1, %xmm0 89 90; OSX_NOOPT-LABEL: test2: 91; OSX_NOOPT: callq _sin 92; OSX_NOOPT: callq _cos 93 94; PS4_SINCOS-LABEL: test2: 95; PS4_SINCOS: callq sincos 96; PS4_SINCOS: vmovsd 16(%rsp), %xmm0 97; PS4_SINCOS: vaddsd 8(%rsp), %xmm0, %xmm0 98 %call = tail call double @sin(double %x) readnone 99 %call1 = tail call double @cos(double %x) readnone 100 %add = fadd double %call, %call1 101 ret double %add 102} 103 104define double @test2_errno(double %x) nounwind { 105entry: 106; GNU_SINCOS-LABEL: test2_errno: 107; GNU_SINCOS: callq sin 108; GNU_SINCOS: callq cos 109 110; GNU_SINCOS_FASTMATH-LABEL: test2_errno: 111; GNU_SINCOS_FASTMATH: callq sin 112; GNU_SINCOS_FASTMATH: callq cos 113 114; OSX_SINCOS-LABEL: test2_errno: 115; OSX_SINCOS: callq _sin 116; OSX_SINCOS: callq _cos 117 118; OSX_NOOPT-LABEL: test2_errno: 119; OSX_NOOPT: callq _sin 120; OSX_NOOPT: callq _cos 121 122; PS4_SINCOS-LABEL: test2_errno: 123; PS4_SINCOS: callq sin 124; PS4_SINCOS: callq cos 125 %call = tail call double @sin(double %x) 126 %call1 = tail call double @cos(double %x) 127 %add = fadd double %call, %call1 128 ret double %add 129} 130 131define x86_fp80 @test3(x86_fp80 %x) nounwind { 132entry: 133; GNU_SINCOS-LABEL: test3: 134; GNU_SINCOS: callq sincosl 135; GNU_SINCOS: fldt 16(%rsp) 136; GNU_SINCOS: fldt 32(%rsp) 137; GNU_SINCOS: faddp %st, %st(1) 138 139; GNU_SINCOS_FASTMATH-LABEL: test3: 140; GNU_SINCOS_FASTMATH: callq sincosl 141; GNU_SINCOS_FASTMATH: fldt 16(%{{[re]}}sp) 142; GNU_SINCOS_FASTMATH: fldt 32(%{{[re]}}sp) 143; GNU_SINCOS_FASTMATH: faddp %st, %st(1) 144 145; PS4_SINCOS-LABEL: test3: 146; PS4_SINCOS: callq sinl 147; PS4_SINCOS: callq cosl 148 %call = tail call x86_fp80 @sinl(x86_fp80 %x) readnone 149 %call1 = tail call x86_fp80 @cosl(x86_fp80 %x) readnone 150 %add = fadd x86_fp80 %call, %call1 151 ret x86_fp80 %add 152} 153 154define x86_fp80 @test3_errno(x86_fp80 %x) nounwind { 155entry: 156; GNU_SINCOS-LABEL: test3_errno: 157; GNU_SINCOS: callq sinl 158; GNU_SINCOS: callq cosl 159 160; GNU_SINCOS_FASTMATH-LABEL: test3_errno: 161; GNU_SINCOS_FASTMATH: callq sinl 162; GNU_SINCOS_FASTMATH: callq cosl 163 164; PS4_SINCOS-LABEL: test3_errno: 165; PS4_SINCOS: callq sinl 166; PS4_SINCOS: callq cosl 167 %call = tail call x86_fp80 @sinl(x86_fp80 %x) 168 %call1 = tail call x86_fp80 @cosl(x86_fp80 %x) 169 %add = fadd x86_fp80 %call, %call1 170 ret x86_fp80 %add 171} 172 173declare float @sinf(float) 174declare double @sin(double) 175declare float @cosf(float) 176declare double @cos(double) 177declare x86_fp80 @sinl(x86_fp80) 178declare x86_fp80 @cosl(x86_fp80) 179