From ffc20a90d2e2570ddb5cb5434dee3ca4096a7228 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Tue, 21 Jun 2016 12:29:03 +0000 Subject: [PATCH] [arm+x86] Make GNU variants behave like GNU w.r.t combining sin+cos into sincos. Summary: canCombineSinCosLibcall() would previously combine sin+cos into sincos for GNUX32/GNUEABI/GNUEABIHF regardless of whether UnsafeFPMath were set or not. However, GNU would only combine them for UnsafeFPMath because sincos does not set errno like sin and cos do. It seems likely that this is an oversight. Reviewers: t.p.northover Subscribers: t.p.northover, aemerson, llvm-commits, rengolin Differential Revision: http://reviews.llvm.org/D21431 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273259 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Triple.h | 6 +++++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 3 +-- lib/CodeGen/TargetLoweringBase.cpp | 2 +- test/CodeGen/ARM/sincos.ll | 18 ++++++++++++++ test/CodeGen/X86/sincos-opt.ll | 30 ++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index beb19ffee4a..d8616545908 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -470,6 +470,12 @@ public: 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 && diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 4c6ae245f5a..02234793e49 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2176,8 +2176,7 @@ static bool canCombineSinCosLibcall(SDNode *Node, const TargetLowering &TLI, 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; } diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp index aa7c4a67209..a4db08ab534 100644 --- a/lib/CodeGen/TargetLoweringBase.cpp +++ b/lib/CodeGen/TargetLoweringBase.cpp @@ -473,7 +473,7 @@ static void InitLibcallNames(const char **Names, const Triple &TT) { 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"; diff --git a/test/CodeGen/ARM/sincos.ll b/test/CodeGen/ARM/sincos.ll index 30b2664e372..5be0044ddbd 100644 --- a/test/CodeGen/ARM/sincos.ll +++ b/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 @@ entry: ; 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 @@ entry: ; 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 diff --git a/test/CodeGen/X86/sincos-opt.ll b/test/CodeGen/X86/sincos-opt.ll index 9d02bcd9a6c..f0dff3b806c 100644 --- a/test/CodeGen/X86/sincos-opt.ll +++ b/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 @@ entry: ; 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 @@ entry: ; 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 @@ entry: ; 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 -- 2.50.1