Skip to content

Commit c87dba4

Browse files
committed
Enhance TLI detection of __size_returning_new lib funcs.
Previously the return types of __size_returning_new variants were not validated based on their members. This patch checks the members manually, also generalizes the size_t checks to be based on the module instead of being hardcoded.
1 parent cece4ba commit c87dba4

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

llvm/include/llvm/Analysis/TargetLibraryInfo.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,22 +365,22 @@ TLI_DEFINE_SIG_INTERNAL(Ptr, Long, Long, Ptr, Bool)
365365
/// __sized_ptr_t __size_returning_new(size_t size)
366366
TLI_DEFINE_ENUM_INTERNAL(size_returning_new)
367367
TLI_DEFINE_STRING_INTERNAL("__size_returning_new")
368-
TLI_DEFINE_SIG_INTERNAL(Struct, Long)
368+
TLI_DEFINE_SIG_INTERNAL(/* Checked manually. */)
369369

370370
/// __sized_ptr_t __size_returning_new_hot_cold(size_t, __hot_cold_t)
371371
TLI_DEFINE_ENUM_INTERNAL(size_returning_new_hot_cold)
372372
TLI_DEFINE_STRING_INTERNAL("__size_returning_new_hot_cold")
373-
TLI_DEFINE_SIG_INTERNAL(Struct, Long, Bool)
373+
TLI_DEFINE_SIG_INTERNAL(/* Checked manually. */)
374374

375375
/// __sized_ptr_t __size_returning_new_aligned(size_t, std::align_val_t)
376376
TLI_DEFINE_ENUM_INTERNAL(size_returning_new_aligned)
377377
TLI_DEFINE_STRING_INTERNAL("__size_returning_new_aligned")
378-
TLI_DEFINE_SIG_INTERNAL(Struct, Long, Long)
378+
TLI_DEFINE_SIG_INTERNAL(/* Checked manually. */)
379379

380380
/// __sized_ptr_t __size_returning_new_aligned(size_t, std::align_val_t, __hot_cold_t)
381381
TLI_DEFINE_ENUM_INTERNAL(size_returning_new_aligned_hot_cold)
382382
TLI_DEFINE_STRING_INTERNAL("__size_returning_new_aligned_hot_cold")
383-
TLI_DEFINE_SIG_INTERNAL(Struct, Long, Long, Bool)
383+
TLI_DEFINE_SIG_INTERNAL(/* Checked manually. */)
384384

385385
/// double __acos_finite(double x);
386386
TLI_DEFINE_ENUM_INTERNAL(acos_finite)

llvm/lib/Analysis/TargetLibraryInfo.cpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,49 @@ static bool matchType(FuncArgTypeID ArgTy, const Type *Ty, unsigned IntBits,
10491049
llvm_unreachable("Invalid type");
10501050
}
10511051

1052+
static bool isValidProtoForSizeReturningNew(const FunctionType& FTy, LibFunc F, const Module& M, int SizeTSizeBits) {
1053+
switch (F) {
1054+
case LibFunc_size_returning_new: {
1055+
if(FTy.getNumParams() != 1 || !FTy.getParamType(0)->isIntegerTy(SizeTSizeBits)) {
1056+
return false;
1057+
}
1058+
}
1059+
break;
1060+
case LibFunc_size_returning_new_hot_cold: {
1061+
if(FTy.getNumParams() != 2 ||
1062+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits) ||
1063+
!FTy.getParamType(1)->isIntegerTy(8)) {
1064+
return false;
1065+
}
1066+
}
1067+
break;
1068+
case LibFunc_size_returning_new_aligned: {
1069+
if(FTy.getNumParams() !=2 ||
1070+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits) ||
1071+
!FTy.getParamType(1)->isIntegerTy(SizeTSizeBits)) {
1072+
return false;
1073+
}
1074+
}
1075+
break;
1076+
case LibFunc_size_returning_new_aligned_hot_cold:
1077+
if( FTy.getNumParams() != 3 ||
1078+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits) ||
1079+
!FTy.getParamType(1)->isIntegerTy(SizeTSizeBits) ||
1080+
!FTy.getParamType(2)->isIntegerTy(8)) {
1081+
return false;
1082+
}
1083+
break;
1084+
default:
1085+
return false;
1086+
}
1087+
1088+
auto& Context = M.getContext();
1089+
llvm::Type *I8Ty = Type::getInt8Ty(Context);
1090+
llvm::PointerType *I8PtrTy = PointerType::get(I8Ty, 0);
1091+
llvm::StructType *SizedPtrTy = llvm::StructType::get(Context, {I8PtrTy, Type::getIntNTy(Context, SizeTSizeBits)});
1092+
return FTy.getReturnType() == SizedPtrTy;
1093+
}
1094+
10521095
bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
10531096
LibFunc F,
10541097
const Module &M) const {
@@ -1099,7 +1142,13 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
10991142

11001143
return false;
11011144
}
1102-
1145+
// Special handling of __size_returning_new functions that return a struct
1146+
// of type {void*, size_t}.
1147+
case LibFunc_size_returning_new:
1148+
case LibFunc_size_returning_new_hot_cold:
1149+
case LibFunc_size_returning_new_aligned:
1150+
case LibFunc_size_returning_new_aligned_hot_cold:
1151+
return isValidProtoForSizeReturningNew(FTy, F, M, getSizeTSize(M));
11031152
default:
11041153
break;
11051154
}

