[llvm-branch-commits] [llvm] RuntimeLibcalls: Add malloc and free entries (PR #167081)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 7 19:29:43 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Calloc was already here, but not the others. Also add
manual type information.
---
Full diff: https://github.com/llvm/llvm-project/pull/167081.diff
3 Files Affected:
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+5)
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+75)
- (modified) llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll (+9)
``````````diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index f6ad23a4f9c49..929959a4735b0 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -382,7 +382,9 @@ def MEMMOVE : RuntimeLibcall;
def MEMMOVE_CHK : RuntimeLibcall;
def MEMSET : RuntimeLibcall;
def MEMSET_CHK : RuntimeLibcall;
+def MALLOC : RuntimeLibcall;
def CALLOC : RuntimeLibcall;
+def FREE : RuntimeLibcall;
def BZERO : RuntimeLibcall;
def STRLEN : RuntimeLibcall;
@@ -1101,8 +1103,11 @@ def __memcpy_chk : RuntimeLibcallImpl<MEMCPY_CHK>;
def __memmove_chk : RuntimeLibcallImpl<MEMMOVE_CHK>;
def __memset_chk : RuntimeLibcallImpl<MEMSET_CHK>;
+def malloc : RuntimeLibcallImpl<MALLOC>;
+
// DSEPass can emit calloc if it finds a pair of malloc/memset
def calloc : RuntimeLibcallImpl<CALLOC>;
+def free : RuntimeLibcallImpl<FREE>;
} // End let IsDefault = true
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 633bd52dade7a..6f00d1d51fd9c 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -129,13 +129,23 @@ bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
}
}
+/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
+/// size of the edfault address space. This matches TargetLibraryInfo and should
+/// be kept in sync.
+static IntegerType *getSizeTType(LLVMContext &Ctx, const DataLayout &DL) {
+ return DL.getIndexType(Ctx, /*AddressSpace=*/0);
+}
+
std::pair<FunctionType *, AttributeList>
RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
const DataLayout &DL,
RTLIB::LibcallImpl LibcallImpl) const {
+ // TODO: NoCallback probably unsafe in general
static constexpr Attribute::AttrKind CommonFnAttrs[] = {
Attribute::MustProgress, Attribute::NoCallback, Attribute::NoFree,
Attribute::NoSync, Attribute::NoUnwind, Attribute::WillReturn};
+ static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
+ Attribute::MustProgress, Attribute::NoUnwind, Attribute::WillReturn};
static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
@@ -181,6 +191,71 @@ RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
}
+ case RTLIB::impl_malloc:
+ case RTLIB::impl_calloc: {
+ AttrBuilder FuncAttrBuilder(Ctx);
+ for (Attribute::AttrKind Attr : MemoryFnAttrs)
+ FuncAttrBuilder.addAttribute(Attr);
+ FuncAttrBuilder.addAttribute(Attribute::NoFree);
+
+ AllocFnKind AllocKind = AllocFnKind::Alloc;
+ if (LibcallImpl == RTLIB::impl_malloc)
+ AllocKind |= AllocFnKind::Uninitialized;
+
+ // TODO: Set memory attribute
+ FuncAttrBuilder.addAllocKindAttr(AllocKind);
+ FuncAttrBuilder.addAttribute("alloc-family", "malloc");
+ FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
+ ? std::nullopt
+ : std::make_optional(1));
+
+ AttributeList Attrs;
+ Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
+
+ {
+ AttrBuilder ArgAttrBuilder(Ctx);
+ for (Attribute::AttrKind AK : CommonPtrArgAttrs)
+ ArgAttrBuilder.addAttribute(AK);
+
+ Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
+ Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
+ Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
+ if (LibcallImpl == RTLIB::impl_calloc)
+ Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
+ }
+
+ IntegerType *SizeT = getSizeTType(Ctx, DL);
+ PointerType *PtrTy = PointerType::get(Ctx, 0);
+ SmallVector<Type *, 2> ArgTys = {SizeT};
+ if (LibcallImpl == RTLIB::impl_calloc)
+ ArgTys.push_back(SizeT);
+
+ return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
+ }
+ case RTLIB::impl_free: {
+ // TODO: Set memory attribute
+ AttrBuilder FuncAttrBuilder(Ctx);
+ for (Attribute::AttrKind Attr : MemoryFnAttrs)
+ FuncAttrBuilder.addAttribute(Attr);
+
+ FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
+ FuncAttrBuilder.addAttribute("alloc-family", "malloc");
+
+ AttributeList Attrs;
+ Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
+
+ {
+ AttrBuilder ArgAttrBuilder(Ctx);
+ ArgAttrBuilder.addAttribute(Attribute::NoUndef);
+ ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
+ ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
+ Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
+ }
+
+ return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
+ false),
+ Attrs};
+ }
case RTLIB::impl_sqrtf:
case RTLIB::impl_sqrt: {
AttrBuilder FuncAttrBuilder(Ctx);
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
index db0cc24c287bc..f1a039dc033ac 100644
--- a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
@@ -20,10 +20,16 @@ define float @sinf(float %x) {
; CHECK: declare void @acosf(...)
+; CHECK: declare noalias noundef ptr @calloc(i64 noundef, i64 noundef) [[CALLOC_ATTRS:#[0-9]+]]
+
; CHECK: declare void @fdim(...)
; CHECK: declare void @fdimf(...)
; CHECK: declare void @fdiml(...)
+; CHECK: declare void @free(ptr allocptr noundef captures(none)) [[FREE_ATTRS:#[0-9]+]]
+
+; CHECK: declare noalias noundef ptr @malloc(i64 noundef) [[MALLOC_ATTRS:#[0-9]+]]
+
; CHECK: declare void @nan(...)
; CHECK: declare void @nanf(...)
; CHECK: declare void @nanl(...)
@@ -58,3 +64,6 @@ define float @sinf(float %x) {
; CHECK: declare void @truncl(...)
+; CHECK: attributes [[CALLOC_ATTRS]] = { mustprogress nofree nounwind willreturn allockind("alloc") allocsize(0,1) "alloc-family"="malloc" }
+; CHECK: attributes [[FREE_ATTRS]] = { mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" }
+; CHECK: attributes [[MALLOC_ATTRS]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" }
``````````
</details>
https://github.com/llvm/llvm-project/pull/167081
More information about the llvm-branch-commits
mailing list