Skip to content

Commit 1ccd7ab

Browse files
authored
Enhance TLI detection of __size_returning_new lib funcs. (#102391)
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. As requested in followup comment on #101564.
1 parent ee23599 commit 1ccd7ab

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-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,
1053+
const Module &M,
1054+
int SizeTSizeBits) {
1055+
switch (F) {
1056+
case LibFunc_size_returning_new: {
1057+
if (FTy.getNumParams() != 1 ||
1058+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits)) {
1059+
return false;
1060+
}
1061+
} break;
1062+
case LibFunc_size_returning_new_hot_cold: {
1063+
if (FTy.getNumParams() != 2 ||
1064+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits) ||
1065+
!FTy.getParamType(1)->isIntegerTy(8)) {
1066+
return false;
1067+
}
1068+
} break;
1069+
case LibFunc_size_returning_new_aligned: {
1070+
if (FTy.getNumParams() != 2 ||
1071+
!FTy.getParamType(0)->isIntegerTy(SizeTSizeBits) ||
1072+
!FTy.getParamType(1)->isIntegerTy(SizeTSizeBits)) {
1073+
return false;
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+
PointerType *PtrTy = PointerType::get(Context, 0);
1090+
StructType *SizedPtrTy = StructType::get(
1091+
Context, {PtrTy, 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: 29 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,29 @@ TEST_F(TargetLibraryInfoTest, InvalidProto) {
8182
}
8283
}
8384

85+
TEST_F(TargetLibraryInfoTest, SizeReturningNewInvalidProto) {
86+
parseAssembly(
87+
"target datalayout = \"p:64:64:64\"\n"
88+
";; Invalid additional params \n"
89+
"declare {i8*, i64} @__size_returning_new(i64, i64)\n"
90+
";; Invalid params types \n"
91+
"declare {i8*, i64} @__size_returning_new_hot_cold(i64, i32)\n"
92+
";; Invalid return struct types \n"
93+
"declare {i8*, i8} @__size_returning_new_aligned(i64, i64)\n"
94+
";; Invalid return type \n"
95+
"declare i8* @__size_returning_new_aligned_hot_cold(i64, i64, i8)\n");
96+
97+
for (const LibFunc LF :
98+
{LibFunc_size_returning_new, LibFunc_size_returning_new_aligned,
99+
LibFunc_size_returning_new_hot_cold,
100+
LibFunc_size_returning_new_aligned_hot_cold}) {
101+
TLII.setAvailable(LF);
102+
Function *F = M->getFunction(TLI.getName(LF));
103+
ASSERT_NE(F, nullptr);
104+
EXPECT_FALSE(isLibFunc(F, LF));
105+
}
106+
}
107+
84108
// Check that we do accept know-correct prototypes.
85109
TEST_F(TargetLibraryInfoTest, ValidProto) {
86110
parseAssembly(
@@ -472,10 +496,11 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
472496
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
473497
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64, i64, "
474498
"%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"
499+
"declare {i8*, i64} @__size_returning_new(i64)\n"
500+
"declare {i8*, i64} @__size_returning_new_hot_cold(i64, i8)\n"
501+
"declare {i8*, i64} @__size_returning_new_aligned(i64, i64)\n"
502+
"declare {i8*, i64} @__size_returning_new_aligned_hot_cold(i64, i64, "
503+
"i8)\n"
479504

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

0 commit comments

Comments
 (0)