Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h +++ include/llvm/ADT/Triple.h @@ -470,6 +470,12 @@ return getOS() == Triple::ELFIAMCU; } + bool isGNUEnvironment() const { + EnvironmentType Env = getEnvironment(); + return Env == Triple::GNU || Env == Triple::GNUEABI || + Env == Triple::GNUEABIHF || Env == Triple::GNUX32; + } + /// Checks if the environment could be MSVC. bool isWindowsMSVCEnvironment() const { return getOS() == Triple::Win32 && Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2176,8 +2176,7 @@ return false; // GNU sin/cos functions set errno while sincos does not. Therefore // combining sin and cos is only safe if unsafe-fpmath is enabled. - bool isGNU = Triple(TM.getTargetTriple()).getEnvironment() == Triple::GNU; - if (isGNU && !TM.Options.UnsafeFPMath) + if (TM.getTargetTriple().isGNUEnvironment() && !TM.Options.UnsafeFPMath) return false; return true; } Index: lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- lib/CodeGen/TargetLoweringBase.cpp +++ lib/CodeGen/TargetLoweringBase.cpp @@ -473,7 +473,7 @@ Names[RTLIB::ATOMIC_FETCH_NAND_8] = "__atomic_fetch_nand_8"; Names[RTLIB::ATOMIC_FETCH_NAND_16] = "__atomic_fetch_nand_16"; - if (TT.getEnvironment() == Triple::GNU) { + if (TT.isGNUEnvironment()) { Names[RTLIB::SINCOS_F32] = "sincosf"; Names[RTLIB::SINCOS_F64] = "sincos"; Names[RTLIB::SINCOS_F80] = "sincosl"; Index: test/CodeGen/ARM/sincos.ll =================================================================== --- test/CodeGen/ARM/sincos.ll +++ test/CodeGen/ARM/sincos.ll @@ -1,5 +1,8 @@ ; RUN: llc < %s -mtriple=armv7-apple-ios6 -mcpu=cortex-a8 | FileCheck %s --check-prefix=NOOPT ; RUN: llc < %s -mtriple=armv7-apple-ios7 -mcpu=cortex-a8 | FileCheck %s --check-prefix=SINCOS +; RUN: llc < %s -mtriple=armv7-linux-gnu -mcpu=cortex-a8 | FileCheck %s --check-prefix=NOOPT-GNU +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 \ +; RUN: --enable-unsafe-fp-math | FileCheck %s --check-prefix=SINCOS-GNU ; Combine sin / cos into a single call. ; rdar://12856873 @@ -9,9 +12,17 @@ ; SINCOS-LABEL: test1: ; SINCOS: bl ___sincosf_stret +; SINCOS-GNU-LABEL: test1: +; SINCOS-GNU: bl sincosf + ; NOOPT-LABEL: test1: ; NOOPT: bl _sinf ; NOOPT: bl _cosf + +; NOOPT-GNU-LABEL: test1: +; NOOPT-GNU: bl sinf +; NOOPT-GNU: bl cosf + %call = tail call float @sinf(float %x) nounwind readnone %call1 = tail call float @cosf(float %x) nounwind readnone %add = fadd float %call, %call1 @@ -23,9 +34,16 @@ ; SINCOS-LABEL: test2: ; SINCOS: bl ___sincos_stret +; SINCOS-GNU-LABEL: test2: +; SINCOS-GNU: bl sincos + ; NOOPT-LABEL: test2: ; NOOPT: bl _sin ; NOOPT: bl _cos + +; NOOPT-GNU-LABEL: test2: +; NOOPT-GNU: bl sin +; NOOPT-GNU: bl cos %call = tail call double @sin(double %x) nounwind readnone %call1 = tail call double @cos(double %x) nounwind readnone %add = fadd double %call, %call1 Index: test/CodeGen/X86/sincos-opt.ll =================================================================== --- test/CodeGen/X86/sincos-opt.ll +++ test/CodeGen/X86/sincos-opt.ll @@ -1,6 +1,8 @@ ; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_SINCOS ; RUN: llc < %s -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_NOOPT +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mcpu=core2 | FileCheck %s --check-prefix=GNU_NOOPT ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNU_SINCOS +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNUX32_SINCOS ; Combine sin / cos into a single call. ; rdar://13087969 @@ -13,6 +15,15 @@ ; GNU_SINCOS: movss 4(%rsp), %xmm0 ; GNU_SINCOS: addss (%rsp), %xmm0 +; GNUX32_SINCOS-LABEL: test1: +; GNUX32_SINCOS: callq sincosf +; GNUX32_SINCOS: movss 4(%esp), %xmm0 +; GNUX32_SINCOS: addss (%esp), %xmm0 + +; GNU_NOOPT: test1 +; GNU_NOOPT: callq sinf +; GNU_NOOPT: callq cosf + ; OSX_SINCOS-LABEL: test1: ; OSX_SINCOS: callq ___sincosf_stret ; OSX_SINCOS: movshdup {{.*}} xmm1 = xmm0[1,1,3,3] @@ -34,6 +45,15 @@ ; GNU_SINCOS: movsd 16(%rsp), %xmm0 ; GNU_SINCOS: addsd 8(%rsp), %xmm0 +; GNUX32_SINCOS-LABEL: test2: +; GNUX32_SINCOS: callq sincos +; GNUX32_SINCOS: movsd 16(%esp), %xmm0 +; GNUX32_SINCOS: addsd 8(%esp), %xmm0 + +; GNU_NOOPT: test2: +; GNU_NOOPT: callq sin +; GNU_NOOPT: callq cos + ; OSX_SINCOS-LABEL: test2: ; OSX_SINCOS: callq ___sincos_stret ; OSX_SINCOS: addsd %xmm1, %xmm0 @@ -53,6 +73,16 @@ ; GNU_SINCOS: callq sinl ; GNU_SINCOS: callq cosl ; GNU_SINCOS: ret + +; GNUX32_SINCOS-LABEL: test3: +; GNUX32_SINCOS: callq sinl +; GNUX32_SINCOS: callq cosl +; GNUX32_SINCOS: ret + +; GNU_NOOPT: test3: +; GNU_NOOPT: callq sinl +; GNU_NOOPT: callq cosl + %call = tail call x86_fp80 @sinl(x86_fp80 %x) nounwind %call1 = tail call x86_fp80 @cosl(x86_fp80 %x) nounwind %add = fadd x86_fp80 %call, %call1