[clang] 4f2421f - [TLI][SimplifyLibCalls] Accept [2 x iN] return type for __size_returing_new (#234856)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 24 11:27:30 PDT 2026
Author: Snehasish Kumar
Date: 2026-10-24T18:27:23Z
New Revision: 4f2421fb77137dd7cbd72e530670fda96f742f90
URL: https://github.com/llvm/llvm-project/commit/4f2421fb77137dd7cbd72e530670fda96f742f90
DIFF: https://github.com/llvm/llvm-project/commit/4f2421fb77137dd7cbd72e530670fda96f742f90.diff
LOG: [TLI][SimplifyLibCalls] Accept [2 x iN] return type for __size_returing_new (#234856)
On AArch64 (AAPCS64), Clang lowers `struct __sized_ptr_t { void *p;
size_t n; }` as `[2 x i64]` (`llvm::ArrayType`), whereas on x86_64 it is
lowered as `{ ptr, i64 }` (`llvm::StructType`).
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]`.
Assisted-by: Gemini Argon
Added:
Modified:
clang/test/CodeGen/alloc-token-lower.c
llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
llvm/lib/Analysis/TargetLibraryInfo.cpp
llvm/lib/Transforms/Utils/BuildLibCalls.cpp
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/test/Instrumentation/AllocToken/extralibfuncs.ll
llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll
llvm/test/Transforms/PGOProfile/memprof_match_hot_cold_new_calls.ll
llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
Removed:
################################################################################
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(
More information about the cfe-commits
mailing list