LLVM 24.0.0git
MemoryBuiltins.cpp
Go to the documentation of this file.
1//===- MemoryBuiltins.cpp - Identify calls to memory builtins -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This family of functions identifies calls to builtin functions that allocate
10// or free memory.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/APInt.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/Statistic.h"
23#include "llvm/IR/Argument.h"
24#include "llvm/IR/Attributes.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/DataLayout.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/GlobalAlias.h"
31#include "llvm/IR/Instruction.h"
34#include "llvm/IR/Operator.h"
36#include "llvm/IR/Type.h"
37#include "llvm/IR/Value.h"
40#include "llvm/Support/Debug.h"
43#include <cassert>
44#include <cstdint>
45#include <iterator>
46#include <numeric>
47#include <optional>
48#include <utility>
49
50using namespace llvm;
51
52#define DEBUG_TYPE "memory-builtins"
53
54namespace llvm {
56}
57
59 "object-size-offset-visitor-max-visit-instructions",
60 cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to "
61 "look at"),
62 cl::init(100));
63
64// clang-format off
66 OpNewLike = 1<<0, // allocates; never returns null
67 MallocLike = 1<<1, // allocates; may return null
68 StrDupLike = 1<<2,
72};
73
74enum class MallocFamily {
76 CPPNew, // new(unsigned int)
77 CPPNewAligned, // new(unsigned int, align_val_t)
78 CPPNewArray, // new[](unsigned int)
79 CPPNewArrayAligned, // new[](unsigned long, align_val_t)
80 MSVCNew, // new(unsigned int)
81 MSVCArrayNew, // new[](unsigned int)
83};
84// clang-format on
85
87 switch (Family) {
89 return "malloc";
91 return "_Znwm";
93 return "_ZnwmSt11align_val_t";
95 return "_Znam";
97 return "_ZnamSt11align_val_t";
99 return "??2@YAPAXI@Z";
101 return "??_U@YAPAXI@Z";
103 return "vec_malloc";
104 }
105 llvm_unreachable("missing an alloc family");
106}
107
110 unsigned NumParams;
111 // First and Second size parameters (or -1 if unused)
113 // Alignment parameter for aligned_alloc and aligned new
115 // Name of default allocator function to group malloc/free calls by family
117};
118
119// clang-format off
120// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
121// know which functions are nounwind, noalias, nocapture parameters, etc.
122static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
123 {LibFunc_Znwj, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int)
124 {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int, nothrow)
125 {LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned int, align_val_t)
126 {LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned int, align_val_t, nothrow)
127 {LibFunc_Znwm, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long)
128 {LibFunc_Znwm12__hot_cold_t, {OpNewLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long, __hot_cold_t)
129 {LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long, nothrow)
130 {LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, {MallocLike, 3, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long, nothrow, __hot_cold_t)
131 {LibFunc_ZnwmSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t)
132 {LibFunc_ZnwmSt11align_val_t12__hot_cold_t, {OpNewLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t, __hot_cold_t)
133 {LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t, nothrow)
134 {LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, {MallocLike, 4, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t, nothrow, __hot_cold_t)
135 {LibFunc_Znaj, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned int)
136 {LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned int, nothrow)
137 {LibFunc_ZnajSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned int, align_val_t)
138 {LibFunc_ZnajSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned int, align_val_t, nothrow)
139 {LibFunc_Znam, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned long)
140 {LibFunc_Znam12__hot_cold_t, {OpNewLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new[](unsigned long, __hot_cold_t)
141 {LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned long, nothrow)
142 {LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, {MallocLike, 3, 0, -1, -1, MallocFamily::CPPNew}}, // new[](unsigned long, nothrow, __hot_cold_t)
143 {LibFunc_ZnamSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned long, align_val_t)
144 {LibFunc_ZnamSt11align_val_t12__hot_cold_t, {OpNewLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new[](unsigned long, align_val_t, __hot_cold_t)
145 {LibFunc_ZnamSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned long, align_val_t, nothrow)
146 {LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, {MallocLike, 4, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new[](unsigned long, align_val_t, nothrow, __hot_cold_t)
147 {LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned int)
148 {LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned int, nothrow)
149 {LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned long long)
150 {LibFunc_msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned long long, nothrow)
151 {LibFunc_msvc_new_array_int, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned int)
152 {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned int, nothrow)
153 {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long)
154 {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long, nothrow)
155 {LibFunc_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}},
156 {LibFunc_dunder_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}},
157 {LibFunc_strndup, {StrDupLike, 2, 1, -1, -1, MallocFamily::Malloc}},
158 {LibFunc_dunder_strndup, {StrDupLike, 2, 1, -1, -1, MallocFamily::Malloc}},
159};
160// clang-format on
161
162static const Function *getCalledFunction(const Value *V) {
163 // Don't care about intrinsics in this case.
165 return nullptr;
166
167 const auto *CB = dyn_cast<CallBase>(V);
168 if (!CB)
169 return nullptr;
170
171 if (CB->isNoBuiltin())
172 return nullptr;
173
174 return CB->getCalledFunction();
175}
176
177/// Returns the allocation data for the given value if it's a call to a known
178/// allocation function.
179static std::optional<AllocFnsTy>
181 const TargetLibraryInfo *TLI) {
182 // Don't perform a slow TLI lookup, if this function doesn't return a pointer
183 // and thus can't be an allocation function.
184 if (!Callee->getReturnType()->isPointerTy())
185 return std::nullopt;
186
187 // Make sure that the function is available.
188 if (!TLI)
189 return std::nullopt;
190
191 LibFunc TLIFn = TLI->getLibFunc(*Callee);
192 if (!TLI->has(TLIFn))
193 return std::nullopt;
194
195 const auto *Iter = find_if(AllocationFnData,
196 [TLIFn](const std::pair<LibFunc, AllocFnsTy> &P) {
197 return P.first == TLIFn;
198 });
199
200 if (Iter == std::end(AllocationFnData))
201 return std::nullopt;
202
203 const AllocFnsTy *FnData = &Iter->second;
204 if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
205 return std::nullopt;
206
207 // Check function prototype.
208 int FstParam = FnData->FstParam;
209 int SndParam = FnData->SndParam;
210 FunctionType *FTy = Callee->getFunctionType();
211
212 if (FTy->getReturnType()->isPointerTy() &&
213 FTy->getNumParams() == FnData->NumParams &&
214 (FstParam < 0 || (FTy->getParamType(FstParam)->isIntegerTy(32) ||
215 FTy->getParamType(FstParam)->isIntegerTy(64))) &&
216 (SndParam < 0 || FTy->getParamType(SndParam)->isIntegerTy(32) ||
217 FTy->getParamType(SndParam)->isIntegerTy(64)))
218 return *FnData;
219 return std::nullopt;
220}
221
222static std::optional<AllocFnsTy>
224 const TargetLibraryInfo *TLI) {
225 if (const Function *Callee = getCalledFunction(V))
226 return getAllocationDataForFunction(Callee, AllocTy, TLI);
227 return std::nullopt;
228}
229
230static std::optional<AllocFnsTy>
232 function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
233 if (const Function *Callee = getCalledFunction(V))
235 Callee, AllocTy, &GetTLI(const_cast<Function &>(*Callee)));
236 return std::nullopt;
237}
238
239static std::optional<AllocFnsTy>
241 if (const Function *Callee = getCalledFunction(CB)) {
242 // Prefer to use existing information over allocsize. This will give us an
243 // accurate AllocTy.
244 if (std::optional<AllocFnsTy> Data =
246 return Data;
247 }
248
249 Attribute Attr = CB->getFnAttr(Attribute::AllocSize);
250 if (Attr == Attribute())
251 return std::nullopt;
252
253 std::pair<unsigned, std::optional<unsigned>> Args = Attr.getAllocSizeArgs();
254
255 AllocFnsTy Result;
256 // Because allocsize only tells us how many bytes are allocated, we're not
257 // really allowed to assume anything, so we use MallocLike.
258 Result.AllocTy = MallocLike;
259 Result.NumParams = CB->arg_size();
260 Result.FstParam = Args.first;
261 Result.SndParam = Args.second.value_or(-1);
262 // Allocsize has no way to specify an alignment argument
263 Result.AlignParam = -1;
264 return Result;
265}
266
268 if (const auto *CB = dyn_cast<CallBase>(V)) {
269 Attribute Attr = CB->getFnAttr(Attribute::AllocKind);
270 if (Attr.isValid())
271 return AllocFnKind(Attr.getValueAsInt());
272 }
274}
275
277 return F->getAttributes().getAllocKind();
278}
279
280static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted) {
281 return (getAllocFnKind(V) & Wanted) != AllocFnKind::Unknown;
282}
283
284static bool checkFnAllocKind(const Function *F, AllocFnKind Wanted) {
285 return (getAllocFnKind(F) & Wanted) != AllocFnKind::Unknown;
286}
287
288/// Tests if a value is a call or invoke to a library function that
289/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
290/// like).
292 // Allocation calls must return ptr. Exit early if this doesn't.
293 if (!V->getType()->isPointerTy())
294 return false;
295 return getAllocationData(V, AnyAlloc, TLI).has_value() ||
297}
299 const Value *V,
300 function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
301 // Allocation calls must return ptr. Exit early if this doesn't.
302 if (!V->getType()->isPointerTy())
303 return false;
304 return getAllocationData(V, AnyAlloc, GetTLI).has_value() ||
306}
307
308/// Tests if a value is a call or invoke to a library function that
309/// allocates memory (either malloc, calloc, or strdup like).
311 // Allocation calls must return ptr. Exit early if this doesn't.
312 if (!V->getType()->isPointerTy())
313 return false;
314 return getAllocationData(V, AllocLike, TLI).has_value() ||
316}
317
318/// Tests if a functions is a call or invoke to a library function that
319/// reallocates memory (e.g., realloc).
323
326 return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
327 return nullptr;
328}
329
331 // Note: Removability is highly dependent on the source language. For
332 // example, recent C++ requires direct calls to the global allocation
333 // [basic.stc.dynamic.allocation] to be observable unless part of a new
334 // expression [expr.new paragraph 13].
335
336 // Historically we've treated the C family allocation routines and operator
337 // new as removable
338 return isAllocLikeFn(CB, TLI);
339}
340
342 const TargetLibraryInfo *TLI) {
343 const std::optional<AllocFnsTy> FnData = getAllocationData(V, AnyAlloc, TLI);
344 if (FnData && FnData->AlignParam >= 0) {
345 return V->getOperand(FnData->AlignParam);
346 }
347 return V->getArgOperandWithAttribute(Attribute::AllocAlign);
348}
349
350/// When we're compiling N-bit code, and the user uses parameters that are
351/// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
352/// trouble with APInt size issues. This function handles resizing + overflow
353/// checks for us. Check and zext or trunc \p I depending on IntTyBits and
354/// I's value.
355static bool checkedZextOrTrunc(APInt &I, unsigned IntTyBits) {
356 // More bits than we can handle. Checking the bit width isn't necessary, but
357 // it's faster than checking active bits, and should give `false` in the
358 // vast majority of cases.
359 if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
360 return false;
361 if (I.getBitWidth() != IntTyBits)
362 I = I.zextOrTrunc(IntTyBits);
363 return true;
364}
365
366std::optional<APInt>
368 function_ref<const Value *(const Value *)> Mapper) {
369 // Note: This handles both explicitly listed allocation functions and
370 // allocsize. The code structure could stand to be cleaned up a bit.
371 std::optional<AllocFnsTy> FnData = getAllocationSize(CB, TLI);
372 if (!FnData)
373 return std::nullopt;
374
375 // Get the index type for this address space, results and intermediate
376 // computations are performed at that width.
377 auto &DL = CB->getDataLayout();
378 const unsigned IntTyBits = DL.getIndexTypeSizeInBits(CB->getType());
379
380 // Handle strdup-like functions separately.
381 if (FnData->AllocTy == StrDupLike) {
382 APInt Size(IntTyBits, GetStringLength(Mapper(CB->getArgOperand(0))));
383 if (!Size)
384 return std::nullopt;
385
386 // Strndup limits strlen.
387 if (FnData->FstParam > 0) {
388 const ConstantInt *Arg =
389 dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
390 if (!Arg)
391 return std::nullopt;
392
393 APInt MaxSize = Arg->getValue().zext(IntTyBits);
394 if (Size.ugt(MaxSize))
395 Size = MaxSize + 1;
396 }
397 return Size;
398 }
399
400 const ConstantInt *Arg =
401 dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
402 if (!Arg)
403 return std::nullopt;
404
405 APInt Size = Arg->getValue();
406 if (!checkedZextOrTrunc(Size, IntTyBits))
407 return std::nullopt;
408
409 // Size is determined by just 1 parameter.
410 if (FnData->SndParam < 0)
411 return Size;
412
413 Arg = dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->SndParam)));
414 if (!Arg)
415 return std::nullopt;
416
417 APInt NumElems = Arg->getValue();
418 if (!checkedZextOrTrunc(NumElems, IntTyBits))
419 return std::nullopt;
420
421 bool Overflow;
422 Size = Size.umul_ov(NumElems, Overflow);
423 if (Overflow)
424 return std::nullopt;
425 return Size;
426}
427
429 const TargetLibraryInfo *TLI,
430 Type *Ty) {
431 if (isa<AllocaInst>(V))
432 return UndefValue::get(Ty);
433
434 auto *Alloc = dyn_cast<CallBase>(V);
435 if (!Alloc)
436 return nullptr;
437
438 // malloc are uninitialized (undef)
439 if (getAllocationData(Alloc, MallocOrOpNewLike, TLI).has_value())
440 return UndefValue::get(Ty);
441
444 return UndefValue::get(Ty);
446 return Constant::getNullValue(Ty);
447
448 return nullptr;
449}
450
451struct FreeFnsTy {
452 unsigned NumParams;
453 // Name of default allocator function to group malloc/free calls by family
455};
456
457// clang-format off
458static const std::pair<LibFunc, FreeFnsTy> FreeFnData[] = {
459 {LibFunc_ZdlPv, {1, MallocFamily::CPPNew}}, // operator delete(void*)
460 {LibFunc_ZdaPv, {1, MallocFamily::CPPNewArray}}, // operator delete[](void*)
461 {LibFunc_msvc_delete_ptr32, {1, MallocFamily::MSVCNew}}, // operator delete(void*)
462 {LibFunc_msvc_delete_ptr64, {1, MallocFamily::MSVCNew}}, // operator delete(void*)
463 {LibFunc_msvc_delete_array_ptr32, {1, MallocFamily::MSVCArrayNew}}, // operator delete[](void*)
464 {LibFunc_msvc_delete_array_ptr64, {1, MallocFamily::MSVCArrayNew}}, // operator delete[](void*)
465 {LibFunc_ZdlPvj, {2, MallocFamily::CPPNew}}, // delete(void*, uint)
466 {LibFunc_ZdlPvm, {2, MallocFamily::CPPNew}}, // delete(void*, ulong)
467 {LibFunc_ZdlPvRKSt9nothrow_t, {2, MallocFamily::CPPNew}}, // delete(void*, nothrow)
468 {LibFunc_ZdlPvSt11align_val_t, {2, MallocFamily::CPPNewAligned}}, // delete(void*, align_val_t)
469 {LibFunc_ZdaPvj, {2, MallocFamily::CPPNewArray}}, // delete[](void*, uint)
470 {LibFunc_ZdaPvm, {2, MallocFamily::CPPNewArray}}, // delete[](void*, ulong)
471 {LibFunc_ZdaPvRKSt9nothrow_t, {2, MallocFamily::CPPNewArray}}, // delete[](void*, nothrow)
472 {LibFunc_ZdaPvSt11align_val_t, {2, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, align_val_t)
473 {LibFunc_msvc_delete_ptr32_int, {2, MallocFamily::MSVCNew}}, // delete(void*, uint)
474 {LibFunc_msvc_delete_ptr64_longlong, {2, MallocFamily::MSVCNew}}, // delete(void*, ulonglong)
475 {LibFunc_msvc_delete_ptr32_nothrow, {2, MallocFamily::MSVCNew}}, // delete(void*, nothrow)
476 {LibFunc_msvc_delete_ptr64_nothrow, {2, MallocFamily::MSVCNew}}, // delete(void*, nothrow)
477 {LibFunc_msvc_delete_array_ptr32_int, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, uint)
478 {LibFunc_msvc_delete_array_ptr64_longlong, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, ulonglong)
479 {LibFunc_msvc_delete_array_ptr32_nothrow, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, nothrow)
480 {LibFunc_msvc_delete_array_ptr64_nothrow, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, nothrow)
481 {LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, align_val_t, nothrow)
482 {LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, align_val_t, nothrow)
483 {LibFunc_ZdlPvjSt11align_val_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, unsigned int, align_val_t)
484 {LibFunc_ZdlPvmSt11align_val_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, unsigned long, align_val_t)
485 {LibFunc_ZdaPvjSt11align_val_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, unsigned int, align_val_t)
486 {LibFunc_ZdaPvmSt11align_val_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, unsigned long, align_val_t)
487};
488// clang-format on
489
490static std::optional<FreeFnsTy>
491getFreeFunctionDataForFunction(const Function *Callee, const LibFunc TLIFn) {
492 const auto *Iter =
493 find_if(FreeFnData, [TLIFn](const std::pair<LibFunc, FreeFnsTy> &P) {
494 return P.first == TLIFn;
495 });
496 if (Iter == std::end(FreeFnData))
497 return std::nullopt;
498 return Iter->second;
499}
500
501std::optional<StringRef>
503 if (const Function *Callee = getCalledFunction(I)) {
504 LibFunc TLIFn = TLI ? TLI->getLibFunc(*Callee) : NotLibFunc;
505 if (TLIFn != NotLibFunc && TLI->has(TLIFn)) {
506 // Callee is some known library function.
507 const auto AllocData =
509 if (AllocData)
510 return mangledNameForMallocFamily(AllocData->Family);
511 const auto FreeData = getFreeFunctionDataForFunction(Callee, TLIFn);
512 if (FreeData)
513 return mangledNameForMallocFamily(FreeData->Family);
514 }
515 }
516
517 // Callee isn't a known library function, still check attributes.
520 Attribute Attr = cast<CallBase>(I)->getFnAttr("alloc-family");
521 if (Attr.isValid())
522 return Attr.getValueAsString();
523 }
524 return std::nullopt;
525}
526
527/// isLibFreeFunction - Returns true if the function is a builtin free()
528bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
529 std::optional<FreeFnsTy> FnData = getFreeFunctionDataForFunction(F, TLIFn);
530 if (!FnData)
532
533 // Check free prototype.
534 // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
535 // attribute will exist.
536 FunctionType *FTy = F->getFunctionType();
537 if (!FTy->getReturnType()->isVoidTy())
538 return false;
539 if (FTy->getNumParams() != FnData->NumParams)
540 return false;
541 if (!FTy->getParamType(0)->isPointerTy())
542 return false;
543
544 return true;
545}
546
548 // Exit early for functions which don't return void. The allockind("free")
549 // attribute requires this, and it's much cheaper to check that TLI.
550 if (!CB->getType()->isVoidTy())
551 return nullptr;
552
553 if (const Function *Callee = getCalledFunction(CB)) {
554 LibFunc TLIFn = TLI ? TLI->getLibFunc(*Callee) : NotLibFunc;
555 if (TLIFn != NotLibFunc && TLI->has(TLIFn) &&
556 isLibFreeFunction(Callee, TLIFn)) {
557 // All currently supported free functions free the first argument.
558 return CB->getArgOperand(0);
559 }
560 }
561
563 return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
564
565 return nullptr;
566}
567
568//===----------------------------------------------------------------------===//
569// Utility functions to compute size of objects.
570//
572 APInt Size = Data.Size;
573 APInt Offset = Data.Offset;
574
575 if (Offset.isNegative() || Size.ult(Offset))
576 return APInt::getZero(Size.getBitWidth());
577
578 return Size - Offset;
579}
580
581/// Compute the size of the object pointed by Ptr. Returns true and the
582/// object size in Size if successful, and false otherwise.
583/// If RoundToAlign is true, then Size is rounded up to the alignment of
584/// allocas, byval arguments, and global variables.
585bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
586 const TargetLibraryInfo *TLI, ObjectSizeOpts Opts) {
587 ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(), Opts);
588 SizeOffsetAPInt Data = Visitor.compute(const_cast<Value *>(Ptr));
589 if (!Data.bothKnown())
590 return false;
591
593 return true;
594}
595
596std::optional<TypeSize> llvm::getBaseObjectSize(const Value *Ptr,
597 const DataLayout &DL,
598 const TargetLibraryInfo *TLI,
599 ObjectSizeOpts Opts) {
601 "Other modes are currently not supported");
602
603 auto Align = [&](TypeSize Size, MaybeAlign Alignment) {
604 if (Opts.RoundToAlign && Alignment && !Size.isScalable())
605 return TypeSize::getFixed(alignTo(Size.getFixedValue(), *Alignment));
606 return Size;
607 };
608
609 if (isa<UndefValue>(Ptr))
610 return TypeSize::getZero();
611
612 if (isa<ConstantPointerNull>(Ptr)) {
614 return std::nullopt;
615 return TypeSize::getZero();
616 }
617
618 if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
619 if (!GV->getValueType()->isSized() || GV->hasExternalWeakLinkage() ||
620 !GV->hasInitializer() || GV->isInterposable())
621 return std::nullopt;
622 return Align(TypeSize::getFixed(GV->getGlobalSize(DL)), GV->getAlign());
623 }
624
625 if (auto *A = dyn_cast<Argument>(Ptr)) {
626 Type *MemoryTy = A->getPointeeInMemoryValueType();
627 if (!MemoryTy || !MemoryTy->isSized())
628 return std::nullopt;
629 return Align(DL.getTypeAllocSize(MemoryTy), A->getParamAlign());
630 }
631
632 if (auto *AI = dyn_cast<AllocaInst>(Ptr)) {
633 if (std::optional<TypeSize> Size = AI->getAllocationSize(DL))
634 return Align(*Size, AI->getAlign());
635 return std::nullopt;
636 }
637
638 if (auto *CB = dyn_cast<CallBase>(Ptr)) {
639 if (std::optional<APInt> Size = getAllocSize(CB, TLI)) {
640 if (std::optional<uint64_t> ZExtSize = Size->tryZExtValue())
641 return TypeSize::getFixed(*ZExtSize);
642 }
643 return std::nullopt;
644 }
645
646 return std::nullopt;
647}
648
650 const DataLayout &DL,
651 const TargetLibraryInfo *TLI,
652 bool MustSucceed) {
653 return lowerObjectSizeCall(ObjectSize, DL, TLI, /*AAResults=*/nullptr,
654 MustSucceed);
655}
656
658 IntrinsicInst *ObjectSize, const DataLayout &DL,
659 const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
660 SmallVectorImpl<Instruction *> *InsertedInstructions) {
661 assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
662 "ObjectSize must be a call to llvm.objectsize!");
663
664 bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(1))->isZero();
665 ObjectSizeOpts EvalOptions;
666 EvalOptions.AA = AA;
667
668 // Unless we have to fold this to something, try to be as accurate as
669 // possible.
670 if (MustSucceed)
671 EvalOptions.EvalMode =
673 else
675
676 EvalOptions.NullIsUnknownSize =
677 cast<ConstantInt>(ObjectSize->getArgOperand(2))->isOne();
678
679 auto *ResultType = cast<IntegerType>(ObjectSize->getType());
680 bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(3))->isZero();
681 if (StaticOnly) {
682 // FIXME: Does it make sense to just return a failure value if the size
683 // won't fit in the output and `!MustSucceed`?
684 uint64_t Size;
685 if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI,
686 EvalOptions) &&
687 isUIntN(ResultType->getBitWidth(), Size))
688 return ConstantInt::get(ResultType, Size);
689 } else {
690 ObjectSizeOffsetEvaluator Eval(*ObjectSize->getModule(), TLI, EvalOptions);
691 SizeOffsetValue SizeOffsetPair = Eval.compute(ObjectSize->getArgOperand(0));
692
693 if (SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown()) {
695 ObjectSize->getIterator(), TargetFolder(DL),
697 if (InsertedInstructions)
698 InsertedInstructions->push_back(I);
699 }));
700
701 Value *Size = SizeOffsetPair.Size;
702 Value *Offset = SizeOffsetPair.Offset;
703
704 // If we've outside the end of the object, then we can always access
705 // exactly 0 bytes.
706 Value *ResultSize = Builder.CreateSub(Size, Offset);
707 Value *UseZero = Builder.CreateICmpULT(Size, Offset);
708 ResultSize = Builder.CreateZExtOrTrunc(ResultSize, ResultType);
709 Value *Ret = Builder.CreateSelect(
710 UseZero, ConstantInt::get(ResultType, 0), ResultSize);
711
712 // The non-constant size expression cannot evaluate to -1.
714 Builder.CreateAssumption(Builder.CreateICmpNE(
715 Ret, ConstantInt::getAllOnesValue(ResultType)));
716
717 return Ret;
718 }
719 }
720
721 if (!MustSucceed)
722 return nullptr;
723
724 return MaxVal ? Constant::getAllOnesValue(ResultType)
725 : Constant::getNullValue(ResultType);
726}
727
728STATISTIC(ObjectVisitorArgument,
729 "Number of arguments with unsolved size and offset");
730STATISTIC(ObjectVisitorLoad,
731 "Number of load instructions with unsolved size and offset");
732
733static std::optional<APInt>
735 std::optional<APInt> RHS,
736 ObjectSizeOpts::Mode EvalMode) {
737 if (!LHS || !RHS)
738 return std::nullopt;
739 if (EvalMode == ObjectSizeOpts::Mode::Max)
740 return LHS->sge(*RHS) ? *LHS : *RHS;
741 return LHS->sle(*RHS) ? *LHS : *RHS;
742}
743
744static std::optional<APInt> aggregatePossibleConstantValuesImpl(
745 const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned BitWidth,
746 unsigned RecursionDepth) {
747 constexpr unsigned MaxRecursionDepth = 4;
748 if (RecursionDepth == MaxRecursionDepth)
749 return std::nullopt;
750
751 if (const auto *CI = dyn_cast<ConstantInt>(V)) {
752 return CI->getValue().sextOrTrunc(BitWidth);
753 } else if (const auto *SI = dyn_cast<SelectInst>(V)) {
755 aggregatePossibleConstantValuesImpl(SI->getTrueValue(), EvalMode,
756 BitWidth, RecursionDepth + 1),
757 aggregatePossibleConstantValuesImpl(SI->getFalseValue(), EvalMode,
758 BitWidth, RecursionDepth + 1),
759 EvalMode);
760 } else if (const auto *PN = dyn_cast<PHINode>(V)) {
761 unsigned Count = PN->getNumIncomingValues();
762 if (Count == 0)
763 return std::nullopt;
765 PN->getIncomingValue(0), EvalMode, BitWidth, RecursionDepth + 1);
766 for (unsigned I = 1; Acc && I < Count; ++I) {
768 PN->getIncomingValue(I), EvalMode, BitWidth, RecursionDepth + 1);
769 Acc = combinePossibleConstantValues(Acc, Tmp, EvalMode);
770 }
771 return Acc;
772 }
773
774 return std::nullopt;
775}
776
777static std::optional<APInt>
779 unsigned BitWidth) {
780 if (auto *CI = dyn_cast<ConstantInt>(V))
781 return CI->getValue().sextOrTrunc(BitWidth);
782
783 if (EvalMode != ObjectSizeOpts::Mode::Min &&
784 EvalMode != ObjectSizeOpts::Mode::Max)
785 return std::nullopt;
786
787 // Not using computeConstantRange here because we cannot guarantee it's not
788 // doing optimization based on UB which we want to avoid when expanding
789 // __builtin_object_size.
790 return aggregatePossibleConstantValuesImpl(V, EvalMode, BitWidth, 0u);
791}
792
793/// Align \p Size according to \p Alignment. If \p Size is greater than
794/// getSignedMaxValue(), set it as unknown as we can only represent signed value
795/// in OffsetSpan.
796APInt ObjectSizeOffsetVisitor::align(APInt Size, MaybeAlign Alignment) {
797 if (Options.RoundToAlign && Alignment)
798 Size = APInt(IntTyBits, alignTo(Size.getZExtValue(), *Alignment));
799
800 return Size.isNegative() ? APInt() : Size;
801}
802
804 const TargetLibraryInfo *TLI,
805 LLVMContext &Context,
806 ObjectSizeOpts Options)
807 : DL(DL), TLI(TLI), Options(Options) {
808 // Pointer size must be rechecked for each object visited since it could have
809 // a different address space.
810}
811
813 InstructionsVisited = 0;
814 OffsetSpan Span = computeImpl(V);
815
816 // In ExactSizeFromOffset mode, we don't care about the Before Field, so allow
817 // us to overwrite it if needs be.
818 if (Span.knownAfter() && !Span.knownBefore() &&
820 Span.Before = APInt::getZero(Span.After.getBitWidth());
821
822 if (!Span.bothKnown())
823 return {};
824
825 return {Span.Before + Span.After, Span.Before};
826}
827
828OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
829 unsigned InitialIntTyBits = DL.getIndexTypeSizeInBits(V->getType());
830
831 // Stripping pointer casts can strip address space casts which can change the
832 // index type size. The invariant is that we use the value type to determine
833 // the index type size and if we stripped address space casts we have to
834 // readjust the APInt as we pass it upwards in order for the APInt to match
835 // the type the caller passed in.
836 APInt Offset(InitialIntTyBits, 0);
837 V = V->stripAndAccumulateConstantOffsets(
838 DL, Offset, /* AllowNonInbounds */ true, /* AllowInvariantGroup */ true);
839
840 // Give it another try with approximated analysis. We don't start with this
841 // one because stripAndAccumulateConstantOffsets behaves differently wrt.
842 // overflows if we provide an external Analysis.
843 if ((Options.EvalMode == ObjectSizeOpts::Mode::Min ||
844 Options.EvalMode == ObjectSizeOpts::Mode::Max) &&
845 isa<GEPOperator>(V)) {
846 // External Analysis used to compute the Min/Max value of individual Offsets
847 // within a GEP.
848 ObjectSizeOpts::Mode EvalMode =
852 // For a GEPOperator the indices are first converted to offsets in the
853 // pointer’s index type, so we need to provide the index type to make sure
854 // the min/max operations are performed in correct type.
855 unsigned IdxTyBits = DL.getIndexTypeSizeInBits(V->getType());
856 auto OffsetRangeAnalysis = [EvalMode, IdxTyBits](Value &VOffset,
857 APInt &Offset) {
858 if (auto PossibleOffset =
859 aggregatePossibleConstantValues(&VOffset, EvalMode, IdxTyBits)) {
860 Offset = *PossibleOffset;
861 return true;
862 }
863 return false;
864 };
865
866 V = V->stripAndAccumulateConstantOffsets(
867 DL, Offset, /* AllowNonInbounds */ true, /* AllowInvariantGroup */ true,
868 /*ExternalAnalysis=*/OffsetRangeAnalysis);
869 }
870
871 // Later we use the index type size and zero but it will match the type of the
872 // value that is passed to computeImpl.
873 IntTyBits = DL.getIndexTypeSizeInBits(V->getType());
874 Zero = APInt::getZero(IntTyBits);
875 OffsetSpan ORT = computeValue(V);
876
877 bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
878 if (!IndexTypeSizeChanged && Offset.isZero())
879 return ORT;
880
881 // We stripped an address space cast that changed the index type size or we
882 // accumulated some constant offset (or both). Readjust the bit width to match
883 // the argument index type size and apply the offset, as required.
884 if (IndexTypeSizeChanged) {
885 if (ORT.knownBefore() &&
886 !::checkedZextOrTrunc(ORT.Before, InitialIntTyBits))
887 ORT.Before = APInt();
888 if (ORT.knownAfter() && !::checkedZextOrTrunc(ORT.After, InitialIntTyBits))
889 ORT.After = APInt();
890 }
891 // If the computed bound is "unknown" we cannot add the stripped offset.
892 if (ORT.knownBefore()) {
893 bool Overflow;
894 ORT.Before = ORT.Before.sadd_ov(Offset, Overflow);
895 if (Overflow)
896 ORT.Before = APInt();
897 }
898 if (ORT.knownAfter()) {
899 bool Overflow;
900 ORT.After = ORT.After.ssub_ov(Offset, Overflow);
901 if (Overflow)
902 ORT.After = APInt();
903 }
904
905 // We end up pointing on a location that's outside of the original object.
906 if (ORT.knownBefore() && ORT.Before.isNegative()) {
907 // This means that we *may* be accessing memory before the allocation.
908 // Conservatively return an unknown size.
909 //
910 // TODO: working with ranges instead of value would make it possible to take
911 // a better decision.
912 if (Options.EvalMode == ObjectSizeOpts::Mode::Min ||
913 Options.EvalMode == ObjectSizeOpts::Mode::Max) {
914 return ObjectSizeOffsetVisitor::unknown();
915 }
916 // Otherwise it's fine, caller can handle negative offset.
917 }
918 return ORT;
919}
920
921OffsetSpan ObjectSizeOffsetVisitor::computeValue(Value *V) {
922 if (Instruction *I = dyn_cast<Instruction>(V)) {
923 // If we have already seen this instruction, bail out. Cycles can happen in
924 // unreachable code after constant propagation.
925 auto P = SeenInsts.try_emplace(I, ObjectSizeOffsetVisitor::unknown());
926 if (!P.second)
927 return P.first->second;
928 ++InstructionsVisited;
929 if (InstructionsVisited > ObjectSizeOffsetVisitorMaxVisitInstructions)
930 return ObjectSizeOffsetVisitor::unknown();
931 OffsetSpan Res = visit(*I);
932 // Cache the result for later visits. If we happened to visit this during
933 // the above recursion, we would consider it unknown until now.
934 SeenInsts[I] = Res;
935 return Res;
936 }
937 if (Argument *A = dyn_cast<Argument>(V))
938 return visitArgument(*A);
939 if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
941 if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
942 return visitGlobalAlias(*GA);
943 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
944 return visitGlobalVariable(*GV);
945 if (UndefValue *UV = dyn_cast<UndefValue>(V))
946 return visitUndefValue(*UV);
947
948 LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: "
949 << *V << '\n');
950 return ObjectSizeOffsetVisitor::unknown();
951}
952
953bool ObjectSizeOffsetVisitor::checkedZextOrTrunc(APInt &I) {
954 return ::checkedZextOrTrunc(I, IntTyBits);
955}
956
958 TypeSize ElemSize = I.getAllocationBaseSize(DL);
959 if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
960 return ObjectSizeOffsetVisitor::unknown();
961 if (!isUIntN(IntTyBits, ElemSize.getKnownMinValue()))
962 return ObjectSizeOffsetVisitor::unknown();
963 APInt Size(IntTyBits, ElemSize.getKnownMinValue());
964
965 if (!I.isArrayAllocation())
966 return OffsetSpan(Zero, align(Size, I.getAlign()));
967
968 Value *ArraySize = I.getArraySize();
969 if (auto PossibleSize = aggregatePossibleConstantValues(
970 ArraySize, Options.EvalMode,
971 ArraySize->getType()->getScalarSizeInBits())) {
972 APInt NumElems = *PossibleSize;
973 if (!checkedZextOrTrunc(NumElems))
974 return ObjectSizeOffsetVisitor::unknown();
975
976 bool Overflow;
977 Size = Size.umul_ov(NumElems, Overflow);
978
979 return Overflow ? ObjectSizeOffsetVisitor::unknown()
980 : OffsetSpan(Zero, align(Size, I.getAlign()));
981 }
982 return ObjectSizeOffsetVisitor::unknown();
983}
984
986 Type *MemoryTy = A.getPointeeInMemoryValueType();
987 // No interprocedural analysis is done at the moment.
988 if (!MemoryTy || !MemoryTy->isSized()) {
989 ++ObjectVisitorArgument;
990 return ObjectSizeOffsetVisitor::unknown();
991 }
992
993 APInt Size(IntTyBits, DL.getTypeAllocSize(MemoryTy));
994 return OffsetSpan(Zero, align(Size, A.getParamAlign()));
995}
996
998 auto Mapper = [this](const Value *V) -> const Value * {
999 if (!V->getType()->isIntegerTy())
1000 return V;
1001
1002 if (auto PossibleBound = aggregatePossibleConstantValues(
1003 V, Options.EvalMode, V->getType()->getScalarSizeInBits()))
1004 return ConstantInt::get(V->getType(), *PossibleBound);
1005
1006 return V;
1007 };
1008
1009 if (std::optional<APInt> Size = getAllocSize(&CB, TLI, Mapper)) {
1010 // Very large unsigned value cannot be represented as OffsetSpan.
1011 if (Size->isNegative())
1012 return ObjectSizeOffsetVisitor::unknown();
1013 return OffsetSpan(Zero, *Size);
1014 }
1015 return ObjectSizeOffsetVisitor::unknown();
1016}
1017
1020 // If null is unknown, there's nothing we can do. Additionally, non-zero
1021 // address spaces can make use of null, so we don't presume to know anything
1022 // about that.
1023 //
1024 // TODO: How should this work with address space casts? We currently just drop
1025 // them on the floor, but it's unclear what we should do when a NULL from
1026 // addrspace(1) gets casted to addrspace(0) (or vice-versa).
1027 if (Options.NullIsUnknownSize || CPN.getPointerType()->getAddressSpace())
1028 return ObjectSizeOffsetVisitor::unknown();
1029 return OffsetSpan(Zero, Zero);
1030}
1031
1034 return ObjectSizeOffsetVisitor::unknown();
1035}
1036
1038 // Easy cases were already folded by previous passes.
1039 return ObjectSizeOffsetVisitor::unknown();
1040}
1041
1043 if (GA.isInterposable())
1044 return ObjectSizeOffsetVisitor::unknown();
1045 return computeImpl(GA.getAliasee());
1046}
1047
1049 if (!GV.getValueType()->isSized() || GV.hasExternalWeakLinkage() ||
1050 ((!GV.hasInitializer() || GV.isInterposable()) &&
1051 Options.EvalMode != ObjectSizeOpts::Mode::Min))
1052 return ObjectSizeOffsetVisitor::unknown();
1053
1054 APInt Size(IntTyBits, GV.getGlobalSize(DL));
1055 return OffsetSpan(Zero, align(Size, GV.getAlign()));
1056}
1057
1059 // clueless
1060 return ObjectSizeOffsetVisitor::unknown();
1061}
1062
1063OffsetSpan ObjectSizeOffsetVisitor::findLoadOffsetRange(
1066 unsigned &ScannedInstCount) {
1067 constexpr unsigned MaxInstsToScan = 128;
1068
1069 auto Where = VisitedBlocks.find(&BB);
1070 if (Where != VisitedBlocks.end())
1071 return Where->second;
1072
1073 auto Unknown = [&BB, &VisitedBlocks]() {
1074 return VisitedBlocks[&BB] = ObjectSizeOffsetVisitor::unknown();
1075 };
1076 auto Known = [&BB, &VisitedBlocks](OffsetSpan SO) {
1077 return VisitedBlocks[&BB] = SO;
1078 };
1079
1080 do {
1081 Instruction &I = *From;
1082
1084 continue;
1085
1086 if (++ScannedInstCount > MaxInstsToScan)
1087 return Unknown();
1088
1089 if (!I.mayWriteToMemory())
1090 continue;
1091
1092 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1093 AliasResult AR =
1094 Options.AA->alias(SI->getPointerOperand(), Load.getPointerOperand());
1095 switch ((AliasResult::Kind)AR) {
1097 continue;
1099 if (SI->getValueOperand()->getType()->isPointerTy())
1100 return Known(computeImpl(SI->getValueOperand()));
1101 else
1102 return Unknown(); // No handling of non-pointer values by `compute`.
1103 default:
1104 return Unknown();
1105 }
1106 }
1107
1108 if (auto *CB = dyn_cast<CallBase>(&I)) {
1110 // Bail out on indirect call.
1111 if (!Callee)
1112 return Unknown();
1113
1114 if (!TLI)
1115 return Unknown();
1116
1117 LibFunc TLIFn = TLI->getLibFunc(*CB->getCalledFunction());
1118 if (!TLI->has(TLIFn))
1119 return Unknown();
1120
1121 // TODO: There's probably more interesting case to support here.
1122 if (TLIFn != LibFunc_posix_memalign)
1123 return Unknown();
1124
1125 AliasResult AR =
1126 Options.AA->alias(CB->getOperand(0), Load.getPointerOperand());
1127 switch ((AliasResult::Kind)AR) {
1129 continue;
1131 break;
1132 default:
1133 return Unknown();
1134 }
1135
1136 // Is the error status of posix_memalign correctly checked? If not it
1137 // would be incorrect to assume it succeeds and load doesn't see the
1138 // previous value.
1139 std::optional<bool> Checked = isImpliedByDomCondition(
1140 ICmpInst::ICMP_EQ, CB, ConstantInt::get(CB->getType(), 0), &Load, DL);
1141 if (!Checked || !*Checked)
1142 return Unknown();
1143
1144 Value *Size = CB->getOperand(2);
1145 auto *C = dyn_cast<ConstantInt>(Size);
1146 if (!C)
1147 return Unknown();
1148
1149 APInt CSize = C->getValue();
1150 if (CSize.isNegative())
1151 return Unknown();
1152
1153 return Known({APInt(CSize.getBitWidth(), 0), CSize});
1154 }
1155
1156 return Unknown();
1157 } while (From-- != BB.begin());
1158
1159 SmallVector<OffsetSpan> PredecessorSizeOffsets;
1160 for (auto *PredBB : predecessors(&BB)) {
1161 PredecessorSizeOffsets.push_back(findLoadOffsetRange(
1162 Load, *PredBB, BasicBlock::iterator(PredBB->getTerminator()),
1163 VisitedBlocks, ScannedInstCount));
1164 if (!PredecessorSizeOffsets.back().bothKnown())
1165 return Unknown();
1166 }
1167
1168 if (PredecessorSizeOffsets.empty())
1169 return Unknown();
1170
1171 return Known(std::accumulate(
1172 PredecessorSizeOffsets.begin() + 1, PredecessorSizeOffsets.end(),
1173 PredecessorSizeOffsets.front(), [this](OffsetSpan LHS, OffsetSpan RHS) {
1174 return combineOffsetRange(LHS, RHS);
1175 }));
1176}
1177
1179 if (!Options.AA) {
1180 ++ObjectVisitorLoad;
1181 return ObjectSizeOffsetVisitor::unknown();
1182 }
1183
1185 unsigned ScannedInstCount = 0;
1186 OffsetSpan SO =
1187 findLoadOffsetRange(LI, *LI.getParent(), BasicBlock::iterator(LI),
1188 VisitedBlocks, ScannedInstCount);
1189 if (!SO.bothKnown())
1190 ++ObjectVisitorLoad;
1191 return SO;
1192}
1193
1194OffsetSpan ObjectSizeOffsetVisitor::combineOffsetRange(OffsetSpan LHS,
1195 OffsetSpan RHS) {
1196 if (!LHS.bothKnown() || !RHS.bothKnown())
1197 return ObjectSizeOffsetVisitor::unknown();
1198
1199 switch (Options.EvalMode) {
1201 return {LHS.Before.slt(RHS.Before) ? LHS.Before : RHS.Before,
1202 LHS.After.slt(RHS.After) ? LHS.After : RHS.After};
1204 return {LHS.Before.sgt(RHS.Before) ? LHS.Before : RHS.Before,
1205 LHS.After.sgt(RHS.After) ? LHS.After : RHS.After};
1206 }
1208 return {LHS.Before.eq(RHS.Before) ? LHS.Before : APInt(),
1209 LHS.After.eq(RHS.After) ? LHS.After : APInt()};
1211 return (LHS == RHS) ? LHS : ObjectSizeOffsetVisitor::unknown();
1212 }
1213 llvm_unreachable("missing an eval mode");
1214}
1215
1217 if (PN.getNumIncomingValues() == 0)
1218 return ObjectSizeOffsetVisitor::unknown();
1219 auto IncomingValues = PN.incoming_values();
1220 return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
1221 computeImpl(*IncomingValues.begin()),
1222 [this](OffsetSpan LHS, Value *VRHS) {
1223 return combineOffsetRange(LHS, computeImpl(VRHS));
1224 });
1225}
1226
1228 return combineOffsetRange(computeImpl(I.getTrueValue()),
1229 computeImpl(I.getFalseValue()));
1230}
1231
1235
1237 LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor unknown instruction:" << I
1238 << '\n');
1239 return ObjectSizeOffsetVisitor::unknown();
1240}
1241
1242// Just set these right here...
1245
1247 Module &M, const TargetLibraryInfo *TLI, ObjectSizeOpts EvalOpts)
1248 : DL(M.getDataLayout()), TLI(TLI), Context(M.getContext()),
1249 Builder(M, TargetFolder(DL),
1251 [&](Instruction *I) { InsertedInstructions.insert(I); })),
1252 EvalOpts(EvalOpts) {
1253 // IntTy and Zero must be set for each compute() since the address space may
1254 // be different for later objects.
1255}
1256
1258 // XXX - Are vectors of pointers possible here?
1259 IntTy = cast<IntegerType>(DL.getIndexType(V->getType()));
1260 Zero = ConstantInt::get(IntTy, 0);
1261
1262 SizeOffsetValue Result = compute_(V);
1263
1264 if (!Result.bothKnown()) {
1265 // Erase everything that was computed in this iteration from the cache, so
1266 // that no dangling references are left behind. We could be a bit smarter if
1267 // we kept a dependency graph. It's probably not worth the complexity.
1268 for (const Value *SeenVal : SeenVals) {
1269 CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
1270 // non-computable results can be safely cached
1271 if (CacheIt != CacheMap.end() && CacheIt->second.anyKnown())
1272 CacheMap.erase(CacheIt);
1273 }
1274
1275 // Erase any instructions we inserted as part of the traversal.
1276 for (Instruction *I : InsertedInstructions) {
1277 I->replaceAllUsesWith(PoisonValue::get(I->getType()));
1278 I->eraseFromParent();
1279 }
1280 }
1281
1282 SeenVals.clear();
1283 InsertedInstructions.clear();
1284 return Result;
1285}
1286
1287SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) {
1288
1289 // Only trust ObjectSizeOffsetVisitor in exact mode, otherwise fallback on
1290 // dynamic computation.
1291 ObjectSizeOpts VisitorEvalOpts(EvalOpts);
1292 VisitorEvalOpts.EvalMode = ObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset;
1293 ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, VisitorEvalOpts);
1294
1295 SizeOffsetAPInt Const = Visitor.compute(V);
1296 if (Const.bothKnown())
1297 return SizeOffsetValue(ConstantInt::get(Context, Const.Size),
1298 ConstantInt::get(Context, Const.Offset));
1299
1300 V = V->stripPointerCasts();
1301
1302 // Check cache.
1303 CacheMapTy::iterator CacheIt = CacheMap.find(V);
1304 if (CacheIt != CacheMap.end())
1305 return CacheIt->second;
1306
1307 // Always generate code immediately before the instruction being
1308 // processed, so that the generated code dominates the same BBs.
1309 BuilderTy::InsertPointGuard Guard(Builder);
1311 Builder.SetInsertPoint(I);
1312
1313 // Now compute the size and offset.
1314 SizeOffsetValue Result;
1315
1316 // Record the pointers that were handled in this run, so that they can be
1317 // cleaned later if something fails. We also use this set to break cycles that
1318 // can occur in dead code.
1319 if (!SeenVals.insert(V).second) {
1321 } else if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
1322 Result = visitGEPOperator(*GEP);
1323 } else if (Instruction *I = dyn_cast<Instruction>(V)) {
1324 Result = visit(*I);
1325 } else if (isa<Argument>(V) ||
1326 (isa<ConstantExpr>(V) &&
1327 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
1329 // Ignore values where we cannot do more than ObjectSizeVisitor.
1331 } else {
1332 LLVM_DEBUG(
1333 dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
1334 << '\n');
1336 }
1337
1338 // Don't reuse CacheIt since it may be invalid at this point.
1339 CacheMap[V] = SizeOffsetWeakTrackingVH(Result);
1340 return Result;
1341}
1342
1344 // must be a VLA or vscale.
1345 assert(I.isArrayAllocation() || I.isScalable());
1346
1347 // If needed, adjust the alloca's operand size to match the pointer indexing
1348 // size. Subsequent math operations expect the types to match.
1349 Type *IndexTy = DL.getIndexType(I.getContext(), DL.getAllocaAddrSpace());
1350 assert(IndexTy == Zero->getType() &&
1351 "Expected zero constant to have pointer index type");
1352
1353 Value *Size = Builder.CreateAllocationSize(IndexTy, &I);
1354 return SizeOffsetValue(Size, Zero);
1355}
1356
1358 std::optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
1359 if (!FnData)
1361
1362 // Handle strdup-like functions separately.
1363 if (FnData->AllocTy == StrDupLike) {
1364 // TODO: implement evaluation of strdup/strndup
1366 }
1367
1368 Value *FirstArg = CB.getArgOperand(FnData->FstParam);
1369 FirstArg = Builder.CreateZExtOrTrunc(FirstArg, IntTy);
1370 if (FnData->SndParam < 0)
1371 return SizeOffsetValue(FirstArg, Zero);
1372
1373 Value *SecondArg = CB.getArgOperand(FnData->SndParam);
1374 SecondArg = Builder.CreateZExtOrTrunc(SecondArg, IntTy);
1375 Value *Size = Builder.CreateMul(FirstArg, SecondArg);
1376 return SizeOffsetValue(Size, Zero);
1377}
1378
1383
1388
1390 SizeOffsetValue PtrData = compute_(GEP.getPointerOperand());
1391 if (!PtrData.bothKnown())
1393
1394 Value *Offset = emitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
1395 Offset = Builder.CreateAdd(PtrData.Offset, Offset);
1396 return SizeOffsetValue(PtrData.Size, Offset);
1397}
1398
1403
1407
1409 // Create 2 PHIs: one for size and another for offset.
1410 PHINode *SizePHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
1411 PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
1412
1413 // Insert right away in the cache to handle recursive PHIs.
1414 CacheMap[&PHI] = SizeOffsetWeakTrackingVH(SizePHI, OffsetPHI);
1415
1416 // Compute offset/size for each PHI incoming pointer.
1417 for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
1418 BasicBlock *IncomingBlock = PHI.getIncomingBlock(i);
1419 Builder.SetInsertPoint(IncomingBlock->getFirstInsertionPt());
1420 SizeOffsetValue EdgeData = compute_(PHI.getIncomingValue(i));
1421
1422 if (!EdgeData.bothKnown()) {
1423 OffsetPHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1424 OffsetPHI->eraseFromParent();
1425 InsertedInstructions.erase(OffsetPHI);
1426 SizePHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1427 SizePHI->eraseFromParent();
1428 InsertedInstructions.erase(SizePHI);
1430 }
1431 SizePHI->addIncoming(EdgeData.Size, IncomingBlock);
1432 OffsetPHI->addIncoming(EdgeData.Offset, IncomingBlock);
1433 }
1434
1435 Value *Size = SizePHI, *Offset = OffsetPHI;
1436 if (Value *Tmp = SizePHI->hasConstantValue()) {
1437 Size = Tmp;
1438 SizePHI->replaceAllUsesWith(Size);
1439 SizePHI->eraseFromParent();
1440 InsertedInstructions.erase(SizePHI);
1441 }
1442 if (Value *Tmp = OffsetPHI->hasConstantValue()) {
1443 Offset = Tmp;
1444 OffsetPHI->replaceAllUsesWith(Offset);
1445 OffsetPHI->eraseFromParent();
1446 InsertedInstructions.erase(OffsetPHI);
1447 }
1448 return SizeOffsetValue(Size, Offset);
1449}
1450
1452 SizeOffsetValue TrueSide = compute_(I.getTrueValue());
1453 SizeOffsetValue FalseSide = compute_(I.getFalseValue());
1454
1455 if (!TrueSide.bothKnown() || !FalseSide.bothKnown())
1457 if (TrueSide == FalseSide)
1458 return TrueSide;
1459
1460 Value *Size =
1461 Builder.CreateSelect(I.getCondition(), TrueSide.Size, FalseSide.Size, "",
1462 ProfcheckDisableMetadataFixes ? nullptr : &I);
1463 Value *Offset =
1464 Builder.CreateSelect(I.getCondition(), TrueSide.Offset, FalseSide.Offset,
1465 "", ProfcheckDisableMetadataFixes ? nullptr : &I);
1466 return SizeOffsetValue(Size, Offset);
1467}
1468
1470 LLVM_DEBUG(dbgs() << "ObjectSizeOffsetEvaluator unknown instruction:" << I
1471 << '\n');
1473}
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
Hexagon Common GEP
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
MallocFamily
static std::optional< APInt > combinePossibleConstantValues(std::optional< APInt > LHS, std::optional< APInt > RHS, ObjectSizeOpts::Mode EvalMode)
static std::optional< FreeFnsTy > getFreeFunctionDataForFunction(const Function *Callee, const LibFunc TLIFn)
static AllocFnKind getAllocFnKind(const Value *V)
static std::optional< APInt > aggregatePossibleConstantValuesImpl(const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned BitWidth, unsigned RecursionDepth)
static bool checkedZextOrTrunc(APInt &I, unsigned IntTyBits)
When we're compiling N-bit code, and the user uses parameters that are greater than N bits (e....
static std::optional< AllocFnsTy > getAllocationDataForFunction(const Function *Callee, AllocType AllocTy, const TargetLibraryInfo *TLI)
Returns the allocation data for the given value if it's a call to a known allocation function.
static std::optional< AllocFnsTy > getAllocationData(const Value *V, AllocType AllocTy, const TargetLibraryInfo *TLI)
static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted)
static std::optional< AllocFnsTy > getAllocationSize(const CallBase *CB, const TargetLibraryInfo *TLI)
static const std::pair< LibFunc, FreeFnsTy > FreeFnData[]
static const Function * getCalledFunction(const Value *V)
static cl::opt< unsigned > ObjectSizeOffsetVisitorMaxVisitInstructions("object-size-offset-visitor-max-visit-instructions", cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to " "look at"), cl::init(100))
static StringRef mangledNameForMallocFamily(const MallocFamily &Family)
static const std::pair< LibFunc, AllocFnsTy > AllocationFnData[]
AllocType
@ MallocLike
@ AnyAlloc
@ AllocLike
@ StrDupLike
@ OpNewLike
@ MallocOrOpNewLike
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data)
static std::optional< APInt > aggregatePossibleConstantValues(const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned BitWidth)
#define P(N)
This file contains the declarations for profiling metadata utility functions.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file contains some templates that are useful if you are working with the STL at all.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Definition APInt.cpp:1966
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
Definition APInt.cpp:1979
@ NoAlias
The two locations do not alias at all.
@ MustAlias
The two locations precisely alias each other.
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
Value * getArgOperand(unsigned i) const
LLVM_ABI Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
unsigned arg_size() const
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
A constant pointer value that points to null.
Definition Constants.h:716
PointerType * getPointerType() const
Return the scalar pointer type for this null value.
Definition Constants.h:736
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition DenseMap.h:678
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
const Constant * getAliasee() const
Definition GlobalAlias.h:87
bool hasExternalWeakLinkage() const
Type * getValueType() const
LLVM_ABI bool isInterposable(bool CheckNoIPA=true) const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
Definition Globals.cpp:178
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
Definition Globals.cpp:640
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
Definition IRBuilder.h:74
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2987
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This class represents a cast from an integer to a pointer.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Evaluate the size and offset of an object pointed to by a Value*.
LLVM_ABI SizeOffsetValue visitExtractValueInst(ExtractValueInst &I)
LLVM_ABI SizeOffsetValue visitExtractElementInst(ExtractElementInst &I)
LLVM_ABI SizeOffsetValue compute(Value *V)
LLVM_ABI SizeOffsetValue visitInstruction(Instruction &I)
LLVM_ABI SizeOffsetValue visitLoadInst(LoadInst &I)
LLVM_ABI SizeOffsetValue visitGEPOperator(GEPOperator &GEP)
LLVM_ABI SizeOffsetValue visitIntToPtrInst(IntToPtrInst &)
LLVM_ABI SizeOffsetValue visitPHINode(PHINode &PHI)
LLVM_ABI SizeOffsetValue visitCallBase(CallBase &CB)
LLVM_ABI ObjectSizeOffsetEvaluator(Module &M, const TargetLibraryInfo *TLI, ObjectSizeOpts EvalOpts={})
LLVM_ABI SizeOffsetValue visitSelectInst(SelectInst &I)
LLVM_ABI SizeOffsetValue visitAllocaInst(AllocaInst &I)
static SizeOffsetValue unknown()
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI OffsetSpan visitSelectInst(SelectInst &I)
LLVM_ABI OffsetSpan visitExtractValueInst(ExtractValueInst &I)
LLVM_ABI OffsetSpan visitConstantPointerNull(ConstantPointerNull &)
LLVM_ABI OffsetSpan visitExtractElementInst(ExtractElementInst &I)
LLVM_ABI OffsetSpan visitGlobalVariable(GlobalVariable &GV)
LLVM_ABI OffsetSpan visitCallBase(CallBase &CB)
LLVM_ABI OffsetSpan visitIntToPtrInst(IntToPtrInst &)
LLVM_ABI OffsetSpan visitAllocaInst(AllocaInst &I)
LLVM_ABI ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options={})
LLVM_ABI OffsetSpan visitLoadInst(LoadInst &I)
LLVM_ABI OffsetSpan visitPHINode(PHINode &)
LLVM_ABI OffsetSpan visitGlobalAlias(GlobalAlias &GA)
LLVM_ABI OffsetSpan visitInstruction(Instruction &I)
LLVM_ABI SizeOffsetAPInt compute(Value *V)
LLVM_ABI OffsetSpan visitUndefValue(UndefValue &)
LLVM_ABI OffsetSpan visitArgument(Argument &A)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
LLVM_ABI Value * hasConstantValue() const
If the specified PHI node always merges together the same value, return the value,...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class represents the LLVM 'select' instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetFolder - Create constants with target dependent folding.
Provides information about what library functions are available for the current target.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:352
static constexpr TypeSize getZero()
Definition TypeSize.h:358
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
'undef' values are things that do not have specified contents.
Definition Constants.h:1657
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
Definition LoopInfo.cpp:61
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
@ Known
Known to have no common set bits.
@ Unknown
Not known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
AllocFnKind
Definition Attributes.h:54
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
LLVM_ABI std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)
Try to turn a call to @llvm.objectsize into an integer value of the given Type.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
LLVM_ABI bool isLibFreeFunction(const Function *F, const LibFunc TLIFn)
isLibFreeFunction - Returns true if the function is a builtin free()
LLVM_ABI Value * getReallocatedOperand(const CallBase *CB)
If this is a call to a realloc function, return the reallocated operand.
LLVM_ABI std::optional< TypeSize > getBaseObjectSize(const Value *Ptr, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Like getObjectSize(), but only returns the size of base objects (like allocas, global variables and a...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc,...
LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
LLVM_ABI Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
Definition Local.cpp:22
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
LLVM_ABI uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool isReallocLikeFn(const Function *F)
Tests if a function is a call or invoke to a library function that reallocates memory (e....
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI std::optional< bool > isImpliedByDomCondition(const Value *Cond, const Instruction *ContextI, const DataLayout &DL)
Return the boolean condition value in the context of the given instruction if it is known based on do...
MallocFamily Family
unsigned NumParams
AllocType AllocTy
MallocFamily Family
unsigned NumParams
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:111
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
Mode EvalMode
How we want to evaluate this object's size.
AAResults * AA
If set, used for more accurate evaluation.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
Mode
Controls how we handle conditional statements with unknown conditions.
@ ExactUnderlyingSizeAndOffset
All branches must be known and have the same underlying size and offset to be merged.
@ Max
Same as Min, except we pick the maximum size of all of the branches.
@ Min
Evaluate all branches of an unknown condition.
@ ExactSizeFromOffset
All branches must be known and have the same size, starting from the offset, to be merged.
OffsetSpan - Used internally by ObjectSizeOffsetVisitor.
bool knownBefore() const
APInt After
Number of allocated bytes before this point.
bool knownAfter() const
bool bothKnown() const
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.
SizeOffsetWeakTrackingVH - Used by ObjectSizeOffsetEvaluator in a DenseMap.