return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
}
+ case Intrinsic::sin:
+ case Intrinsic::cos:
+ case Intrinsic::pow: {
+ MVT RetVT;
+ if (!isTypeLegal(II->getType(), RetVT))
+ return false;
+
+ if (RetVT != MVT::f32 && RetVT != MVT::f64)
+ return false;
+
+ static const RTLIB::Libcall LibCallTable[3][2] = {
+ { RTLIB::SIN_F32, RTLIB::SIN_F64 },
+ { RTLIB::COS_F32, RTLIB::COS_F64 },
+ { RTLIB::POW_F32, RTLIB::POW_F64 }
+ };
+ RTLIB::Libcall LC;
+ bool Is64Bit = RetVT == MVT::f64;
+ switch (II->getIntrinsicID()) {
+ default:
+ llvm_unreachable("Unexpected intrinsic.");
+ case Intrinsic::sin:
+ LC = LibCallTable[0][Is64Bit];
+ break;
+ case Intrinsic::cos:
+ LC = LibCallTable[1][Is64Bit];
+ break;
+ case Intrinsic::pow:
+ LC = LibCallTable[2][Is64Bit];
+ break;
+ }
+
+ ArgListTy Args;
+ Args.reserve(II->getNumArgOperands());
+
+ // Populate the argument list.
+ for (auto &Arg : II->arg_operands()) {
+ ArgListEntry Entry;
+ Entry.Val = Arg;
+ Entry.Ty = Arg->getType();
+ Args.push_back(Entry);
+ }
+
+ CallLoweringInfo CLI;
+ CLI.setCallee(TLI.getLibcallCallingConv(LC), II->getType(),
+ TLI.getLibcallName(LC), std::move(Args));
+ if (!lowerCallTo(CLI))
+ return false;
+ updateValueMap(II, CLI.ResultReg);
+ return true;
+ }
case Intrinsic::trap: {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
.addImm(1);
+++ /dev/null
-; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=small -verify-machineinstrs < %s | FileCheck %s --check-prefix=SMALL
-; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
-
-define float @frem_f32(float %a, float %b) {
-; SMALL-LABEL: frem_f32
-; SMALL: bl _fmodf
-; LARGE-LABEL: frem_f32
-; LARGE: adrp [[REG:x[0-9]+]], _fmodf@GOTPAGE
-; LARGE: ldr [[REG]], {{\[}}[[REG]], _fmodf@GOTPAGEOFF{{\]}}
-; LARGE-NEXT: blr [[REG]]
- %1 = frem float %a, %b
- ret float %1
-}
-
-define double @frem_f64(double %a, double %b) {
-; SMALL-LABEL: frem_f64
-; SMALL: bl _fmod
-; LARGE-LABEL: frem_f64
-; LARGE: adrp [[REG:x[0-9]+]], _fmod@GOTPAGE
-; LARGE: ldr [[REG]], {{\[}}[[REG]], _fmod@GOTPAGEOFF{{\]}}
-; LARGE-NEXT: blr [[REG]]
- %1 = frem double %a, %b
- ret double %1
-}
--- /dev/null
+; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=small -verify-machineinstrs < %s | FileCheck %s --check-prefix=SMALL
+; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
+
+define float @frem_f32(float %a, float %b) {
+; SMALL-LABEL: frem_f32
+; SMALL: bl _fmodf
+; LARGE-LABEL: frem_f32
+; LARGE: adrp [[REG:x[0-9]+]], _fmodf@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _fmodf@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = frem float %a, %b
+ ret float %1
+}
+
+define double @frem_f64(double %a, double %b) {
+; SMALL-LABEL: frem_f64
+; SMALL: bl _fmod
+; LARGE-LABEL: frem_f64
+; LARGE: adrp [[REG:x[0-9]+]], _fmod@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _fmod@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = frem double %a, %b
+ ret double %1
+}
+
+define float @sin_f32(float %a) {
+; SMALL-LABEL: sin_f32
+; SMALL: bl _sinf
+; LARGE-LABEL: sin_f32
+; LARGE: adrp [[REG:x[0-9]+]], _sinf@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _sinf@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call float @llvm.sin.f32(float %a)
+ ret float %1
+}
+
+define double @sin_f64(double %a) {
+; SMALL-LABEL: sin_f64
+; SMALL: bl _sin
+; LARGE-LABEL: sin_f64
+; LARGE: adrp [[REG:x[0-9]+]], _sin@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _sin@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call double @llvm.sin.f64(double %a)
+ ret double %1
+}
+
+define float @cos_f32(float %a) {
+; SMALL-LABEL: cos_f32
+; SMALL: bl _cosf
+; LARGE-LABEL: cos_f32
+; LARGE: adrp [[REG:x[0-9]+]], _cosf@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _cosf@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call float @llvm.cos.f32(float %a)
+ ret float %1
+}
+
+define double @cos_f64(double %a) {
+; SMALL-LABEL: cos_f64
+; SMALL: bl _cos
+; LARGE-LABEL: cos_f64
+; LARGE: adrp [[REG:x[0-9]+]], _cos@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _cos@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call double @llvm.cos.f64(double %a)
+ ret double %1
+}
+
+define float @pow_f32(float %a, float %b) {
+; SMALL-LABEL: pow_f32
+; SMALL: bl _powf
+; LARGE-LABEL: pow_f32
+; LARGE: adrp [[REG:x[0-9]+]], _powf@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _powf@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call float @llvm.pow.f32(float %a, float %b)
+ ret float %1
+}
+
+define double @pow_f64(double %a, double %b) {
+; SMALL-LABEL: pow_f64
+; SMALL: bl _pow
+; LARGE-LABEL: pow_f64
+; LARGE: adrp [[REG:x[0-9]+]], _pow@GOTPAGE
+; LARGE: ldr [[REG]], {{\[}}[[REG]], _pow@GOTPAGEOFF{{\]}}
+; LARGE-NEXT: blr [[REG]]
+ %1 = call double @llvm.pow.f64(double %a, double %b)
+ ret double %1
+}
+declare float @llvm.sin.f32(float)
+declare double @llvm.sin.f64(double)
+declare float @llvm.cos.f32(float)
+declare double @llvm.cos.f64(double)
+declare float @llvm.pow.f32(float, float)
+declare double @llvm.pow.f64(double, double)