LLVM  16.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/None.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/Statistic.h"
25 #include "llvm/IR/Argument.h"
26 #include "llvm/IR/Attributes.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DataLayout.h"
29 #include "llvm/IR/DerivedTypes.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/GlobalAlias.h"
32 #include "llvm/IR/GlobalVariable.h"
33 #include "llvm/IR/Instruction.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/Operator.h"
37 #include "llvm/IR/Type.h"
38 #include "llvm/IR/Value.h"
39 #include "llvm/Support/Casting.h"
40 #include "llvm/Support/Debug.h"
43 #include <cassert>
44 #include <cstdint>
45 #include <iterator>
46 #include <numeric>
47 #include <type_traits>
48 #include <utility>
49 
50 using namespace llvm;
51 
52 #define DEBUG_TYPE "memory-builtins"
53 
54 enum AllocType : uint8_t {
55  OpNewLike = 1<<0, // allocates; never returns null
56  MallocLike = 1<<1, // allocates; may return null
57  AlignedAllocLike = 1<<2, // allocates with alignment; may return null
58  CallocLike = 1<<3, // allocates + bzero
59  ReallocLike = 1<<4, // reallocates
60  StrDupLike = 1<<5,
65 };
66 
67 enum class MallocFamily {
68  Malloc,
69  CPPNew, // new(unsigned int)
70  CPPNewAligned, // new(unsigned int, align_val_t)
71  CPPNewArray, // new[](unsigned int)
72  CPPNewArrayAligned, // new[](unsigned long, align_val_t)
73  MSVCNew, // new(unsigned int)
74  MSVCArrayNew, // new[](unsigned int)
75  VecMalloc,
77 };
78 
80  switch (Family) {
82  return "malloc";
84  return "_Znwm";
86  return "_ZnwmSt11align_val_t";
88  return "_Znam";
90  return "_ZnamSt11align_val_t";
92  return "??2@YAPAXI@Z";
94  return "??_U@YAPAXI@Z";
96  return "vec_malloc";
98  return "__kmpc_alloc_shared";
99  }
100  llvm_unreachable("missing an alloc family");
101 }
102 
103 struct AllocFnsTy {
105  unsigned NumParams;
106  // First and Second size parameters (or -1 if unused)
107  int FstParam, SndParam;
108  // Alignment parameter for aligned_alloc and aligned new
110  // Name of default allocator function to group malloc/free calls by family
112 };
113 
114 // clang-format off
115 // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
116 // know which functions are nounwind, noalias, nocapture parameters, etc.
117 static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
118  {LibFunc_vec_malloc, {MallocLike, 1, 0, -1, -1, MallocFamily::VecMalloc}},
119  {LibFunc_Znwj, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int)
120  {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int, nothrow)
121  {LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned int, align_val_t)
122  {LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned int, align_val_t, nothrow)
123  {LibFunc_Znwm, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long)
124  {LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned long, nothrow)
125  {LibFunc_ZnwmSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t)
126  {LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned long, align_val_t, nothrow)
127  {LibFunc_Znaj, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned int)
128  {LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned int, nothrow)
129  {LibFunc_ZnajSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned int, align_val_t)
130  {LibFunc_ZnajSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned int, align_val_t, nothrow)
131  {LibFunc_Znam, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned long)
132  {LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNewArray}}, // new[](unsigned long, nothrow)
133  {LibFunc_ZnamSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned long, align_val_t)
134  {LibFunc_ZnamSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1, MallocFamily::CPPNewArrayAligned}}, // new[](unsigned long, align_val_t, nothrow)
135  {LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned int)
136  {LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned int, nothrow)
137  {LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned long long)
138  {LibFunc_msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCNew}}, // new(unsigned long long, nothrow)
139  {LibFunc_msvc_new_array_int, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned int)
140  {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned int, nothrow)
141  {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long)
142  {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long, nothrow)
143  {LibFunc_memalign, {AlignedAllocLike, 2, 1, -1, 0, MallocFamily::Malloc}},
144  {LibFunc_vec_calloc, {CallocLike, 2, 0, 1, -1, MallocFamily::VecMalloc}},
145  {LibFunc_vec_realloc, {ReallocLike, 2, 1, -1, -1, MallocFamily::VecMalloc}},
146  {LibFunc_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}},
147  {LibFunc_dunder_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}},
148  {LibFunc_strndup, {StrDupLike, 2, 1, -1, -1, MallocFamily::Malloc}},
149  {LibFunc_dunder_strndup, {StrDupLike, 2, 1, -1, -1, MallocFamily::Malloc}},
150  {LibFunc___kmpc_alloc_shared, {MallocLike, 1, 0, -1, -1, MallocFamily::KmpcAllocShared}},
151 };
152 // clang-format on
153 
154 static const Function *getCalledFunction(const Value *V,
155  bool &IsNoBuiltin) {
156  // Don't care about intrinsics in this case.
157  if (isa<IntrinsicInst>(V))
158  return nullptr;
159 
160  const auto *CB = dyn_cast<CallBase>(V);
161  if (!CB)
162  return nullptr;
163 
164  IsNoBuiltin = CB->isNoBuiltin();
165 
166  if (const Function *Callee = CB->getCalledFunction())
167  return Callee;
168  return nullptr;
169 }
170 
171 /// Returns the allocation data for the given value if it's a call to a known
172 /// allocation function.
175  const TargetLibraryInfo *TLI) {
176  // Don't perform a slow TLI lookup, if this function doesn't return a pointer
177  // and thus can't be an allocation function.
178  if (!Callee->getReturnType()->isPointerTy())
179  return None;
180 
181  // Make sure that the function is available.
182  LibFunc TLIFn;
183  if (!TLI || !TLI->getLibFunc(*Callee, TLIFn) || !TLI->has(TLIFn))
184  return None;
185 
186  const auto *Iter = find_if(
187  AllocationFnData, [TLIFn](const std::pair<LibFunc, AllocFnsTy> &P) {
188  return P.first == TLIFn;
189  });
190 
191  if (Iter == std::end(AllocationFnData))
192  return None;
193 
194  const AllocFnsTy *FnData = &Iter->second;
195  if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
196  return None;
197 
198  // Check function prototype.
199  int FstParam = FnData->FstParam;
200  int SndParam = FnData->SndParam;
202 
203  if (FTy->getReturnType() == Type::getInt8PtrTy(FTy->getContext()) &&
204  FTy->getNumParams() == FnData->NumParams &&
205  (FstParam < 0 ||
206  (FTy->getParamType(FstParam)->isIntegerTy(32) ||
207  FTy->getParamType(FstParam)->isIntegerTy(64))) &&
208  (SndParam < 0 ||
209  FTy->getParamType(SndParam)->isIntegerTy(32) ||
210  FTy->getParamType(SndParam)->isIntegerTy(64)))
211  return *FnData;
212  return None;
213 }
214 
216  const TargetLibraryInfo *TLI) {
217  bool IsNoBuiltinCall;
218  if (const Function *Callee = getCalledFunction(V, IsNoBuiltinCall))
219  if (!IsNoBuiltinCall)
220  return getAllocationDataForFunction(Callee, AllocTy, TLI);
221  return None;
222 }
223 
226  function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
227  bool IsNoBuiltinCall;
228  if (const Function *Callee = getCalledFunction(V, IsNoBuiltinCall))
229  if (!IsNoBuiltinCall)
231  Callee, AllocTy, &GetTLI(const_cast<Function &>(*Callee)));
232  return None;
233 }
234 
236  const TargetLibraryInfo *TLI) {
237  bool IsNoBuiltinCall;
238  const Function *Callee =
239  getCalledFunction(V, IsNoBuiltinCall);
240  if (!Callee)
241  return None;
242 
243  // Prefer to use existing information over allocsize. This will give us an
244  // accurate AllocTy.
245  if (!IsNoBuiltinCall)
248  return Data;
249 
250  Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
251  if (Attr == Attribute())
252  return None;
253 
254  std::pair<unsigned, Optional<unsigned>> Args = Attr.getAllocSizeArgs();
255 
256  AllocFnsTy Result;
257  // Because allocsize only tells us how many bytes are allocated, we're not
258  // really allowed to assume anything, so we use MallocLike.
259  Result.AllocTy = MallocLike;
260  Result.NumParams = Callee->getNumOperands();
261  Result.FstParam = Args.first;
262  Result.SndParam = Args.second.value_or(-1);
263  // Allocsize has no way to specify an alignment argument
264  Result.AlignParam = -1;
265  return Result;
266 }
267 
268 static AllocFnKind getAllocFnKind(const Value *V) {
269  if (const auto *CB = dyn_cast<CallBase>(V)) {
270  Attribute Attr = CB->getFnAttr(Attribute::AllocKind);
271  if (Attr.isValid())
272  return AllocFnKind(Attr.getValueAsInt());
273  }
274  return AllocFnKind::Unknown;
275 }
276 
278  Attribute Attr = F->getFnAttribute(Attribute::AllocKind);
279  if (Attr.isValid())
280  return AllocFnKind(Attr.getValueAsInt());
281  return AllocFnKind::Unknown;
282 }
283 
284 static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted) {
285  return (getAllocFnKind(V) & Wanted) != AllocFnKind::Unknown;
286 }
287 
288 static bool checkFnAllocKind(const Function *F, AllocFnKind Wanted) {
289  return (getAllocFnKind(F) & Wanted) != AllocFnKind::Unknown;
290 }
291 
292 /// Tests if a value is a call or invoke to a library function that
293 /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
294 /// like).
295 bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI) {
296  return getAllocationData(V, AnyAlloc, TLI).has_value() ||
298 }
300  const Value *V,
301  function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
302  return getAllocationData(V, AnyAlloc, GetTLI).has_value() ||
304 }
305 
306 /// Tests if a value is a call or invoke to a library function that
307 /// allocates memory via new.
308 bool llvm::isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
309  return getAllocationData(V, OpNewLike, TLI).has_value();
310 }
311 
312 /// Tests if a value is a call or invoke to a library function that
313 /// allocates uninitialized memory (such as malloc).
314 static bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
315  return getAllocationData(V, MallocOrOpNewLike, TLI).has_value();
316 }
317 
318 /// Tests if a value is a call or invoke to a library function that
319 /// allocates uninitialized memory with alignment (such as aligned_alloc).
320 static bool isAlignedAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
321  return getAllocationData(V, AlignedAllocLike, TLI).has_value();
322 }
323 
324 /// Tests if a value is a call or invoke to a library function that
325 /// allocates zero-filled memory (such as calloc).
326 static bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
327  return getAllocationData(V, CallocLike, TLI).has_value();
328 }
329 
330 /// Tests if a value is a call or invoke to a library function that
331 /// allocates memory similar to malloc or calloc.
333  return getAllocationData(V, MallocOrCallocLike, TLI).has_value();
334 }
335 
336 /// Tests if a value is a call or invoke to a library function that
337 /// allocates memory (either malloc, calloc, or strdup like).
338 bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
339  return getAllocationData(V, AllocLike, TLI).has_value() ||
341 }
342 
343 /// Tests if a functions is a call or invoke to a library function that
344 /// reallocates memory (e.g., realloc).
346  return getAllocationDataForFunction(F, ReallocLike, TLI).has_value() ||
348 }
349 
351  const TargetLibraryInfo *TLI) {
352  if (getAllocationData(CB, ReallocLike, TLI).has_value()) {
353  // All currently supported realloc functions reallocate the first argument.
354  return CB->getArgOperand(0);
355  }
357  return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
358  return nullptr;
359 }
360 
361 bool llvm::isRemovableAlloc(const CallBase *CB, const TargetLibraryInfo *TLI) {
362  // Note: Removability is highly dependent on the source language. For
363  // example, recent C++ requires direct calls to the global allocation
364  // [basic.stc.dynamic.allocation] to be observable unless part of a new
365  // expression [expr.new paragraph 13].
366 
367  // Historically we've treated the C family allocation routines and operator
368  // new as removable
369  return isAllocLikeFn(CB, TLI);
370 }
371 
373  const TargetLibraryInfo *TLI) {
374  const Optional<AllocFnsTy> FnData = getAllocationData(V, AnyAlloc, TLI);
375  if (FnData && FnData->AlignParam >= 0) {
376  return V->getOperand(FnData->AlignParam);
377  }
378  return V->getArgOperandWithAttribute(Attribute::AllocAlign);
379 }
380 
381 /// When we're compiling N-bit code, and the user uses parameters that are
382 /// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
383 /// trouble with APInt size issues. This function handles resizing + overflow
384 /// checks for us. Check and zext or trunc \p I depending on IntTyBits and
385 /// I's value.
386 static bool CheckedZextOrTrunc(APInt &I, unsigned IntTyBits) {
387  // More bits than we can handle. Checking the bit width isn't necessary, but
388  // it's faster than checking active bits, and should give `false` in the
389  // vast majority of cases.
390  if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
391  return false;
392  if (I.getBitWidth() != IntTyBits)
393  I = I.zextOrTrunc(IntTyBits);
394  return true;
395 }
396 
399  function_ref<const Value *(const Value *)> Mapper) {
400  // Note: This handles both explicitly listed allocation functions and
401  // allocsize. The code structure could stand to be cleaned up a bit.
402  Optional<AllocFnsTy> FnData = getAllocationSize(CB, TLI);
403  if (!FnData)
404  return None;
405 
406  // Get the index type for this address space, results and intermediate
407  // computations are performed at that width.
408  auto &DL = CB->getModule()->getDataLayout();
409  const unsigned IntTyBits = DL.getIndexTypeSizeInBits(CB->getType());
410 
411  // Handle strdup-like functions separately.
412  if (FnData->AllocTy == StrDupLike) {
413  APInt Size(IntTyBits, GetStringLength(Mapper(CB->getArgOperand(0))));
414  if (!Size)
415  return None;
416 
417  // Strndup limits strlen.
418  if (FnData->FstParam > 0) {
419  const ConstantInt *Arg =
420  dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
421  if (!Arg)
422  return None;
423 
424  APInt MaxSize = Arg->getValue().zext(IntTyBits);
425  if (Size.ugt(MaxSize))
426  Size = MaxSize + 1;
427  }
428  return Size;
429  }
430 
431  const ConstantInt *Arg =
432  dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
433  if (!Arg)
434  return None;
435 
436  APInt Size = Arg->getValue();
437  if (!CheckedZextOrTrunc(Size, IntTyBits))
438  return None;
439 
440  // Size is determined by just 1 parameter.
441  if (FnData->SndParam < 0)
442  return Size;
443 
444  Arg = dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->SndParam)));
445  if (!Arg)
446  return None;
447 
448  APInt NumElems = Arg->getValue();
449  if (!CheckedZextOrTrunc(NumElems, IntTyBits))
450  return None;
451 
452  bool Overflow;
453  Size = Size.umul_ov(NumElems, Overflow);
454  if (Overflow)
455  return None;
456  return Size;
457 }
458 
460  const TargetLibraryInfo *TLI,
461  Type *Ty) {
462  auto *Alloc = dyn_cast<CallBase>(V);
463  if (!Alloc)
464  return nullptr;
465 
466  // malloc and aligned_alloc are uninitialized (undef)
467  if (isMallocLikeFn(Alloc, TLI) || isAlignedAllocLikeFn(Alloc, TLI))
468  return UndefValue::get(Ty);
469 
470  // calloc zero initializes
471  if (isCallocLikeFn(Alloc, TLI))
472  return Constant::getNullValue(Ty);
473 
474  AllocFnKind AK = getAllocFnKind(Alloc);
476  return UndefValue::get(Ty);
478  return Constant::getNullValue(Ty);
479 
480  return nullptr;
481 }
482 
483 struct FreeFnsTy {
484  unsigned NumParams;
485  // Name of default allocator function to group malloc/free calls by family
487 };
488 
489 // clang-format off
490 static const std::pair<LibFunc, FreeFnsTy> FreeFnData[] = {
491  {LibFunc_vec_free, {1, MallocFamily::VecMalloc}},
492  {LibFunc_ZdlPv, {1, MallocFamily::CPPNew}}, // operator delete(void*)
493  {LibFunc_ZdaPv, {1, MallocFamily::CPPNewArray}}, // operator delete[](void*)
494  {LibFunc_msvc_delete_ptr32, {1, MallocFamily::MSVCNew}}, // operator delete(void*)
495  {LibFunc_msvc_delete_ptr64, {1, MallocFamily::MSVCNew}}, // operator delete(void*)
496  {LibFunc_msvc_delete_array_ptr32, {1, MallocFamily::MSVCArrayNew}}, // operator delete[](void*)
497  {LibFunc_msvc_delete_array_ptr64, {1, MallocFamily::MSVCArrayNew}}, // operator delete[](void*)
498  {LibFunc_ZdlPvj, {2, MallocFamily::CPPNew}}, // delete(void*, uint)
499  {LibFunc_ZdlPvm, {2, MallocFamily::CPPNew}}, // delete(void*, ulong)
500  {LibFunc_ZdlPvRKSt9nothrow_t, {2, MallocFamily::CPPNew}}, // delete(void*, nothrow)
501  {LibFunc_ZdlPvSt11align_val_t, {2, MallocFamily::CPPNewAligned}}, // delete(void*, align_val_t)
502  {LibFunc_ZdaPvj, {2, MallocFamily::CPPNewArray}}, // delete[](void*, uint)
503  {LibFunc_ZdaPvm, {2, MallocFamily::CPPNewArray}}, // delete[](void*, ulong)
504  {LibFunc_ZdaPvRKSt9nothrow_t, {2, MallocFamily::CPPNewArray}}, // delete[](void*, nothrow)
505  {LibFunc_ZdaPvSt11align_val_t, {2, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, align_val_t)
506  {LibFunc_msvc_delete_ptr32_int, {2, MallocFamily::MSVCNew}}, // delete(void*, uint)
507  {LibFunc_msvc_delete_ptr64_longlong, {2, MallocFamily::MSVCNew}}, // delete(void*, ulonglong)
508  {LibFunc_msvc_delete_ptr32_nothrow, {2, MallocFamily::MSVCNew}}, // delete(void*, nothrow)
509  {LibFunc_msvc_delete_ptr64_nothrow, {2, MallocFamily::MSVCNew}}, // delete(void*, nothrow)
510  {LibFunc_msvc_delete_array_ptr32_int, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, uint)
511  {LibFunc_msvc_delete_array_ptr64_longlong, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, ulonglong)
512  {LibFunc_msvc_delete_array_ptr32_nothrow, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, nothrow)
513  {LibFunc_msvc_delete_array_ptr64_nothrow, {2, MallocFamily::MSVCArrayNew}}, // delete[](void*, nothrow)
514  {LibFunc___kmpc_free_shared, {2, MallocFamily::KmpcAllocShared}}, // OpenMP Offloading RTL free
515  {LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, align_val_t, nothrow)
516  {LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, align_val_t, nothrow)
517  {LibFunc_ZdlPvjSt11align_val_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, unsigned int, align_val_t)
518  {LibFunc_ZdlPvmSt11align_val_t, {3, MallocFamily::CPPNewAligned}}, // delete(void*, unsigned long, align_val_t)
519  {LibFunc_ZdaPvjSt11align_val_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, unsigned int, align_val_t)
520  {LibFunc_ZdaPvmSt11align_val_t, {3, MallocFamily::CPPNewArrayAligned}}, // delete[](void*, unsigned long, align_val_t)
521 };
522 // clang-format on
523 
525  const LibFunc TLIFn) {
526  const auto *Iter =
527  find_if(FreeFnData, [TLIFn](const std::pair<LibFunc, FreeFnsTy> &P) {
528  return P.first == TLIFn;
529  });
530  if (Iter == std::end(FreeFnData))
531  return None;
532  return Iter->second;
533 }
534 
536  const TargetLibraryInfo *TLI) {
537  bool IsNoBuiltin;
538  const Function *Callee = getCalledFunction(I, IsNoBuiltin);
539  if (Callee == nullptr || IsNoBuiltin)
540  return None;
541  LibFunc TLIFn;
542 
543  if (TLI && TLI->getLibFunc(*Callee, TLIFn) && TLI->has(TLIFn)) {
544  // Callee is some known library function.
545  const auto AllocData = getAllocationDataForFunction(Callee, AnyAlloc, TLI);
546  if (AllocData)
547  return mangledNameForMallocFamily(AllocData.value().Family);
548  const auto FreeData = getFreeFunctionDataForFunction(Callee, TLIFn);
549  if (FreeData)
550  return mangledNameForMallocFamily(FreeData.value().Family);
551  }
552  // Callee isn't a known library function, still check attributes.
555  Attribute Attr = cast<CallBase>(I)->getFnAttr("alloc-family");
556  if (Attr.isValid())
557  return Attr.getValueAsString();
558  }
559  return None;
560 }
561 
562 /// isLibFreeFunction - Returns true if the function is a builtin free()
563 bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
565  if (!FnData)
567 
568  // Check free prototype.
569  // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
570  // attribute will exist.
571  FunctionType *FTy = F->getFunctionType();
572  if (!FTy->getReturnType()->isVoidTy())
573  return false;
574  if (FTy->getNumParams() != FnData->NumParams)
575  return false;
576  if (FTy->getParamType(0) != Type::getInt8PtrTy(F->getContext()))
577  return false;
578 
579  return true;
580 }
581 
583  bool IsNoBuiltinCall;
584  const Function *Callee = getCalledFunction(CB, IsNoBuiltinCall);
585  if (Callee == nullptr || IsNoBuiltinCall)
586  return nullptr;
587 
588  LibFunc TLIFn;
589  if (TLI && TLI->getLibFunc(*Callee, TLIFn) && TLI->has(TLIFn) &&
590  isLibFreeFunction(Callee, TLIFn)) {
591  // All currently supported free functions free the first argument.
592  return CB->getArgOperand(0);
593  }
594 
596  return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
597 
598  return nullptr;
599 }
600 
601 //===----------------------------------------------------------------------===//
602 // Utility functions to compute size of objects.
603 //
605  if (Data.second.isNegative() || Data.first.ult(Data.second))
606  return APInt(Data.first.getBitWidth(), 0);
607  return Data.first - Data.second;
608 }
609 
610 /// Compute the size of the object pointed by Ptr. Returns true and the
611 /// object size in Size if successful, and false otherwise.
612 /// If RoundToAlign is true, then Size is rounded up to the alignment of
613 /// allocas, byval arguments, and global variables.
614 bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
615  const TargetLibraryInfo *TLI, ObjectSizeOpts Opts) {
616  ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(), Opts);
617  SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
618  if (!Visitor.bothKnown(Data))
619  return false;
620 
622  return true;
623 }
624 
626  const DataLayout &DL,
627  const TargetLibraryInfo *TLI,
628  bool MustSucceed) {
629  return lowerObjectSizeCall(ObjectSize, DL, TLI, /*AAResults=*/nullptr,
630  MustSucceed);
631 }
632 
634  const DataLayout &DL,
635  const TargetLibraryInfo *TLI, AAResults *AA,
636  bool MustSucceed) {
637  assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
638  "ObjectSize must be a call to llvm.objectsize!");
639 
640  bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(1))->isZero();
641  ObjectSizeOpts EvalOptions;
642  EvalOptions.AA = AA;
643 
644  // Unless we have to fold this to something, try to be as accurate as
645  // possible.
646  if (MustSucceed)
647  EvalOptions.EvalMode =
649  else
651 
652  EvalOptions.NullIsUnknownSize =
653  cast<ConstantInt>(ObjectSize->getArgOperand(2))->isOne();
654 
655  auto *ResultType = cast<IntegerType>(ObjectSize->getType());
656  bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(3))->isZero();
657  if (StaticOnly) {
658  // FIXME: Does it make sense to just return a failure value if the size won't
659  // fit in the output and `!MustSucceed`?
660  uint64_t Size;
661  if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, EvalOptions) &&
662  isUIntN(ResultType->getBitWidth(), Size))
663  return ConstantInt::get(ResultType, Size);
664  } else {
665  LLVMContext &Ctx = ObjectSize->getFunction()->getContext();
666  ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, EvalOptions);
667  SizeOffsetEvalType SizeOffsetPair =
668  Eval.compute(ObjectSize->getArgOperand(0));
669 
670  if (SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown()) {
672  Builder.SetInsertPoint(ObjectSize);
673 
674  // If we've outside the end of the object, then we can always access
675  // exactly 0 bytes.
676  Value *ResultSize =
677  Builder.CreateSub(SizeOffsetPair.first, SizeOffsetPair.second);
678  Value *UseZero =
679  Builder.CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
680  ResultSize = Builder.CreateZExtOrTrunc(ResultSize, ResultType);
681  Value *Ret = Builder.CreateSelect(
682  UseZero, ConstantInt::get(ResultType, 0), ResultSize);
683 
684  // The non-constant size expression cannot evaluate to -1.
685  if (!isa<Constant>(SizeOffsetPair.first) ||
686  !isa<Constant>(SizeOffsetPair.second))
687  Builder.CreateAssumption(
688  Builder.CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
689 
690  return Ret;
691  }
692  }
693 
694  if (!MustSucceed)
695  return nullptr;
696 
697  return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0);
698 }
699 
700 STATISTIC(ObjectVisitorArgument,
701  "Number of arguments with unsolved size and offset");
702 STATISTIC(ObjectVisitorLoad,
703  "Number of load instructions with unsolved size and offset");
704 
705 APInt ObjectSizeOffsetVisitor::align(APInt Size, MaybeAlign Alignment) {
706  if (Options.RoundToAlign && Alignment)
707  return APInt(IntTyBits, alignTo(Size.getZExtValue(), *Alignment));
708  return Size;
709 }
710 
712  const TargetLibraryInfo *TLI,
715  : DL(DL), TLI(TLI), Options(Options) {
716  // Pointer size must be rechecked for each object visited since it could have
717  // a different address space.
718 }
719 
721  unsigned InitialIntTyBits = DL.getIndexTypeSizeInBits(V->getType());
722 
723  // Stripping pointer casts can strip address space casts which can change the
724  // index type size. The invariant is that we use the value type to determine
725  // the index type size and if we stripped address space casts we have to
726  // readjust the APInt as we pass it upwards in order for the APInt to match
727  // the type the caller passed in.
728  APInt Offset(InitialIntTyBits, 0);
730  DL, Offset, /* AllowNonInbounds */ true, /* AllowInvariantGroup */ true);
731 
732  // Later we use the index type size and zero but it will match the type of the
733  // value that is passed to computeImpl.
734  IntTyBits = DL.getIndexTypeSizeInBits(V->getType());
735  Zero = APInt::getZero(IntTyBits);
736 
737  bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
738  if (!IndexTypeSizeChanged && Offset.isZero())
739  return computeImpl(V);
740 
741  // We stripped an address space cast that changed the index type size or we
742  // accumulated some constant offset (or both). Readjust the bit width to match
743  // the argument index type size and apply the offset, as required.
744  SizeOffsetType SOT = computeImpl(V);
745  if (IndexTypeSizeChanged) {
746  if (knownSize(SOT) && !::CheckedZextOrTrunc(SOT.first, InitialIntTyBits))
747  SOT.first = APInt();
748  if (knownOffset(SOT) && !::CheckedZextOrTrunc(SOT.second, InitialIntTyBits))
749  SOT.second = APInt();
750  }
751  // If the computed offset is "unknown" we cannot add the stripped offset.
752  return {SOT.first,
753  SOT.second.getBitWidth() > 1 ? SOT.second + Offset : SOT.second};
754 }
755 
756 SizeOffsetType ObjectSizeOffsetVisitor::computeImpl(Value *V) {
757  if (Instruction *I = dyn_cast<Instruction>(V)) {
758  // If we have already seen this instruction, bail out. Cycles can happen in
759  // unreachable code after constant propagation.
760  if (!SeenInsts.insert(I).second)
761  return unknown();
762 
763  return visit(*I);
764  }
765  if (Argument *A = dyn_cast<Argument>(V))
766  return visitArgument(*A);
767  if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
768  return visitConstantPointerNull(*P);
769  if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
770  return visitGlobalAlias(*GA);
771  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
772  return visitGlobalVariable(*GV);
773  if (UndefValue *UV = dyn_cast<UndefValue>(V))
774  return visitUndefValue(*UV);
775 
776  LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: "
777  << *V << '\n');
778  return unknown();
779 }
780 
781 bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {
782  return ::CheckedZextOrTrunc(I, IntTyBits);
783 }
784 
786  TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
787  if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
788  return unknown();
789  APInt Size(IntTyBits, ElemSize.getKnownMinSize());
790  if (!I.isArrayAllocation())
791  return std::make_pair(align(Size, I.getAlign()), Zero);
792 
793  Value *ArraySize = I.getArraySize();
794  if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
795  APInt NumElems = C->getValue();
796  if (!CheckedZextOrTrunc(NumElems))
797  return unknown();
798 
799  bool Overflow;
800  Size = Size.umul_ov(NumElems, Overflow);
801  return Overflow ? unknown()
802  : std::make_pair(align(Size, I.getAlign()), Zero);
803  }
804  return unknown();
805 }
806 
808  Type *MemoryTy = A.getPointeeInMemoryValueType();
809  // No interprocedural analysis is done at the moment.
810  if (!MemoryTy|| !MemoryTy->isSized()) {
811  ++ObjectVisitorArgument;
812  return unknown();
813  }
814 
815  APInt Size(IntTyBits, DL.getTypeAllocSize(MemoryTy));
816  return std::make_pair(align(Size, A.getParamAlign()), Zero);
817 }
818 
820  if (Optional<APInt> Size = getAllocSize(&CB, TLI))
821  return std::make_pair(*Size, Zero);
822  return unknown();
823 }
824 
827  // If null is unknown, there's nothing we can do. Additionally, non-zero
828  // address spaces can make use of null, so we don't presume to know anything
829  // about that.
830  //
831  // TODO: How should this work with address space casts? We currently just drop
832  // them on the floor, but it's unclear what we should do when a NULL from
833  // addrspace(1) gets casted to addrspace(0) (or vice-versa).
834  if (Options.NullIsUnknownSize || CPN.getType()->getAddressSpace())
835  return unknown();
836  return std::make_pair(Zero, Zero);
837 }
838 
841  return unknown();
842 }
843 
846  // Easy cases were already folded by previous passes.
847  return unknown();
848 }
849 
851  if (GA.isInterposable())
852  return unknown();
853  return compute(GA.getAliasee());
854 }
855 
857  if (!GV.hasDefinitiveInitializer())
858  return unknown();
859 
860  APInt Size(IntTyBits, DL.getTypeAllocSize(GV.getValueType()));
861  return std::make_pair(align(Size, GV.getAlign()), Zero);
862 }
863 
865  // clueless
866  return unknown();
867 }
868 
869 SizeOffsetType ObjectSizeOffsetVisitor::findLoadSizeOffset(
872  unsigned &ScannedInstCount) {
873  constexpr unsigned MaxInstsToScan = 128;
874 
875  auto Where = VisitedBlocks.find(&BB);
876  if (Where != VisitedBlocks.end())
877  return Where->second;
878 
879  auto Unknown = [this, &BB, &VisitedBlocks]() {
880  return VisitedBlocks[&BB] = unknown();
881  };
882  auto Known = [&BB, &VisitedBlocks](SizeOffsetType SO) {
883  return VisitedBlocks[&BB] = SO;
884  };
885 
886  do {
887  Instruction &I = *From;
888 
889  if (I.isDebugOrPseudoInst())
890  continue;
891 
892  if (++ScannedInstCount > MaxInstsToScan)
893  return Unknown();
894 
895  if (!I.mayWriteToMemory())
896  continue;
897 
898  if (auto *SI = dyn_cast<StoreInst>(&I)) {
899  AliasResult AR =
900  Options.AA->alias(SI->getPointerOperand(), Load.getPointerOperand());
901  switch ((AliasResult::Kind)AR) {
903  continue;
905  if (SI->getValueOperand()->getType()->isPointerTy())
906  return Known(compute(SI->getValueOperand()));
907  else
908  return Unknown(); // No handling of non-pointer values by `compute`.
909  default:
910  return Unknown();
911  }
912  }
913 
914  if (auto *CB = dyn_cast<CallBase>(&I)) {
916  // Bail out on indirect call.
917  if (!Callee)
918  return Unknown();
919 
920  LibFunc TLIFn;
921  if (!TLI || !TLI->getLibFunc(*CB->getCalledFunction(), TLIFn) ||
922  !TLI->has(TLIFn))
923  return Unknown();
924 
925  // TODO: There's probably more interesting case to support here.
926  if (TLIFn != LibFunc_posix_memalign)
927  return Unknown();
928 
929  AliasResult AR =
930  Options.AA->alias(CB->getOperand(0), Load.getPointerOperand());
931  switch ((AliasResult::Kind)AR) {
933  continue;
935  break;
936  default:
937  return Unknown();
938  }
939 
940  // Is the error status of posix_memalign correctly checked? If not it
941  // would be incorrect to assume it succeeds and load doesn't see the
942  // previous value.
944  ICmpInst::ICMP_EQ, CB, ConstantInt::get(CB->getType(), 0), &Load, DL);
945  if (!Checked || !*Checked)
946  return Unknown();
947 
948  Value *Size = CB->getOperand(2);
949  auto *C = dyn_cast<ConstantInt>(Size);
950  if (!C)
951  return Unknown();
952 
953  return Known({C->getValue(), APInt(C->getValue().getBitWidth(), 0)});
954  }
955 
956  return Unknown();
957  } while (From-- != BB.begin());
958 
959  SmallVector<SizeOffsetType> PredecessorSizeOffsets;
960  for (auto *PredBB : predecessors(&BB)) {
961  PredecessorSizeOffsets.push_back(findLoadSizeOffset(
962  Load, *PredBB, BasicBlock::iterator(PredBB->getTerminator()),
963  VisitedBlocks, ScannedInstCount));
964  if (!bothKnown(PredecessorSizeOffsets.back()))
965  return Unknown();
966  }
967 
968  if (PredecessorSizeOffsets.empty())
969  return Unknown();
970 
971  return Known(std::accumulate(PredecessorSizeOffsets.begin() + 1,
972  PredecessorSizeOffsets.end(),
973  PredecessorSizeOffsets.front(),
975  return combineSizeOffset(LHS, RHS);
976  }));
977 }
978 
980  if (!Options.AA) {
981  ++ObjectVisitorLoad;
982  return unknown();
983  }
984 
986  unsigned ScannedInstCount = 0;
987  SizeOffsetType SO =
988  findLoadSizeOffset(LI, *LI.getParent(), BasicBlock::iterator(LI),
989  VisitedBlocks, ScannedInstCount);
990  if (!bothKnown(SO))
991  ++ObjectVisitorLoad;
992  return SO;
993 }
994 
995 SizeOffsetType ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetType LHS,
997  if (!bothKnown(LHS) || !bothKnown(RHS))
998  return unknown();
999 
1000  switch (Options.EvalMode) {
1002  return (getSizeWithOverflow(LHS).slt(getSizeWithOverflow(RHS))) ? LHS : RHS;
1004  return (getSizeWithOverflow(LHS).sgt(getSizeWithOverflow(RHS))) ? LHS : RHS;
1007  : unknown();
1009  return LHS == RHS && LHS.second.eq(RHS.second) ? LHS : unknown();
1010  }
1011  llvm_unreachable("missing an eval mode");
1012 }
1013 
1015  auto IncomingValues = PN.incoming_values();
1016  return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
1017  compute(*IncomingValues.begin()),
1018  [this](SizeOffsetType LHS, Value *VRHS) {
1019  return combineSizeOffset(LHS, compute(VRHS));
1020  });
1021 }
1022 
1024  return combineSizeOffset(compute(I.getTrueValue()),
1025  compute(I.getFalseValue()));
1026 }
1027 
1029  return std::make_pair(Zero, Zero);
1030 }
1031 
1033  LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor unknown instruction:" << I
1034  << '\n');
1035  return unknown();
1036 }
1037 
1039  const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
1040  ObjectSizeOpts EvalOpts)
1041  : DL(DL), TLI(TLI), Context(Context),
1044  [&](Instruction *I) { InsertedInstructions.insert(I); })),
1045  EvalOpts(EvalOpts) {
1046  // IntTy and Zero must be set for each compute() since the address space may
1047  // be different for later objects.
1048 }
1049 
1051  // XXX - Are vectors of pointers possible here?
1052  IntTy = cast<IntegerType>(DL.getIndexType(V->getType()));
1053  Zero = ConstantInt::get(IntTy, 0);
1054 
1055  SizeOffsetEvalType Result = compute_(V);
1056 
1057  if (!bothKnown(Result)) {
1058  // Erase everything that was computed in this iteration from the cache, so
1059  // that no dangling references are left behind. We could be a bit smarter if
1060  // we kept a dependency graph. It's probably not worth the complexity.
1061  for (const Value *SeenVal : SeenVals) {
1062  CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
1063  // non-computable results can be safely cached
1064  if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
1065  CacheMap.erase(CacheIt);
1066  }
1067 
1068  // Erase any instructions we inserted as part of the traversal.
1069  for (Instruction *I : InsertedInstructions) {
1070  I->replaceAllUsesWith(PoisonValue::get(I->getType()));
1071  I->eraseFromParent();
1072  }
1073  }
1074 
1075  SeenVals.clear();
1076  InsertedInstructions.clear();
1077  return Result;
1078 }
1079 
1080 SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
1081  ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, EvalOpts);
1082  SizeOffsetType Const = Visitor.compute(V);
1083  if (Visitor.bothKnown(Const))
1084  return std::make_pair(ConstantInt::get(Context, Const.first),
1085  ConstantInt::get(Context, Const.second));
1086 
1087  V = V->stripPointerCasts();
1088 
1089  // Check cache.
1090  CacheMapTy::iterator CacheIt = CacheMap.find(V);
1091  if (CacheIt != CacheMap.end())
1092  return CacheIt->second;
1093 
1094  // Always generate code immediately before the instruction being
1095  // processed, so that the generated code dominates the same BBs.
1096  BuilderTy::InsertPointGuard Guard(Builder);
1097  if (Instruction *I = dyn_cast<Instruction>(V))
1098  Builder.SetInsertPoint(I);
1099 
1100  // Now compute the size and offset.
1101  SizeOffsetEvalType Result;
1102 
1103  // Record the pointers that were handled in this run, so that they can be
1104  // cleaned later if something fails. We also use this set to break cycles that
1105  // can occur in dead code.
1106  if (!SeenVals.insert(V).second) {
1107  Result = unknown();
1108  } else if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
1109  Result = visitGEPOperator(*GEP);
1110  } else if (Instruction *I = dyn_cast<Instruction>(V)) {
1111  Result = visit(*I);
1112  } else if (isa<Argument>(V) ||
1113  (isa<ConstantExpr>(V) &&
1114  cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
1115  isa<GlobalAlias>(V) ||
1116  isa<GlobalVariable>(V)) {
1117  // Ignore values where we cannot do more than ObjectSizeVisitor.
1118  Result = unknown();
1119  } else {
1120  LLVM_DEBUG(
1121  dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
1122  << '\n');
1123  Result = unknown();
1124  }
1125 
1126  // Don't reuse CacheIt since it may be invalid at this point.
1127  CacheMap[V] = Result;
1128  return Result;
1129 }
1130 
1132  if (!I.getAllocatedType()->isSized())
1133  return unknown();
1134 
1135  // must be a VLA
1136  assert(I.isArrayAllocation());
1137 
1138  // If needed, adjust the alloca's operand size to match the pointer size.
1139  // Subsequent math operations expect the types to match.
1140  Value *ArraySize = Builder.CreateZExtOrTrunc(
1141  I.getArraySize(), DL.getIntPtrType(I.getContext()));
1142  assert(ArraySize->getType() == Zero->getType() &&
1143  "Expected zero constant to have pointer type");
1144 
1145  Value *Size = ConstantInt::get(ArraySize->getType(),
1146  DL.getTypeAllocSize(I.getAllocatedType()));
1147  Size = Builder.CreateMul(Size, ArraySize);
1148  return std::make_pair(Size, Zero);
1149 }
1150 
1152  Optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
1153  if (!FnData)
1154  return unknown();
1155 
1156  // Handle strdup-like functions separately.
1157  if (FnData->AllocTy == StrDupLike) {
1158  // TODO: implement evaluation of strdup/strndup
1159  return unknown();
1160  }
1161 
1162  Value *FirstArg = CB.getArgOperand(FnData->FstParam);
1163  FirstArg = Builder.CreateZExtOrTrunc(FirstArg, IntTy);
1164  if (FnData->SndParam < 0)
1165  return std::make_pair(FirstArg, Zero);
1166 
1167  Value *SecondArg = CB.getArgOperand(FnData->SndParam);
1168  SecondArg = Builder.CreateZExtOrTrunc(SecondArg, IntTy);
1169  Value *Size = Builder.CreateMul(FirstArg, SecondArg);
1170  return std::make_pair(Size, Zero);
1171 }
1172 
1175  return unknown();
1176 }
1177 
1180  return unknown();
1181 }
1182 
1185  SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());
1186  if (!bothKnown(PtrData))
1187  return unknown();
1188 
1189  Value *Offset = EmitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
1190  Offset = Builder.CreateAdd(PtrData.second, Offset);
1191  return std::make_pair(PtrData.first, Offset);
1192 }
1193 
1195  // clueless
1196  return unknown();
1197 }
1198 
1200  return unknown();
1201 }
1202 
1204  // Create 2 PHIs: one for size and another for offset.
1205  PHINode *SizePHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
1206  PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
1207 
1208  // Insert right away in the cache to handle recursive PHIs.
1209  CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI);
1210 
1211  // Compute offset/size for each PHI incoming pointer.
1212  for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
1213  Builder.SetInsertPoint(&*PHI.getIncomingBlock(i)->getFirstInsertionPt());
1214  SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i));
1215 
1216  if (!bothKnown(EdgeData)) {
1217  OffsetPHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1218  OffsetPHI->eraseFromParent();
1219  InsertedInstructions.erase(OffsetPHI);
1220  SizePHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1221  SizePHI->eraseFromParent();
1222  InsertedInstructions.erase(SizePHI);
1223  return unknown();
1224  }
1225  SizePHI->addIncoming(EdgeData.first, PHI.getIncomingBlock(i));
1226  OffsetPHI->addIncoming(EdgeData.second, PHI.getIncomingBlock(i));
1227  }
1228 
1229  Value *Size = SizePHI, *Offset = OffsetPHI;
1230  if (Value *Tmp = SizePHI->hasConstantValue()) {
1231  Size = Tmp;
1232  SizePHI->replaceAllUsesWith(Size);
1233  SizePHI->eraseFromParent();
1234  InsertedInstructions.erase(SizePHI);
1235  }
1236  if (Value *Tmp = OffsetPHI->hasConstantValue()) {
1237  Offset = Tmp;
1238  OffsetPHI->replaceAllUsesWith(Offset);
1239  OffsetPHI->eraseFromParent();
1240  InsertedInstructions.erase(OffsetPHI);
1241  }
1242  return std::make_pair(Size, Offset);
1243 }
1244 
1246  SizeOffsetEvalType TrueSide = compute_(I.getTrueValue());
1247  SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
1248 
1249  if (!bothKnown(TrueSide) || !bothKnown(FalseSide))
1250  return unknown();
1251  if (TrueSide == FalseSide)
1252  return TrueSide;
1253 
1254  Value *Size = Builder.CreateSelect(I.getCondition(), TrueSide.first,
1255  FalseSide.first);
1256  Value *Offset = Builder.CreateSelect(I.getCondition(), TrueSide.second,
1257  FalseSide.second);
1258  return std::make_pair(Size, Offset);
1259 }
1260 
1262  LLVM_DEBUG(dbgs() << "ObjectSizeOffsetEvaluator unknown instruction:" << I
1263  << '\n');
1264  return unknown();
1265 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::CallBase::getArgOperandWithAttribute
Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
Definition: Instructions.cpp:330
i
i
Definition: README.txt:29
llvm::isNewLikeFn
bool isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory via new.
Definition: MemoryBuiltins.cpp:308
llvm::ObjectSizeOffsetEvaluator::unknown
static SizeOffsetEvalType unknown()
Definition: MemoryBuiltins.h:277
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::SizeOffsetType
std::pair< APInt, APInt > SizeOffsetType
Definition: MemoryBuiltins.h:188
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:283
getAllocationSize
static Optional< AllocFnsTy > getAllocationSize(const Value *V, const TargetLibraryInfo *TLI)
Definition: MemoryBuiltins.cpp:235
llvm::ObjectSizeOffsetVisitor::visitGlobalAlias
SizeOffsetType visitGlobalAlias(GlobalAlias &GA)
Definition: MemoryBuiltins.cpp:850
llvm::getReallocatedOperand
Value * getReallocatedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this is a call to a realloc function, return the reallocated operand.
Definition: MemoryBuiltins.cpp:350
MathExtras.h
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:179
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::Attribute::isValid
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:184
AllocFnsTy::NumParams
unsigned NumParams
Definition: MemoryBuiltins.cpp:105
FreeFnData
static const std::pair< LibFunc, FreeFnsTy > FreeFnData[]
Definition: MemoryBuiltins.cpp:490
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:69
llvm::CmpInst::ICMP_EQ
@ ICMP_EQ
equal
Definition: InstrTypes.h:741
llvm::DataLayout::getIndexTypeSizeInBits
unsigned getIndexTypeSizeInBits(Type *Ty) const
Layout size of the index used in GEP calculation.
Definition: DataLayout.cpp:732
Optional.h
llvm::PHINode::incoming_values
op_range incoming_values()
Definition: Instructions.h:2785
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:291
MallocFamily::CPPNewArray
@ CPPNewArray
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:87
PHI
Rewrite undef for PHI
Definition: AMDGPURewriteUndefForPHI.cpp:101
IntrinsicInst.h
getFreeFunctionDataForFunction
Optional< FreeFnsTy > getFreeFunctionDataForFunction(const Function *Callee, const LibFunc TLIFn)
Definition: MemoryBuiltins.cpp:524
MallocFamily::Malloc
@ Malloc
llvm::ExtractElementInst
This instruction extracts a single (scalar) element from a VectorType value.
Definition: Instructions.h:1872
llvm::Function
Definition: Function.h:60
llvm::Attribute
Definition: Attributes.h:66
AllocFnsTy::AlignParam
int AlignParam
Definition: MemoryBuiltins.cpp:109
TargetFolder.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:53
AllocFnsTy::Family
MallocFamily Family
Definition: MemoryBuiltins.cpp:111
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
Statistic.h
llvm::ObjectSizeOffsetEvaluator::compute
SizeOffsetEvalType compute(Value *V)
Definition: MemoryBuiltins.cpp:1050
llvm::GlobalObject::getAlign
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
Definition: GlobalObject.h:79
llvm::ObjectSizeOffsetVisitor::visitExtractValueInst
SizeOffsetType visitExtractValueInst(ExtractValueInst &I)
Definition: MemoryBuiltins.cpp:845
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2525
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::PointerType::getAddressSpace
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:682
llvm::ObjectSizeOffsetEvaluator::visitSelectInst
SizeOffsetEvalType visitSelectInst(SelectInst &I)
Definition: MemoryBuiltins.cpp:1245
llvm::ObjectSizeOffsetEvaluator::visitGEPOperator
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP)
Definition: MemoryBuiltins.cpp:1184
llvm::SmallDenseMap
Definition: DenseMap.h:880
llvm::GlobalAlias
Definition: GlobalAlias.h:28
ValueTracking.h
isMallocLikeFn
static bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates uninitialized memory (such ...
Definition: MemoryBuiltins.cpp:314
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
APInt.h
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:321
CallocLike
@ CallocLike
Definition: MemoryBuiltins.cpp:58
llvm::DataLayout::getIndexType
Type * getIndexType(Type *PtrTy) const
Returns the type of a GEP index.
Definition: DataLayout.cpp:869
llvm::DenseMapIterator
Definition: DenseMap.h:57
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
MemoryBuiltins.h
llvm::ObjectSizeOpts::NullIsUnknownSize
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
Definition: MemoryBuiltins.h:162
AllocFnsTy
Definition: MemoryBuiltins.cpp:103
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
FreeFnsTy::Family
MallocFamily Family
Definition: MemoryBuiltins.cpp:486
llvm::AllocFnKind::Alloc
@ Alloc
llvm::Optional
Definition: APInt.h:33
llvm::ObjectSizeOffsetEvaluator::visitCallBase
SizeOffsetEvalType visitCallBase(CallBase &CB)
Definition: MemoryBuiltins.cpp:1151
llvm::Value::stripAndAccumulateConstantOffsets
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
llvm::AliasResult
The possible results of an alias query.
Definition: AliasAnalysis.h:83
llvm::ObjectSizeOpts::RoundToAlign
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
Definition: MemoryBuiltins.h:158
Operator.h
llvm::FunctionType::getNumParams
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:139
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
STLExtras.h
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
getAllocationData
static Optional< AllocFnsTy > getAllocationData(const Value *V, AllocType AllocTy, const TargetLibraryInfo *TLI)
Definition: MemoryBuiltins.cpp:215
llvm::AllocFnKind::Unknown
@ Unknown
llvm::ObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset
@ ExactUnderlyingSizeAndOffset
All branches must be known and have the same underlying size and offset to be merged.
llvm::ObjectSizeOffsetEvaluator::visitLoadInst
SizeOffsetEvalType visitLoadInst(LoadInst &I)
Definition: MemoryBuiltins.cpp:1199
llvm::EmitGEPOffset
Value * EmitGEPOffset(IRBuilderTy *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.h:29
llvm::LinearPolySize::isScalable
bool isScalable() const
Returns whether the size is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:298
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::APInt::getZero
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition: APInt.h:177
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
AliasAnalysis.h
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ObjectSizeOffsetEvaluator::visitIntToPtrInst
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst &)
Definition: MemoryBuiltins.cpp:1194
llvm::isAllocationFn
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...
Definition: MemoryBuiltins.cpp:295
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::ConstantPointerNull
A constant pointer value that points to null.
Definition: Constants.h:535
Instruction.h
MallocOrCallocLike
@ MallocOrCallocLike
Definition: MemoryBuiltins.cpp:62
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::Attribute::getValueAsInt
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition: Attributes.cpp:291
llvm::ObjectSizeOffsetVisitor::bothKnown
static bool bothKnown(const SizeOffsetType &SizeOffset)
Definition: MemoryBuiltins.h:221
llvm::IRBuilderBase::CreateMul
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1267
Constants.h
llvm::AAResults
Definition: AliasAnalysis.h:294
llvm::LibFunc
LibFunc
Definition: TargetLibraryInfo.h:36
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ObjectSizeOffsetVisitor::visitIntToPtrInst
SizeOffsetType visitIntToPtrInst(IntToPtrInst &)
Definition: MemoryBuiltins.cpp:864
llvm::ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts EvalOpts={})
Definition: MemoryBuiltins.cpp:1038
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1397
MallocFamily::CPPNewAligned
@ CPPNewAligned
SI
@ SI
Definition: SIInstrInfo.cpp:7966
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
TargetLibraryInfo.h
FreeFnsTy::NumParams
unsigned NumParams
Definition: MemoryBuiltins.cpp:484
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
llvm::isUIntN
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:422
llvm::TargetLibraryInfo::getLibFunc
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Definition: TargetLibraryInfo.h:298
llvm::ObjectSizeOffsetVisitor::visitGlobalVariable
SizeOffsetType visitGlobalVariable(GlobalVariable &GV)
Definition: MemoryBuiltins.cpp:856
llvm::Instruction
Definition: Instruction.h:42
llvm::ObjectSizeOffsetVisitor::visitAllocaInst
SizeOffsetType visitAllocaInst(AllocaInst &I)
Definition: MemoryBuiltins.cpp:785
llvm::ObjectSizeOffsetEvaluator::visitExtractElementInst
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I)
Definition: MemoryBuiltins.cpp:1174
llvm::ObjectSizeOpts::Mode::ExactSizeFromOffset
@ ExactSizeFromOffset
All branches must be known and have the same size, starting from the offset, to be merged.
AnyAlloc
@ AnyAlloc
Definition: MemoryBuiltins.cpp:64
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1486
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::predecessors
auto predecessors(MachineBasicBlock *BB)
Definition: MachineSSAContext.h:30
ReallocLike
@ ReallocLike
Definition: MemoryBuiltins.cpp:59
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1713
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:879
llvm::ObjectSizeOffsetEvaluator
Evaluate the size and offset of an object pointed to by a Value*.
Definition: MemoryBuiltins.h:256
llvm::FunctionCallee::getFunctionType
FunctionType * getFunctionType()
Definition: DerivedTypes.h:182
llvm::ObjectSizeOffsetEvaluator::visitPHINode
SizeOffsetEvalType visitPHINode(PHINode &PHI)
Definition: MemoryBuiltins.cpp:1203
llvm::getObjectSize
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.
Definition: MemoryBuiltins.cpp:614
llvm::Attribute::getValueAsString
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:312
Type.h
llvm::getFreedOperand
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
Definition: MemoryBuiltins.cpp:582
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:210
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::isReallocLikeFn
bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI)
Tests if a function is a call or invoke to a library function that reallocates memory (e....
Definition: MemoryBuiltins.cpp:345
llvm::AllocFnKind::Realloc
@ Realloc
llvm::AllocFnKind::Free
@ Free
llvm::getInitialValueOfAllocation
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,...
Definition: MemoryBuiltins.cpp:459
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:81
llvm::PHINode::hasConstantValue
Value * hasConstantValue() const
If the specified PHI node always merges together the same value, return the value,...
Definition: Instructions.cpp:154
AlignedAllocLike
@ AlignedAllocLike
Definition: MemoryBuiltins.cpp:57
uint64_t
llvm::pdb::Unknown
@ Unknown
Definition: PDBTypes.h:396
MallocFamily::CPPNewArrayAligned
@ CPPNewArrayAligned
llvm::GlobalVariable::hasDefinitiveInitializer
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
Definition: GlobalVariable.h:109
AllocFnsTy::SndParam
int SndParam
Definition: MemoryBuiltins.cpp:107
llvm::PHINode::addIncoming
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Definition: Instructions.h:2849
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:53
MallocFamily
MallocFamily
Definition: MemoryBuiltins.cpp:67
llvm::ObjectSizeOffsetVisitor::visitUndefValue
SizeOffsetType visitUndefValue(UndefValue &)
Definition: MemoryBuiltins.cpp:1028
I
#define I(x, y, z)
Definition: MD5.cpp:58
getCalledFunction
static const Function * getCalledFunction(const Value *V, bool &IsNoBuiltin)
Definition: MemoryBuiltins.cpp:154
llvm::FunctionType::getParamType
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:135
OpNewLike
@ OpNewLike
Definition: MemoryBuiltins.cpp:55
llvm::UndefValue
'undef' values are things that do not have specified contents.
Definition: Constants.h:1356
llvm::ObjectSizeOffsetVisitor
Evaluate the size and offset of an object pointed to by a Value* statically.
Definition: MemoryBuiltins.h:192
llvm::lowerObjectSizeCall
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.
Definition: MemoryBuiltins.cpp:625
llvm::IRBuilderBase::CreateSelect
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.cpp:1123
MallocOrOpNewLike
@ MallocOrOpNewLike
Definition: MemoryBuiltins.cpp:61
llvm::ObjectSizeOffsetVisitor::visitSelectInst
SizeOffsetType visitSelectInst(SelectInst &I)
Definition: MemoryBuiltins.cpp:1023
MallocFamily::CPPNew
@ CPPNew
llvm::InstVisitor< ObjectSizeOffsetVisitor, SizeOffsetType >::visit
void visit(Iterator Start, Iterator End)
Definition: InstVisitor.h:87
llvm::IRBuilderBase::CreateAdd
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1233
llvm::isAllocLikeFn
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,...
Definition: MemoryBuiltins.cpp:338
MallocLike
@ MallocLike
Definition: MemoryBuiltins.cpp:56
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
FreeFnsTy
Definition: MemoryBuiltins.cpp:483
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ObjectSizeOpts::Mode::Min
@ Min
Evaluate all branches of an unknown condition.
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::SelectInst
This class represents the LLVM 'select' instruction.
Definition: Instructions.h:1737
llvm::TargetLibraryInfo::has
bool has(LibFunc F) const
Tests whether a library function is available.
Definition: TargetLibraryInfo.h:332
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
llvm::IRBuilderCallbackInserter
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
Definition: IRBuilder.h:75
getOpcode
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:191
llvm::GEPOperator
Definition: Operator.h:375
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
MallocFamily::VecMalloc
@ VecMalloc
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
MallocFamily::KmpcAllocShared
@ KmpcAllocShared
llvm::IRBuilderBase::CreatePHI
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:2254
llvm::SmallPtrSetImplBase::clear
void clear()
Definition: SmallPtrSet.h:95
llvm::ObjectSizeOffsetEvaluator::visitAllocaInst
SizeOffsetEvalType visitAllocaInst(AllocaInst &I)
Definition: MemoryBuiltins.cpp:1131
llvm::ObjectSizeOpts::AA
AAResults * AA
If set, used for more accurate evaluation.
Definition: MemoryBuiltins.h:164
None.h
DataLayout.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::Instruction::getFunction
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:73
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
llvm::AliasResult::NoAlias
@ NoAlias
The two locations do not alias at all.
Definition: AliasAnalysis.h:101
llvm::IRBuilderBase::InsertPointGuard
Definition: IRBuilder.h:358
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::AliasResult::MustAlias
@ MustAlias
The two locations precisely alias each other.
Definition: AliasAnalysis.h:108
Local.h
llvm::ObjectSizeOpts
Various options to control the behavior of getObjectSize.
Definition: MemoryBuiltins.h:138
llvm::GlobalAlias::getAliasee
const Constant * getAliasee() const
Definition: GlobalAlias.h:84
AllocationFnData
static const std::pair< LibFunc, AllocFnsTy > AllocationFnData[]
Definition: MemoryBuiltins.cpp:117
llvm::Type::getContext
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::ObjectSizeOpts::Mode::Max
@ Max
Same as Min, except we pick the maximum size of all of the branches.
llvm::ObjectSizeOffsetVisitor::visitLoadInst
SizeOffsetType visitLoadInst(LoadInst &I)
Definition: MemoryBuiltins.cpp:979
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:685
Argument.h
llvm::find_if
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:1761
llvm::ObjectSizeOffsetVisitor::visitInstruction
SizeOffsetType visitInstruction(Instruction &I)
Definition: MemoryBuiltins.cpp:1032
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:187
CheckedZextOrTrunc
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....
Definition: MemoryBuiltins.cpp:386
llvm::GlobalValue::isInterposable
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
Definition: Globals.cpp:102
llvm::GetStringLength
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'.
Definition: ValueTracking.cpp:4432
mangledNameForMallocFamily
StringRef mangledNameForMallocFamily(const MallocFamily &Family)
Definition: MemoryBuiltins.cpp:79
Attributes.h
llvm::DataLayout::getIntPtrType
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Definition: DataLayout.cpp:842
llvm::TargetFolder
TargetFolder - Create constants with target dependent folding.
Definition: TargetFolder.h:34
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:350
llvm::ObjectSizeOffsetVisitor::visitCallBase
SizeOffsetType visitCallBase(CallBase &CB)
Definition: MemoryBuiltins.cpp:819
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
llvm::ObjectSizeOffsetVisitor::visitArgument
SizeOffsetType visitArgument(Argument &A)
Definition: MemoryBuiltins.cpp:807
getAllocFnKind
static AllocFnKind getAllocFnKind(const Value *V)
Definition: MemoryBuiltins.cpp:268
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
llvm::getAllocationFamily
Optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
Definition: MemoryBuiltins.cpp:535
GlobalVariable.h
llvm::ObjectSizeOpts::EvalMode
Mode EvalMode
How we want to evaluate this object's size.
Definition: MemoryBuiltins.h:155
llvm::ExtractValueInst
This instruction extracts a struct member or array element value from an aggregate value.
Definition: Instructions.h:2446
llvm::TypeSize
Definition: TypeSize.h:435
llvm::AllocFnKind::Uninitialized
@ Uninitialized
llvm::getAllocAlignment
Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
Definition: MemoryBuiltins.cpp:372
llvm::getAllocSize
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.
Definition: MemoryBuiltins.cpp:398
llvm::SizeOffsetEvalType
std::pair< Value *, Value * > SizeOffsetEvalType
Definition: MemoryBuiltins.h:252
Casting.h
llvm::isRemovableAlloc
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...
Definition: MemoryBuiltins.cpp:361
Function.h
llvm::ObjectSizeOffsetVisitor::knownOffset
static bool knownOffset(const SizeOffsetType &SizeOffset)
Definition: MemoryBuiltins.h:217
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:226
llvm::AAResults::alias
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
Definition: AliasAnalysis.cpp:107
isCallocLikeFn
static bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates zero-filled memory (such as...
Definition: MemoryBuiltins.cpp:326
llvm::IntToPtrInst
This class represents a cast from an integer to a pointer.
Definition: Instructions.h:5162
GlobalAlias.h
AllocType
AllocType
Definition: MemoryBuiltins.cpp:54
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::AliasResult::Kind
Kind
Definition: AliasAnalysis.h:95
llvm::ObjectSizeOffsetVisitor::compute
SizeOffsetType compute(Value *V)
Definition: MemoryBuiltins.cpp:720
llvm::ObjectSizeOffsetVisitor::visitConstantPointerNull
SizeOffsetType visitConstantPointerNull(ConstantPointerNull &)
Definition: MemoryBuiltins.cpp:826
Instructions.h
getSizeWithOverflow
static APInt getSizeWithOverflow(const SizeOffsetType &Data)
Definition: MemoryBuiltins.cpp:604
llvm::DenseMapBase< DenseMap< const Value *, WeakEvalType, DenseMapInfo< const Value * >, llvm::detail::DenseMapPair< const Value *, WeakEvalType > >, const Value *, WeakEvalType, DenseMapInfo< const Value * >, llvm::detail::DenseMapPair< const Value *, WeakEvalType > >::iterator
DenseMapIterator< const Value *, WeakEvalType, DenseMapInfo< const Value * >, llvm::detail::DenseMapPair< const Value *, WeakEvalType > > iterator
Definition: DenseMap.h:71
llvm::isImpliedByDomCondition
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...
Definition: ValueTracking.cpp:6904
llvm::ObjectSizeOffsetEvaluator::visitExtractValueInst
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I)
Definition: MemoryBuiltins.cpp:1179
StrDupLike
@ StrDupLike
Definition: MemoryBuiltins.cpp:60
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1342
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:91
llvm::ObjectSizeOffsetEvaluator::visitInstruction
SizeOffsetEvalType visitInstruction(Instruction &I)
Definition: MemoryBuiltins.cpp:1261
llvm::ObjectSizeOffsetVisitor::knownSize
static bool knownSize(const SizeOffsetType &SizeOffset)
Definition: MemoryBuiltins.h:213
llvm::AllocFnKind
AllocFnKind
Definition: Attributes.h:48
llvm::PHINode
Definition: Instructions.h:2699
llvm::TypeSize::getKnownMinSize
ScalarTy getKnownMinSize() const
Definition: TypeSize.h:445
getAllocationDataForFunction
static 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.
Definition: MemoryBuiltins.cpp:174
llvm::IRBuilderBase::CreateZExtOrTrunc
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition: IRBuilder.h:1903
llvm::ObjectSizeOffsetEvaluator::bothKnown
bool bothKnown(SizeOffsetEvalType SizeOffset)
Definition: MemoryBuiltins.h:298
MallocFamily::MSVCArrayNew
@ MSVCArrayNew
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1175
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:399
DerivedTypes.h
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:292
AllocLike
@ AllocLike
Definition: MemoryBuiltins.cpp:63
llvm::ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options={})
Definition: MemoryBuiltins.cpp:711
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:171
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::ConstantPointerNull::getType
PointerType * getType() const
Specialize the getType() method to always return an PointerType, which reduces the amount of casting ...
Definition: Constants.h:551
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:59
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::isLibFreeFunction
bool isLibFreeFunction(const Function *F, const LibFunc TLIFn)
isLibFreeFunction - Returns true if the function is a builtin free()
Definition: MemoryBuiltins.cpp:563
raw_ostream.h
llvm::ObjectSizeOffsetVisitor::visitExtractElementInst
SizeOffsetType visitExtractElementInst(ExtractElementInst &I)
Definition: MemoryBuiltins.cpp:840
checkFnAllocKind
static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted)
Definition: MemoryBuiltins.cpp:284
AllocFnsTy::FstParam
int FstParam
Definition: MemoryBuiltins.cpp:107
Value.h
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition: DerivedTypes.h:124
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::ObjectSizeOffsetEvaluator::anyKnown
bool anyKnown(SizeOffsetEvalType SizeOffset)
Definition: MemoryBuiltins.h:294
Debug.h
llvm::AllocFnKind::Zeroed
@ Zeroed
AllocFnsTy::AllocTy
AllocType AllocTy
Definition: MemoryBuiltins.cpp:104
MallocFamily::MSVCNew
@ MSVCNew
llvm::isMallocOrCallocLikeFn
bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory similar to malloc or...
Definition: MemoryBuiltins.cpp:332
llvm::ObjectSizeOffsetVisitor::visitPHINode
SizeOffsetType visitPHINode(PHINode &)
Definition: MemoryBuiltins.cpp:1014
llvm::Attribute::getAllocSizeArgs
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition: Attributes.cpp:362
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:365
isAlignedAllocLikeFn
static bool isAlignedAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates uninitialized memory with a...
Definition: MemoryBuiltins.cpp:320
llvm::DataLayout::getTypeAllocSize
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:506
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1732