llvm/unittests/Analysis/TargetLibraryInfoTest.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "llvm/Analysis/TargetLibraryInfo.h"
1010
#include "llvm/AsmParser/Parser.h"
11+
#include "llvm/IR/DerivedTypes.h"
1112
#include "llvm/IR/LLVMContext.h"
1213
#include "llvm/IR/Module.h"
1314
#include "llvm/Support/SourceMgr.h"
@@ -81,6 +82,30 @@ TEST_F(TargetLibraryInfoTest, InvalidProto) {
8182
}
8283
}
8384

85+
TEST_F(TargetLibraryInfoTest, SizeReturningNewProto) {
86+
parseAssembly("target datalayout = \"p:64:64:64\"\n"
87+
"declare {i8*, i64} @__size_returning_new(i64)\n"
88+
"declare {i8*, i64} @__size_returning_new_hot_cold(i64, i8)\n"
89+
"declare {i8*, i64} @__size_returning_new_aligned(i64, i64)\n"
90+
"declare {i8*, i64} "
91+
"@__size_returning_new_aligned_hot_cold(i64, i64, i8)\n");
92+
93+
llvm::Type *I8Ty = Type::getInt8Ty(Context);
94+
llvm::PointerType *I8PtrTy = PointerType::get(I8Ty, 0);
95+
llvm::StructType *SizedPtrT =
96+
llvm::StructType::get(Context, {I8PtrTy, Type::getInt64Ty(Context)});
97+
98+
for (const LibFunc LF :
99+
{LibFunc_size_returning_new, LibFunc_size_returning_new_aligned,
100+
LibFunc_size_returning_new_hot_cold,
101+
LibFunc_size_returning_new_aligned_hot_cold}) {
102+
TLII.setAvailable(LF);
103+
Function *F = M->getFunction(TLI.getName(LF));
104+
ASSERT_NE(F, nullptr);
105+
EXPECT_EQ(F->getReturnType(), SizedPtrT);
106+
}
107+
}
108+
84109
// Check that we do accept know-correct prototypes.
85110
TEST_F(TargetLibraryInfoTest, ValidProto) {
86111
parseAssembly(
@@ -472,10 +497,11 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
472497
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
473498
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64, i64, "
474499
"%struct*, i8)\n"
475-
"declare %struct @__size_returning_new(i64)\n"
476-
"declare %struct @__size_returning_new_hot_cold(i64, i8)\n"
477-
"declare %struct @__size_returning_new_aligned(i64, i64)\n"
478-
"declare %struct @__size_returning_new_aligned_hot_cold(i64, i64, i8)\n"
500+
"declare {i8*, i64} @__size_returning_new(i64)\n"
501+
"declare {i8*, i64} @__size_returning_new_hot_cold(i64, i8)\n"
502+
"declare {i8*, i64} @__size_returning_new_aligned(i64, i64)\n"
503+
"declare {i8*, i64} @__size_returning_new_aligned_hot_cold(i64, i64, "
504+
"i8)\n"
479505

480506
"declare void @\"??3@YAXPEAX@Z\"(i8*)\n"
481507
"declare void @\"??3@YAXPEAXAEBUnothrow_t@std@@@Z\"(i8*, %struct*)\n"

0 commit comments

Comments
 (0)