[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