summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp70
1 files changed, 47 insertions, 23 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 427e6fd3ace24..0b61b1c0eabd7 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -52,11 +52,12 @@ using namespace llvm;
enum AllocType : uint8_t {
OpNewLike = 1<<0, // allocates; never returns null
MallocLike = 1<<1 | OpNewLike, // allocates; may return null
- CallocLike = 1<<2, // allocates + bzero
- ReallocLike = 1<<3, // reallocates
- StrDupLike = 1<<4,
- MallocOrCallocLike = MallocLike | CallocLike,
- AllocLike = MallocLike | CallocLike | StrDupLike,
+ AlignedAllocLike = 1<<2, // allocates with alignment; may return null
+ CallocLike = 1<<3, // allocates + bzero
+ ReallocLike = 1<<4, // reallocates
+ StrDupLike = 1<<5,
+ MallocOrCallocLike = MallocLike | CallocLike | AlignedAllocLike,
+ AllocLike = MallocOrCallocLike | StrDupLike,
AnyAlloc = AllocLike | ReallocLike
};
@@ -100,6 +101,7 @@ static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
{LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow)
{LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long)
{LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow)
+ {LibFunc_aligned_alloc, {AlignedAllocLike, 2, 1, -1}},
{LibFunc_calloc, {CallocLike, 2, 0, 1}},
{LibFunc_realloc, {ReallocLike, 2, 1, -1}},
{LibFunc_reallocf, {ReallocLike, 2, 1, -1}},
@@ -117,13 +119,13 @@ static const Function *getCalledFunction(const Value *V, bool LookThroughBitCast
if (LookThroughBitCast)
V = V->stripPointerCasts();
- ImmutableCallSite CS(V);
- if (!CS.getInstruction())
+ const auto *CB = dyn_cast<CallBase>(V);
+ if (!CB)
return nullptr;
- IsNoBuiltin = CS.isNoBuiltin();
+ IsNoBuiltin = CB->isNoBuiltin();
- if (const Function *Callee = CS.getCalledFunction())
+ if (const Function *Callee = CB->getCalledFunction())
return Callee;
return nullptr;
}
@@ -225,8 +227,9 @@ static Optional<AllocFnsTy> getAllocationSize(const Value *V,
}
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
- ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
- return CS && CS.hasRetAttr(Attribute::NoAlias);
+ const auto *CB =
+ dyn_cast<CallBase>(LookThroughBitCast ? V->stripPointerCasts() : V);
+ return CB && CB->hasRetAttr(Attribute::NoAlias);
}
/// Tests if a value is a call or invoke to a library function that
@@ -266,6 +269,20 @@ bool llvm::isMallocLikeFn(
}
/// Tests if a value is a call or invoke to a library function that
+/// allocates uninitialized memory with alignment (such as aligned_alloc).
+bool llvm::isAlignedAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast) {
+ return getAllocationData(V, AlignedAllocLike, TLI, LookThroughBitCast)
+ .hasValue();
+}
+bool llvm::isAlignedAllocLikeFn(
+ const Value *V, function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ bool LookThroughBitCast) {
+ return getAllocationData(V, AlignedAllocLike, GetTLI, LookThroughBitCast)
+ .hasValue();
+}
+
+/// Tests if a value is a call or invoke to a library function that
/// allocates zero-filled memory (such as calloc).
bool llvm::isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast) {
@@ -439,7 +456,11 @@ bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow)
ExpectedNumParams = 2;
else if (TLIFn == LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t || // delete(void*, align_val_t, nothrow)
- TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
+ TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t || // delete[](void*, align_val_t, nothrow)
+ TLIFn == LibFunc_ZdlPvjSt11align_val_t || // delete(void*, unsigned long, align_val_t)
+ TLIFn == LibFunc_ZdlPvmSt11align_val_t || // delete(void*, unsigned long, align_val_t)
+ TLIFn == LibFunc_ZdaPvjSt11align_val_t || // delete[](void*, unsigned int, align_val_t)
+ TLIFn == LibFunc_ZdaPvmSt11align_val_t) // delete[](void*, unsigned long, align_val_t)
ExpectedNumParams = 3;
else
return false;
@@ -633,6 +654,9 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
if (!I.getAllocatedType()->isSized())
return unknown();
+ if (isa<ScalableVectorType>(I.getAllocatedType()))
+ return unknown();
+
APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
if (!I.isArrayAllocation())
return std::make_pair(align(Size, I.getAlignment()), Zero);
@@ -653,7 +677,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
// No interprocedural analysis is done at the moment.
- if (!A.hasByValOrInAllocaAttr()) {
+ if (!A.hasPassPointeeByValueAttr()) {
++ObjectVisitorArgument;
return unknown();
}
@@ -662,21 +686,21 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
return std::make_pair(align(Size, A.getParamAlignment()), Zero);
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
- Optional<AllocFnsTy> FnData = getAllocationSize(CS.getInstruction(), TLI);
+SizeOffsetType ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
+ Optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
if (!FnData)
return unknown();
// Handle strdup-like functions separately.
if (FnData->AllocTy == StrDupLike) {
- APInt Size(IntTyBits, GetStringLength(CS.getArgument(0)));
+ APInt Size(IntTyBits, GetStringLength(CB.getArgOperand(0)));
if (!Size)
return unknown();
// Strndup limits strlen.
if (FnData->FstParam > 0) {
ConstantInt *Arg =
- dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
+ dyn_cast<ConstantInt>(CB.getArgOperand(FnData->FstParam));
if (!Arg)
return unknown();
@@ -687,7 +711,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
return std::make_pair(Size, Zero);
}
- ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
+ ConstantInt *Arg = dyn_cast<ConstantInt>(CB.getArgOperand(FnData->FstParam));
if (!Arg)
return unknown();
@@ -699,7 +723,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
if (FnData->SndParam < 0)
return std::make_pair(Size, Zero);
- Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->SndParam));
+ Arg = dyn_cast<ConstantInt>(CB.getArgOperand(FnData->SndParam));
if (!Arg)
return unknown();
@@ -927,8 +951,8 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
return std::make_pair(Size, Zero);
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
- Optional<AllocFnsTy> FnData = getAllocationSize(CS.getInstruction(), TLI);
+SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {
+ Optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
if (!FnData)
return unknown();
@@ -938,12 +962,12 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
return unknown();
}
- Value *FirstArg = CS.getArgument(FnData->FstParam);
+ Value *FirstArg = CB.getArgOperand(FnData->FstParam);
FirstArg = Builder.CreateZExtOrTrunc(FirstArg, IntTy);
if (FnData->SndParam < 0)
return std::make_pair(FirstArg, Zero);
- Value *SecondArg = CS.getArgument(FnData->SndParam);
+ Value *SecondArg = CB.getArgOperand(FnData->SndParam);
SecondArg = Builder.CreateZExtOrTrunc(SecondArg, IntTy);
Value *Size = Builder.CreateMul(FirstArg, SecondArg);
return std::make_pair(Size, Zero);