Skip to content

Commit 6147c59

Browse files
committed
RuntimeLibcalls: Add malloc and free entries
Calloc was already here, but not the others. Also add manual type information.
1 parent a921be6 commit 6147c59

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,9 @@ def MEMMOVE : RuntimeLibcall;
382382
def MEMMOVE_CHK : RuntimeLibcall;
383383
def MEMSET : RuntimeLibcall;
384384
def MEMSET_CHK : RuntimeLibcall;
385+
def MALLOC : RuntimeLibcall;
385386
def CALLOC : RuntimeLibcall;
387+
def FREE : RuntimeLibcall;
386388
def BZERO : RuntimeLibcall;
387389
def STRLEN : RuntimeLibcall;
388390

@@ -1101,8 +1103,11 @@ def __memcpy_chk : RuntimeLibcallImpl<MEMCPY_CHK>;
11011103
def __memmove_chk : RuntimeLibcallImpl<MEMMOVE_CHK>;
11021104
def __memset_chk : RuntimeLibcallImpl<MEMSET_CHK>;
11031105

1106+
def malloc : RuntimeLibcallImpl<MALLOC>;
1107+
11041108
// DSEPass can emit calloc if it finds a pair of malloc/memset
11051109
def calloc : RuntimeLibcallImpl<CALLOC>;
1110+
def free : RuntimeLibcallImpl<FREE>;
11061111

11071112
} // End let IsDefault = true
11081113

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,23 @@ bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
130130
}
131131
}
132132

133+
/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
134+
/// size of the edfault address space. This matches TargetLibraryInfo and should
135+
/// be kept in sync.
136+
static IntegerType *getSizeTType(LLVMContext &Ctx, const DataLayout &DL) {
137+
return DL.getIndexType(Ctx, /*AddressSpace=*/0);
138+
}
139+
133140
std::pair<FunctionType *, AttributeList>
134141
RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
135142
const DataLayout &DL,
136143
RTLIB::LibcallImpl LibcallImpl) const {
144+
// TODO: NoCallback probably unsafe in general
137145
static constexpr Attribute::AttrKind CommonFnAttrs[] = {
138146
Attribute::MustProgress, Attribute::NoCallback, Attribute::NoFree,
139147
Attribute::NoSync, Attribute::NoUnwind, Attribute::WillReturn};
148+
static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
149+
Attribute::MustProgress, Attribute::NoUnwind, Attribute::WillReturn};
140150
static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
141151
Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
142152

@@ -182,6 +192,71 @@ RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
182192

183193
return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
184194
}
195+
case RTLIB::impl_malloc:
196+
case RTLIB::impl_calloc: {
197+
AttrBuilder FuncAttrBuilder(Ctx);
198+
for (Attribute::AttrKind Attr : MemoryFnAttrs)
199+
FuncAttrBuilder.addAttribute(Attr);
200+
FuncAttrBuilder.addAttribute(Attribute::NoFree);
201+
202+
AllocFnKind AllocKind = AllocFnKind::Alloc;
203+
if (LibcallImpl == RTLIB::impl_malloc)
204+
AllocKind |= AllocFnKind::Uninitialized;
205+
206+
// TODO: Set memory attribute
207+
FuncAttrBuilder.addAllocKindAttr(AllocKind);
208+
FuncAttrBuilder.addAttribute("alloc-family", "malloc");
209+
FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
210+
? std::nullopt
211+
: std::make_optional(1));
212+
213+
AttributeList Attrs;
214+
Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
215+
216+
{
217+
AttrBuilder ArgAttrBuilder(Ctx);
218+
for (Attribute::AttrKind AK : CommonPtrArgAttrs)
219+
ArgAttrBuilder.addAttribute(AK);
220+
221+
Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
222+
Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
223+
Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
224+
if (LibcallImpl == RTLIB::impl_calloc)
225+
Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
226+
}
227+
228+
IntegerType *SizeT = getSizeTType(Ctx, DL);
229+
PointerType *PtrTy = PointerType::get(Ctx, 0);
230+
SmallVector<Type *, 2> ArgTys = {SizeT};
231+
if (LibcallImpl == RTLIB::impl_calloc)
232+
ArgTys.push_back(SizeT);
233+
234+
return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
235+
}
236+
case RTLIB::impl_free: {
237+
// TODO: Set memory attribute
238+
AttrBuilder FuncAttrBuilder(Ctx);
239+
for (Attribute::AttrKind Attr : MemoryFnAttrs)
240+
FuncAttrBuilder.addAttribute(Attr);
241+
242+
FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
243+
FuncAttrBuilder.addAttribute("alloc-family", "malloc");
244+
245+
AttributeList Attrs;
246+
Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
247+
248+
{
249+
AttrBuilder ArgAttrBuilder(Ctx);
250+
ArgAttrBuilder.addAttribute(Attribute::NoUndef);
251+
ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
252+
ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
253+
Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
254+
}
255+
256+
return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
257+
false),
258+
Attrs};
259+
}
185260
case RTLIB::impl_sqrtf:
186261
case RTLIB::impl_sqrt: {
187262
AttrBuilder FuncAttrBuilder(Ctx);

llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@ define float @sinf(float %x) {
2020

2121
; CHECK: declare void @acosf(...)
2222

23+
; CHECK: declare noalias noundef ptr @calloc(i64 noundef, i64 noundef) [[CALLOC_ATTRS:#[0-9]+]]
24+
2325
; CHECK: declare void @fdim(...)
2426
; CHECK: declare void @fdimf(...)
2527
; CHECK: declare void @fdiml(...)
2628

29+
; CHECK: declare void @free(ptr allocptr noundef captures(none)) [[FREE_ATTRS:#[0-9]+]]
30+
31+
; CHECK: declare noalias noundef ptr @malloc(i64 noundef) [[MALLOC_ATTRS:#[0-9]+]]
32+
2733
; CHECK: declare void @nan(...)
2834
; CHECK: declare void @nanf(...)
2935
; CHECK: declare void @nanl(...)
@@ -58,3 +64,6 @@ define float @sinf(float %x) {
5864

5965
; CHECK: declare void @truncl(...)
6066

67+
; CHECK: attributes [[CALLOC_ATTRS]] = { mustprogress nofree nounwind willreturn allockind("alloc") allocsize(0,1) "alloc-family"="malloc" }
68+
; CHECK: attributes [[FREE_ATTRS]] = { mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" }
69+
; CHECK: attributes [[MALLOC_ATTRS]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" }

0 commit comments

Comments
 (0)