Skip to content

Commit f4beefa

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

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
@@ -129,13 +129,23 @@ bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
129129
}
130130
}
131131

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

@@ -181,6 +191,71 @@ RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
181191

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