diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def index fd53a26ef8fc1..db566b8ee610e 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def @@ -2077,6 +2077,11 @@ TLI_DEFINE_ENUM_INTERNAL(reallocf) TLI_DEFINE_STRING_INTERNAL("reallocf") TLI_DEFINE_SIG_INTERNAL(Ptr, Ptr, SizeT) +/// void *reallocarray(void *ptr, size_t nmemb, size_t size); +TLI_DEFINE_ENUM_INTERNAL(reallocarray) +TLI_DEFINE_STRING_INTERNAL("reallocarray") +TLI_DEFINE_SIG_INTERNAL(Ptr, Ptr, SizeT, SizeT) + /// char *realpath(const char *file_name, char *resolved_name); TLI_DEFINE_ENUM_INTERNAL(realpath) TLI_DEFINE_STRING_INTERNAL("realpath") diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 7f0b98ab3c151..e4b1dbfc3e723 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -852,6 +852,7 @@ static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.setUnavailable(LibFunc_memrchr); TLI.setUnavailable(LibFunc_ntohl); TLI.setUnavailable(LibFunc_ntohs); + TLI.setUnavailable(LibFunc_reallocarray); TLI.setUnavailable(LibFunc_reallocf); TLI.setUnavailable(LibFunc_roundeven); TLI.setUnavailable(LibFunc_roundevenf); diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index e039457f313b2..e4f4052e5e481 100644 --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -577,6 +577,20 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, Changed |= setDoesNotCapture(F, 0); Changed |= setArgNoUndef(F, 1); break; + case LibFunc_reallocarray: + Changed |= setAllocFamily(F, "malloc"); + Changed |= setAllocKind(F, AllocFnKind::Realloc); + Changed |= setAllocatedPointerParam(F, 0); + Changed |= setAllocSize(F, 1, 2); + Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F); + Changed |= setRetNoUndef(F); + Changed |= setDoesNotThrow(F); + Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); + Changed |= setDoesNotCapture(F, 0); + Changed |= setArgNoUndef(F, 1); + Changed |= setArgNoUndef(F, 2); + break; case LibFunc_read: // May throw; "read" is a valid pthread cancellation point. Changed |= setRetAndArgsNoUndef(F); diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll index 452d90aa98d88..e63487de61ba2 100644 --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -827,6 +827,9 @@ declare i64 @readlink(ptr, ptr, i64) ; CHECK: declare noalias noundef ptr @realloc(ptr allocptr nocapture, i64 noundef) [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC:#[0-9]+]] declare ptr @realloc(ptr, i64) +; CHECK: declare noalias noundef ptr @reallocarray(ptr allocptr nocapture, i64 noundef, i64 noundef) [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE12_FAMILY_MALLOC:#[0-9]+]] +declare ptr @reallocarray(ptr, i64, i64) + ; CHECK: declare noalias noundef ptr @reallocf(ptr allocptr nocapture, i64 noundef) [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] declare ptr @reallocf(ptr, i64) @@ -1194,6 +1197,7 @@ declare void @memset_pattern16(ptr, ptr, i64) ; CHECK-DAG: attributes [[NOFREE]] = { nofree } ; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { nofree nounwind memory(argmem: readwrite) } ; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } +; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE12_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1,2) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } ; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } ; CHECK-DAG: attributes [[NOFREE_COLD]] = { cold nofree } ; CHECK-DAG: attributes [[NOFREE_COLD_NORETURN]] = { cold nofree noreturn } diff --git a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml index 6702725e4fc8a..2d23b15d74b17 100644 --- a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml +++ b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml @@ -54,10 +54,10 @@ ## the exact count first; the two directives should add up to that. ## Yes, this means additions to TLI will fail this test, but the argument ## to -COUNT can't be an expression. -# AVAIL: TLI knows 522 symbols, 289 available +# AVAIL: TLI knows 523 symbols, 289 available # AVAIL-COUNT-289: {{^}} available # AVAIL-NOT: {{^}} available -# UNAVAIL-COUNT-233: not available +# UNAVAIL-COUNT-234: not available # UNAVAIL-NOT: not available ## This is a large file so it's worth telling lit to stop here. diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp index 982d00c5d3359..b9900db68b142 100644 --- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp +++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp @@ -318,6 +318,7 @@ TEST_F(TargetLibraryInfoTest, ValidProto) { "declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)*)\n" "declare i64 @readlink(i8*, i8*, i64)\n" "declare i8* @realloc(i8*, i64)\n" + "declare i8* @reallocarray(i8*, i64, i64)\n" "declare i8* @reallocf(i8*, i64)\n" "declare double @remainder(double, double)\n" "declare float @remainderf(float, float)\n"