diff options
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r-- | llvm/lib/Analysis/MemoryBuiltins.cpp | 70 |
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); |