https://github.com/snehasish updated https://github.com/llvm/llvm-project/pull/234856
>From 3d7db397921f1eb72107ac4ef24a2bfb358f4f0c Mon Sep 17 00:00:00 2001 From: Snehasish Kumar <[email protected]> Date: Fri, 23 Oct 2026 06:21:26 +0000 Subject: [PATCH] [TLI][SimplifyLibCalls] Accept [2 x iN] return type for __size_returning_new* On AArch64, Clang lowers `struct __sized_ptr_t { void *p; size_t n; }` as the direct coerced return type `[2 x i64]` (`llvm::ArrayType`), whereas on x86_64 it is lowered as `{ ptr, i64 }` (`llvm::StructType`). Because `isValidProtoForSizeReturningNew` only accepted `StructType::get(Context, {PtrTy, SizeTTy})`, `TargetLibraryInfo::getLibFunc` rejected all four `__size_returning_new*` variants on AArch64. This caused: - `MemProfUse` to ignore `__size_returning_new*` calls when matching allocation profiles. - `LibCallSimplifier::optimizeNew` (via `InstCombine`) not to convert `__size_returning_new` / `__size_returning_new_aligned` with `memprof` attributes into their `_hot_cold` variants. - `AllocToken` instrumentation to skip `__size_returning_new*` calls on AArch64. Additionally, `emitHotColdSizeReturningNew` and `emitHotColdSizeReturningNewAligned` in `BuildLibCalls.cpp` previously hardcoded `StructType::get(B.getContext(), {B.getPtrTy(), SizeTTy})` as the return type of the newly emitted `_hot_cold` call, which would fail `replaceAllUsesWith` when replacing a call returning `[2 x i64]`. Fix this by: 1. Updating `isValidProtoForSizeReturningNew` to accept `[2 x iN]` (`ArrayType::get(SizeTTy, 2)`) in addition to `{ ptr, iN }`. 2. Passing the caller's return type (`CI->getType()`) to `emitHotColdSizeReturningNew` and `emitHotColdSizeReturningNewAligned` so the emitted `_hot_cold` declaration and call preserve the original return type. --- clang/test/CodeGen/alloc-token-lower.c | 10 +++-- .../llvm/Transforms/Utils/BuildLibCalls.h | 10 ++--- llvm/lib/Analysis/TargetLibraryInfo.cpp | 10 +++-- llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 24 ++++++------ .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 12 +++--- .../AllocToken/extralibfuncs.ll | 9 ++++- .../InstCombine/simplify-libcalls-new.ll | 12 ++++++ .../memprof_match_hot_cold_new_calls.ll | 6 +++ .../Analysis/TargetLibraryInfoTest.cpp | 37 +++++++++++++++++++ 9 files changed, 99 insertions(+), 31 deletions(-) diff --git a/clang/test/CodeGen/alloc-token-lower.c b/clang/test/CodeGen/alloc-token-lower.c index 9ab50ca7cd9383..cef9b99a07f852 100644 --- a/clang/test/CodeGen/alloc-token-lower.c +++ b/clang/test/CodeGen/alloc-token-lower.c @@ -1,12 +1,13 @@ // Test optimization pipelines do not interfere with AllocToken lowering, and we // pass on function attributes correctly. // -// RUN: %clang_cc1 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT -// RUN: %clang_cc1 -O1 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT -// RUN: %clang_cc1 -O2 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT +// RUN: %clang_cc1 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT,X86 +// RUN: %clang_cc1 -O1 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT,X86 +// RUN: %clang_cc1 -O2 -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT,X86 // RUN: %clang_cc1 -fsanitize=alloc-token -fsanitize-alloc-token-fast-abi -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,FASTABI // RUN: %clang_cc1 -O1 -fsanitize=alloc-token -fsanitize-alloc-token-fast-abi -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,FASTABI // RUN: %clang_cc1 -O2 -fsanitize=alloc-token -fsanitize-alloc-token-fast-abi -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,FASTABI +// RUN: %clang_cc1 -O1 -fsanitize=alloc-token -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT,ARM typedef __typeof(sizeof(int)) size_t; @@ -45,7 +46,8 @@ typedef struct { __sized_ptr_t __size_returning_new(size_t size) __attribute__((malloc_span)); // CHECK-LABEL: @test_size_returning_new -// DEFAULT: call{{.*}} { ptr, i64 } @__alloc_token___size_returning_new(i64 noundef 4, i64 2689373973731826898){{.*}} !alloc_token [[META_INT]] +// X86: call{{.*}} { ptr, i64 } @__alloc_token___size_returning_new(i64 noundef 4, i64 2689373973731826898){{.*}} !alloc_token [[META_INT]] +// ARM: call{{.*}} [2 x i64] @__alloc_token___size_returning_new(i64 noundef 4, i64 2689373973731826898){{.*}} !alloc_token [[META_INT]] // FASTABI: call{{.*}} { ptr, i64 } @__alloc_token_2689373973731826898___size_returning_new(i64 noundef 4){{.*}} !alloc_token [[META_INT]] void *test_size_returning_new() { __sized_ptr_t ret = __size_returning_new(sizeof(int)); diff --git a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h index 67b4ff985db636..c2a407dd43a8ce 100644 --- a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -299,11 +299,11 @@ namespace llvm { LibFunc NewFunc, Value *HotCold); LLVM_ABI Value *emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, - LibFunc NewFunc, Value *HotCold); - LLVM_ABI Value * - emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B, - const TargetLibraryInfo *TLI, - LibFunc NewFunc, Value *HotCold); + LibFunc NewFunc, Value *HotCold, + Type *RetTy); + LLVM_ABI Value *emitHotColdSizeReturningNewAligned( + Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, + LibFunc NewFunc, Value *HotCold, Type *RetTy); } #endif diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index c3469979d72047..4612e1fb5dbf6a 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -1085,9 +1085,13 @@ static bool isValidProtoForSizeReturningNew(const FunctionType &FTy, LibFunc F, auto &Context = M.getContext(); PointerType *PtrTy = PointerType::get(Context, 0); - StructType *SizedPtrTy = StructType::get( - Context, {PtrTy, Type::getIntNTy(Context, SizeTSizeBits)}); - return FTy.getReturnType() == SizedPtrTy; + Type *SizeTTy = Type::getIntNTy(Context, SizeTSizeBits); + Type *RetTy = FTy.getReturnType(); + // Return type struct __sized_ptr_t { void*, size_t } is lowered to + // { ptr, iN } on some targets (e.g. x86_64) and [2 x iN] on others (e.g. + // AArch64). + return RetTy == StructType::get(Context, {PtrTy, SizeTTy}) || + RetTy == ArrayType::get(SizeTTy, 2); } bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index 497927684a8d33..8e3f0249ff3548 100644 --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -2100,18 +2100,18 @@ Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B, Value *llvm::emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc SizeFeedbackNewFunc, - Value *HotCold) { + Value *HotCold, Type *RetTy) { Module *M = B.getModule(); if (!isLibFuncEmittable(M, TLI, SizeFeedbackNewFunc)) return nullptr; StringRef Name = TLI->getName(SizeFeedbackNewFunc); + if (const Function *F = M->getFunction(Name); + F && F->getReturnType() != RetTy) + return nullptr; - // __sized_ptr_t struct return type { void*, size_t } - StructType *SizedPtrT = - StructType::get(M->getContext(), {B.getPtrTy(), Num->getType()}); - FunctionCallee Func = getOrInsertLibFunc( - M, *TLI, SizeFeedbackNewFunc, SizedPtrT, Num->getType(), B.getInt8Ty()); + FunctionCallee Func = getOrInsertLibFunc(M, *TLI, SizeFeedbackNewFunc, RetTy, + Num->getType(), B.getInt8Ty()); inferNonMandatoryLibFuncAttrs(M, Name, *TLI); CallInst *CI = B.CreateCall(Func, {Num, HotCold}, "sized_ptr"); @@ -2125,19 +2125,19 @@ Value *llvm::emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc SizeFeedbackNewFunc, - Value *HotCold) { + Value *HotCold, Type *RetTy) { Module *M = B.getModule(); if (!isLibFuncEmittable(M, TLI, SizeFeedbackNewFunc)) return nullptr; StringRef Name = TLI->getName(SizeFeedbackNewFunc); + if (const Function *F = M->getFunction(Name); + F && F->getReturnType() != RetTy) + return nullptr; - // __sized_ptr_t struct return type { void*, size_t } - StructType *SizedPtrT = - StructType::get(M->getContext(), {B.getPtrTy(), Num->getType()}); FunctionCallee Func = - getOrInsertLibFunc(M, *TLI, SizeFeedbackNewFunc, SizedPtrT, - Num->getType(), Align->getType(), B.getInt8Ty()); + getOrInsertLibFunc(M, *TLI, SizeFeedbackNewFunc, RetTy, Num->getType(), + Align->getType(), B.getInt8Ty()); inferNonMandatoryLibFuncAttrs(M, Name, *TLI); CallInst *CI = B.CreateCall(Func, {Num, Align, HotCold}, "sized_ptr"); diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 60bfda6efaa4cb..4b21e3a02b1d77 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1995,25 +1995,25 @@ Value *LibCallSimplifier::optimizeNew(CallInst *CI, IRBuilderBase &B, case LibFunc_size_returning_new: NewCall = emitHotColdSizeReturningNew(CI->getArgOperand(0), B, TLI, LibFunc_size_returning_new_hot_cold, - HotColdVal); + HotColdVal, CI->getType()); break; case LibFunc_size_returning_new_hot_cold: if (ShouldOptimizeExistingHotColdNew) - NewCall = emitHotColdSizeReturningNew(CI->getArgOperand(0), B, TLI, - LibFunc_size_returning_new_hot_cold, - getHotColdHintForExisting(HotCold)); + NewCall = emitHotColdSizeReturningNew( + CI->getArgOperand(0), B, TLI, LibFunc_size_returning_new_hot_cold, + getHotColdHintForExisting(HotCold), CI->getType()); break; case LibFunc_size_returning_new_aligned: NewCall = emitHotColdSizeReturningNewAligned( CI->getArgOperand(0), CI->getArgOperand(1), B, TLI, - LibFunc_size_returning_new_aligned_hot_cold, HotColdVal); + LibFunc_size_returning_new_aligned_hot_cold, HotColdVal, CI->getType()); break; case LibFunc_size_returning_new_aligned_hot_cold: if (ShouldOptimizeExistingHotColdNew) NewCall = emitHotColdSizeReturningNewAligned( CI->getArgOperand(0), CI->getArgOperand(1), B, TLI, LibFunc_size_returning_new_aligned_hot_cold, - getHotColdHintForExisting(HotCold)); + getHotColdHintForExisting(HotCold), CI->getType()); break; default: return nullptr; diff --git a/llvm/test/Instrumentation/AllocToken/extralibfuncs.ll b/llvm/test/Instrumentation/AllocToken/extralibfuncs.ll index 0e382b2cebed69..4529f09b7c087d 100644 --- a/llvm/test/Instrumentation/AllocToken/extralibfuncs.ll +++ b/llvm/test/Instrumentation/AllocToken/extralibfuncs.ll @@ -6,6 +6,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" declare {ptr, i64} @__size_returning_new(i64) +declare [2 x i64] @__size_returning_new_aligned(i64, i64) define ptr @test_extra_libfuncs() sanitize_alloc_token { ; CHECK-LABEL: define ptr @test_extra_libfuncs( @@ -13,11 +14,17 @@ define ptr @test_extra_libfuncs() sanitize_alloc_token { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[TMP0:%.*]] = call { ptr, i64 } @__alloc_token___size_returning_new(i64 10, i64 2689373973731826898), !alloc_token [[META0:![0-9]+]] ; CHECK-NEXT: [[PTR1:%.*]] = extractvalue { ptr, i64 } [[TMP0]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = call [2 x i64] @__alloc_token___size_returning_new_aligned(i64 10, i64 8, i64 2689373973731826898), !alloc_token [[META0]] +; CHECK-NEXT: [[PTR2_INT:%.*]] = extractvalue [2 x i64] [[TMP1]], 0 +; CHECK-NEXT: [[PTR2:%.*]] = inttoptr i64 [[PTR2_INT]] to ptr ; CHECK-NEXT: ret ptr [[PTR1]] ; entry: %srn = call {ptr, i64} @__size_returning_new(i64 10), !alloc_token !0 - %ptr1 = extractvalue {ptr, i64} %srn, 0 + %ptr1 = extractvalue {ptr, i64} %srn, 0 + %srna = call [2 x i64] @__size_returning_new_aligned(i64 10, i64 8), !alloc_token !0 + %ptr2_int = extractvalue [2 x i64] %srna, 0 + %ptr2 = inttoptr i64 %ptr2_int to ptr ret ptr %ptr1 } diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll index 545df33a389ff9..a5fe051a7a654d 100644 --- a/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll +++ b/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll @@ -25,6 +25,10 @@ ; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -notcold-new-hint-value=100 -hot-new-hint-value=200 -ambiguous-new-hint-value=44 -optimize-existing-hot-cold-new -min-existing-hot-cold-new-hint -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-OFF,MIN-ALWAYS -DCOLD=5 -DHOT=-56 -DNOTCOLD=100 -DAMBIG=44 -DPREVHINTCOLD=5 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7 -DMINCOLD1=2 -DMINCOLD2=5 -DMINHOT1=-56 -DMINHOT2=50 ; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -notcold-new-hint-value=100 -hot-new-hint-value=200 -ambiguous-new-hint-value=44 -optimize-existing-hot-cold-new=cold -min-existing-hot-cold-new-hint -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-OFF,MIN-COLD -DCOLD=5 -DHOT=-56 -DNOTCOLD=100 -DAMBIG=44 -DPREVHINTCOLD=5 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7 -DMINCOLD1=2 -DMINCOLD2=5 -DMINHOT1=-6 -DMINHOT2=50 +;; Check that [2 x i64] return type (e.g. on AArch64) is also recognized and +;; preserved for __size_returning_new variants. +; RUN: sed -e 's/{ptr, i64}/[2 x i64]/g' -e 's/call void @dummy(ptr %%p/; /g' %s | opt -passes=instcombine -optimize-hot-cold-new -optimize-existing-hot-cold-new -S | FileCheck %s --check-prefix=ARRAY-RET + ;; Make sure that values not in 0..255 are flagged with an error ; RUN: not opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=256 -S 2>&1 | FileCheck %s --check-prefix=ERROR ; RUN: not opt < %s -passes=instcombine -optimize-hot-cold-new -hot-new-hint-value=5000 -S 2>&1 | FileCheck %s --check-prefix=ERROR @@ -489,9 +493,11 @@ define void @array_new_align_nothrow_hot_cold() { ;; Check that operator __size_returning_new(unsigned long) converted to ;; __size_returning_new(unsigned long, __hot_cold_t) with a hot or cold attribute. ; HOTCOLD-LABEL: @size_returning_test() +; ARRAY-RET-LABEL: @size_returning_test() define void @size_returning_test() { ;; Attribute cold converted to __hot_cold_t cold value. ; HOTCOLD: @__size_returning_new_hot_cold(i64 10, i8 [[COLD]]) + ; ARRAY-RET: call [2 x i64] @__size_returning_new_hot_cold(i64 10, i8 1) %call = call {ptr, i64} @__size_returning_new(i64 10) #3 %p = extractvalue {ptr, i64} %call, 0 call void @dummy(ptr %p) @@ -522,9 +528,11 @@ define void @size_returning_test() { ;; Check that operator __size_returning_new_aligned(unsigned long, std::align_val_t) converted to ;; __size_returning_new_aligned(unsigned long, std::align_val_t, __hot_cold_t) with a hot or cold attribute. ; HOTCOLD-LABEL: @size_returning_aligned_test() +; ARRAY-RET-LABEL: @size_returning_aligned_test() define void @size_returning_aligned_test() { ;; Attribute cold converted to __hot_cold_t cold value. ; HOTCOLD: @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 [[COLD]]) + ; ARRAY-RET: call [2 x i64] @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 1) %call = call {ptr, i64} @__size_returning_new_aligned(i64 10, i64 8) #3 %p = extractvalue {ptr, i64} %call, 0 call void @dummy(ptr %p) @@ -555,9 +563,11 @@ define void @size_returning_aligned_test() { ;; Check that __size_returning_new_hot_cold(unsigned long, __hot_cold_t) ;; optionally has its hint updated. ; HOTCOLD-LABEL: @size_returning_update_test() +; ARRAY-RET-LABEL: @size_returning_update_test() define void @size_returning_update_test() { ;; Attribute cold converted to __hot_cold_t cold value. ; HOTCOLD: @__size_returning_new_hot_cold(i64 10, i8 [[PREVHINTCOLD]]) + ; ARRAY-RET: call [2 x i64] @__size_returning_new_hot_cold(i64 10, i8 1) %call = call {ptr, i64} @__size_returning_new_hot_cold(i64 10, i8 7) #3 %p = extractvalue {ptr, i64} %call, 0 call void @dummy(ptr %p) @@ -587,9 +597,11 @@ define void @size_returning_update_test() { ;; Check that __size_returning_new_aligned_hot_cold(unsigned long, __hot_cold_t) ;; optionally has its hint updated. ; HOTCOLD-LABEL: @size_returning_aligned_update_test() +; ARRAY-RET-LABEL: @size_returning_aligned_update_test() define void @size_returning_aligned_update_test() { ;; Attribute cold converted to __hot_cold_t cold value. ; HOTCOLD: @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 [[PREVHINTCOLD]]) + ; ARRAY-RET: call [2 x i64] @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 1) %call = call {ptr, i64} @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 7) #3 %p = extractvalue {ptr, i64} %call, 0 call void @dummy(ptr %p) diff --git a/llvm/test/Transforms/PGOProfile/memprof_match_hot_cold_new_calls.ll b/llvm/test/Transforms/PGOProfile/memprof_match_hot_cold_new_calls.ll index 4aa05116226623..b71e478cb36cd7 100644 --- a/llvm/test/Transforms/PGOProfile/memprof_match_hot_cold_new_calls.ll +++ b/llvm/test/Transforms/PGOProfile/memprof_match_hot_cold_new_calls.ll @@ -100,10 +100,16 @@ define dso_local noundef ptr @_Z3foov() !dbg !10 { entry: ; MEMPROF: call {{.*}} @_Znwm{{.*}} !memprof ![[M1:[0-9]+]], !callsite ![[C1:[0-9]+]] %call = call noalias noundef align 32 ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 noundef 32, i64 noundef 32, ptr noundef nonnull align 1 dereferenceable(1) @_ZSt7nothrow, i8 noundef zeroext 0), !dbg !13 + ; MEMPROF: call {{.*}} @__size_returning_new_hot_cold{{.*}} !memprof ![[M1]], !callsite ![[C1]] + %srn = call [2 x i64] @__size_returning_new_hot_cold(i64 noundef 32, i8 noundef zeroext 0), !dbg !13 + ; MEMPROF: call {{.*}} @__size_returning_new_aligned_hot_cold{{.*}} !memprof ![[M1]], !callsite ![[C1]] + %srna = call [2 x i64] @__size_returning_new_aligned_hot_cold(i64 noundef 32, i64 noundef 32, i8 noundef zeroext 0), !dbg !13 ret ptr %call } declare noundef ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 noundef, i64 noundef, ptr noundef nonnull align 1 dereferenceable(1), i8 noundef zeroext) +declare [2 x i64] @__size_returning_new_hot_cold(i64 noundef, i8 noundef zeroext) +declare [2 x i64] @__size_returning_new_aligned_hot_cold(i64 noundef, i64 noundef, i8 noundef zeroext) ; MEMPROF: ![[M1]] = !{![[MIB1:[0-9]+]], ![[MIB2:[0-9]+]], ![[MIB3:[0-9]+]], ![[MIB4:[0-9]+]]} ; MEMPROF: ![[MIB1]] = !{![[STACK1:[0-9]+]], !"cold"} diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp index c68f5051b8ced9..fed7fa85fc7bf0 100644 --- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp +++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp @@ -107,6 +107,43 @@ TEST_F(TargetLibraryInfoTest, SizeReturningNewInvalidProto) { } } +TEST_F(TargetLibraryInfoTest, SizeReturningNewArrayProto) { + parseAssembly("target datalayout = \"p:64:64:64\"\n" + "declare [2 x i64] @__size_returning_new(i64)\n" + "declare [2 x i64] @__size_returning_new_hot_cold(i64, i8)\n" + "declare [2 x i64] @__size_returning_new_aligned(i64, i64)\n" + "declare [2 x i64] @__size_returning_new_aligned_hot_cold(i64, " + "i64, i8)\n"); + + for (const LibFunc LF : + {LibFunc_size_returning_new, LibFunc_size_returning_new_aligned, + LibFunc_size_returning_new_hot_cold, + LibFunc_size_returning_new_aligned_hot_cold}) { + TLII.setAvailable(LF); + Function *F = M->getFunction(TLI.getName(LF)); + ASSERT_NE(F, nullptr); + EXPECT_TRUE(isLibFunc(F, LF)); + } + + // Invalid array element count or element type. + parseAssembly("target datalayout = \"p:64:64:64\"\n" + "declare [3 x i64] @__size_returning_new(i64)\n" + "declare [1 x i64] @__size_returning_new_hot_cold(i64, i8)\n" + "declare [2 x i32] @__size_returning_new_aligned(i64, i64)\n" + "declare [2 x ptr] @__size_returning_new_aligned_hot_cold(i64, " + "i64, i8)\n"); + + for (const LibFunc LF : + {LibFunc_size_returning_new, LibFunc_size_returning_new_aligned, + LibFunc_size_returning_new_hot_cold, + LibFunc_size_returning_new_aligned_hot_cold}) { + TLII.setAvailable(LF); + Function *F = M->getFunction(TLI.getName(LF)); + ASSERT_NE(F, nullptr); + EXPECT_FALSE(isLibFunc(F, LF)); + } +} + // Check that we do accept know-correct prototypes. TEST_F(TargetLibraryInfoTest, ValidProto) { parseAssembly( _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
