aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/RuntimeLibcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/RuntimeLibcalls.cpp')
-rw-r--r--llvm/lib/IR/RuntimeLibcalls.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 77af29b..2ce5719 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/RuntimeLibcalls.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringTable.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/xxhash.h"
#include "llvm/TargetParser/ARMTargetParser.h"
@@ -72,3 +74,80 @@ bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
return false;
}
}
+
+std::pair<FunctionType *, AttributeList>
+RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
+ const DataLayout &DL,
+ RTLIB::LibcallImpl LibcallImpl) const {
+ static constexpr Attribute::AttrKind CommonFnAttrs[] = {
+ Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
+ Attribute::NoUnwind, Attribute::WillReturn};
+
+ switch (LibcallImpl) {
+ case RTLIB::impl___sincos_stret:
+ case RTLIB::impl___sincosf_stret: {
+ if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
+ return {};
+
+ Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
+ ? Type::getFloatTy(Ctx)
+ : Type::getDoubleTy(Ctx);
+
+ AttrBuilder FuncAttrBuilder(Ctx);
+ for (Attribute::AttrKind Attr : CommonFnAttrs)
+ FuncAttrBuilder.addAttribute(Attr);
+
+ const bool UseSret =
+ TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
+ ARM::computeTargetABI(TT) == ARM::ARM_ABI_APCS);
+
+ FuncAttrBuilder.addMemoryAttr(MemoryEffects::argumentOrErrnoMemOnly(
+ UseSret ? ModRefInfo::Mod : ModRefInfo::NoModRef, ModRefInfo::Mod));
+
+ AttributeList Attrs;
+ Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
+
+ if (UseSret) {
+ AttrBuilder AttrBuilder(Ctx);
+ StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
+ AttrBuilder.addStructRetAttr(StructTy);
+ AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
+ FunctionType *FuncTy = FunctionType::get(
+ Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
+
+ return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
+ }
+
+ Type *RetTy =
+ LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
+ ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
+ : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
+
+ return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
+ }
+ case RTLIB::impl_sqrtf:
+ case RTLIB::impl_sqrt: {
+ AttrBuilder FuncAttrBuilder(Ctx);
+
+ for (Attribute::AttrKind Attr : CommonFnAttrs)
+ FuncAttrBuilder.addAttribute(Attr);
+ FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
+
+ AttributeList Attrs;
+ Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
+
+ Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
+ : Type::getDoubleTy(Ctx);
+ FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
+
+ Attrs = Attrs.addRetAttribute(
+ Ctx, Attribute::getWithNoFPClass(Ctx, fcNegInf | fcNegSubnormal |
+ fcNegNormal));
+ return {FuncTy, Attrs};
+ }
+ default:
+ return {};
+ }
+
+ return {};
+}