45#define DEBUG_TYPE "tysan"
53 "__tysan_shadow_memory_address";
61STATISTIC(NumInstrumentedAccesses,
"Number of instrumented accesses");
70 void instrumentGlobals(
Module &M);
77 void initializeCallbacks(
Module &M);
84 bool IsWrite,
Value *ShadowBase,
85 Value *AppMemMask,
bool ForceSetType,
86 bool SanitizeFunction,
87 TypeDescriptorsMapTy &TypeDescriptors,
95 std::string getAnonymousStructIdentifier(
const MDNode *MD,
96 TypeNameMapTy &TypeNames);
97 bool generateTypeDescriptor(
const MDNode *MD,
98 TypeDescriptorsMapTy &TypeDescriptors,
99 TypeNameMapTy &TypeNames,
Module &M);
100 bool generateBaseTypeDescriptor(
const MDNode *MD,
101 TypeDescriptorsMapTy &TypeDescriptors,
102 TypeNameMapTy &TypeNames,
Module &M);
104 const Triple TargetTriple;
115 Function *TysanGlobalsSetTypeFunction;
119TypeSanitizer::TypeSanitizer(
Module &M)
120 : TargetTriple(
M.getTargetTriple()),
121 AnonNameRegex(
"^_ZTS.*N[1-9][0-9]*_GLOBAL__N") {
123 IntptrTy =
DL.getIntPtrType(
M.getContext());
124 PtrShift =
countr_zero(IntptrTy->getPrimitiveSizeInBits() / 8);
126 TysanGlobalsSetTypeFunction =
M.getFunction(
"__tysan_set_globals_types");
127 initializeCallbacks(M);
130void TypeSanitizer::initializeCallbacks(
Module &M) {
132 OrdTy = IRB.getInt32Ty();
149void TypeSanitizer::instrumentGlobals(
Module &M) {
150 TysanGlobalsSetTypeFunction =
nullptr;
152 NamedMDNode *Globals =
M.getNamedMetadata(
"llvm.tysan.globals");
164 Value *ShadowBase = getShadowBase(*TysanGlobalsSetTypeFunction);
165 Value *AppMemMask = getAppMemMask(*TysanGlobalsSetTypeFunction);
166 TypeDescriptorsMapTy TypeDescriptors;
167 TypeNameMapTy TypeNames;
169 for (
const auto &GMD : Globals->
operands()) {
170 auto *GV = mdconst::dyn_extract_or_null<GlobalVariable>(GMD->getOperand(0));
173 const MDNode *TBAAMD = cast<MDNode>(GMD->getOperand(1));
174 if (!generateBaseTypeDescriptor(TBAAMD, TypeDescriptors, TypeNames, M))
178 TysanGlobalsSetTypeFunction->getEntryBlock().getTerminator());
179 Type *AccessTy = GV->getValueType();
181 uint64_t AccessSize =
DL.getTypeStoreSize(AccessTy);
182 instrumentWithShadowUpdate(IRB, TBAAMD, GV, AccessSize,
false,
false,
183 ShadowBase, AppMemMask,
true,
false,
184 TypeDescriptors,
DL);
187 if (TysanGlobalsSetTypeFunction) {
188 IRBuilder<> IRB(cast<Function>(TysanCtorFunction.getCallee())
191 IRB.CreateCall(TysanGlobalsSetTypeFunction, {});
195static const char LUT[] =
"0123456789abcdef";
200 Output.reserve(Output.size() + 3 *
Length);
201 for (
size_t i = 0; i <
Length; ++i) {
202 const unsigned char c =
Name[i];
213 Output.push_back(
'_');
214 Output.push_back(
LUT[c >> 4]);
215 Output.push_back(
LUT[c & 15]);
222TypeSanitizer::getAnonymousStructIdentifier(
const MDNode *MD,
223 TypeNameMapTy &TypeNames) {
231 auto TNI = TypeNames.find(MemberNode);
232 std::string MemberName;
233 if (TNI != TypeNames.end()) {
234 MemberName = TNI->second;
242 if (MemberName.empty())
243 MemberName = getAnonymousStructIdentifier(MemberNode, TypeNames);
244 if (MemberName.empty())
246 TypeNames[MemberNode] = MemberName;
253 mdconst::extract<ConstantInt>(MD->
getOperand(i + 1))->getZExtValue();
259 Hash.
final(HashResult);
260 return "__anonymous_" + std::string(HashResult.
digest().
str());
263bool TypeSanitizer::generateBaseTypeDescriptor(
264 const MDNode *MD, TypeDescriptorsMapTy &TypeDescriptors,
265 TypeNameMapTy &TypeNames,
Module &M) {
275 Name = getAnonymousStructIdentifier(MD, TypeNames);
278 TypeNames[MD] =
Name;
282 dyn_cast_or_null<GlobalVariable>(
M.getNamedValue(EncodedName));
284 TypeDescriptors[MD] = GV;
295 auto TDI = TypeDescriptors.find(MemberNode);
296 if (TDI != TypeDescriptors.end()) {
299 if (!generateBaseTypeDescriptor(MemberNode, TypeDescriptors, TypeNames,
303 Member = TypeDescriptors[MemberNode];
307 mdconst::extract<ConstantInt>(MD->
getOperand(i + 1))->getZExtValue();
325 PushTDSub(ConstantInt::get(IntptrTy, 2));
326 PushTDSub(ConstantInt::get(IntptrTy, Members.
size()));
334 bool ShouldBeComdat = !AnonNameRegex.match(NameNode->
getString());
335 for (
auto &Member : Members) {
337 PushTDSub(ConstantInt::get(IntptrTy,
Member.second));
350 M.insertGlobalVariable(TDGV);
352 if (ShouldBeComdat) {
353 if (TargetTriple.isOSBinFormatELF()) {
354 Comdat *TDComdat =
M.getOrInsertComdat(EncodedName);
360 TypeDescriptors[MD] = TDGV;
364bool TypeSanitizer::generateTypeDescriptor(
365 const MDNode *MD, TypeDescriptorsMapTy &TypeDescriptors,
366 TypeNameMapTy &TypeNames,
Module &M) {
385 auto TDI = TypeDescriptors.find(BaseNode);
386 if (TDI != TypeDescriptors.end()) {
389 if (!generateBaseTypeDescriptor(BaseNode, TypeDescriptors, TypeNames, M))
392 Base = TypeDescriptors[BaseNode];
396 TDI = TypeDescriptors.find(AccessNode);
397 if (TDI != TypeDescriptors.end()) {
400 if (!generateBaseTypeDescriptor(AccessNode, TypeDescriptors, TypeNames, M))
403 Access = TypeDescriptors[AccessNode];
407 mdconst::extract<ConstantInt>(MD->
getOperand(2))->getZExtValue();
408 std::string EncodedName =
409 std::string(
Base->getName()) +
"_o_" + utostr(
Offset);
412 dyn_cast_or_null<GlobalVariable>(
M.getNamedValue(EncodedName));
414 TypeDescriptors[MD] = GV;
425 ConstantInt::get(IntptrTy,
Offset));
427 bool ShouldBeComdat = cast<GlobalVariable>(
Base)->getLinkage() ==
435 M.insertGlobalVariable(TDGV);
437 if (ShouldBeComdat) {
438 if (TargetTriple.isOSBinFormatELF()) {
439 Comdat *TDComdat =
M.getOrInsertComdat(EncodedName);
445 TypeDescriptors[MD] = TDGV;
453 return IRB.CreateLoad(IntptrTy, GlobalShadowAddress,
"shadow.base");
458 Value *GlobalAppMemMask =
460 return IRB.CreateLoad(IntptrTy, GlobalAppMemMask,
"app.mem.mask");
467 SmallVectorImpl<std::pair<Instruction *, MemoryLocation>> &MemoryAccesses,
473 if (Inst.getMetadata(LLVMContext::MD_nosanitize))
476 if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
477 isa<AtomicCmpXchgInst>(Inst) || isa<AtomicRMWInst>(Inst)) {
491 MemoryAccesses.push_back(std::make_pair(&Inst, MLoc));
492 }
else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
493 if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
496 if (isa<MemIntrinsic, LifetimeIntrinsic>(Inst))
498 }
else if (isa<AllocaInst>(Inst)) {
504bool TypeSanitizer::sanitizeFunction(
Function &
F,
506 if (
F.isDeclaration())
510 if (&
F == TysanCtorFunction.getCallee() || &
F == TysanGlobalsSetTypeFunction)
512 initializeCallbacks(*
F.getParent());
523 for (
auto &
A :
F.args())
524 if (
A.hasByValAttr())
528 TypeDescriptorsMapTy TypeDescriptors;
529 TypeNameMapTy TypeNames;
531 for (
const MDNode *MD : TBAAMetadata) {
532 if (TypeDescriptors.count(MD))
535 if (!generateTypeDescriptor(MD, TypeDescriptors, TypeNames, M))
542 bool SanitizeFunction =
F.hasFnAttribute(Attribute::SanitizeType);
543 bool NeedsInstrumentation =
544 MemTypeResetInsts.
empty() && MemoryAccesses.
empty();
545 Instruction *ShadowBase = NeedsInstrumentation ? nullptr : getShadowBase(
F);
546 Instruction *AppMemMask = NeedsInstrumentation ? nullptr : getAppMemMask(
F);
547 for (
const auto &[
I, MLoc] : MemoryAccesses) {
549 assert(MLoc.Size.isPrecise());
550 if (instrumentWithShadowUpdate(
551 IRB, MLoc.AATags.TBAA,
const_cast<Value *
>(MLoc.Ptr),
552 MLoc.Size.getValue(),
I->mayReadFromMemory(),
I->mayWriteToMemory(),
553 ShadowBase, AppMemMask,
false, SanitizeFunction, TypeDescriptors,
555 ++NumInstrumentedAccesses;
560 for (
auto Inst : MemTypeResetInsts)
561 Res |= instrumentMemInst(Inst, ShadowBase, AppMemMask,
DL);
572 AppMemMask,
"app.ptr.masked"),
573 PtrShift,
"app.ptr.shifted"),
574 ShadowBase,
"shadow.ptr.int");
577bool TypeSanitizer::instrumentWithShadowUpdate(
579 bool IsRead,
bool IsWrite,
Value *ShadowBase,
Value *AppMemMask,
580 bool ForceSetType,
bool SanitizeFunction,
581 TypeDescriptorsMapTy &TypeDescriptors,
const DataLayout &
DL) {
584 TDGV = TypeDescriptors[TBAAMD];
591 ShadowBase, AppMemMask);
596 auto SetType = [&]() {
601 for (
uint64_t i = 1; i < AccessSize; ++i) {
604 ConstantInt::get(IntptrTy, i << PtrShift),
605 "shadow.byte." +
Twine(i) +
".offset"),
606 Int8PtrPtrTy,
"shadow.byte." +
Twine(i) +
".ptr");
625 "should have handled case above");
629 if (!SanitizeFunction) {
637 NullTDTerm->
getParent()->setName(
"set.type");
696 Constant *
Flags = ConstantInt::get(OrdTy,
int(IsRead) | (
int(IsWrite) << 1));
702 &GoodTDTerm, UnlikelyBW);
717 Value *
Size = ConstantInt::get(OrdTy, AccessSize);
719 for (
uint64_t i = 1; i < AccessSize; ++i) {
721 IRB.
CreateAdd(ShadowDataInt, ConstantInt::get(IntptrTy, i << PtrShift)),
746 for (
uint64_t i = 1; i < AccessSize; ++i) {
748 IRB.
CreateAdd(ShadowDataInt, ConstantInt::get(IntptrTy, i << PtrShift)),
753 NotAllBadTD, IRB.
CreateICmpSGE(ILdTD, ConstantInt::get(IntptrTy, 0)));
771 if (
auto *
I = dyn_cast<Instruction>(V)) {
776 auto *
A = cast<Argument>(V);
778 BB = &
F->getEntryBlock();
782 if (IP->comesBefore(ShadowBase))
784 if (IP->comesBefore(AppMemMask))
789 bool NeedsMemMove =
false;
795 ConstantInt::get(IntptrTy,
796 DL.getTypeAllocSize(AI->getAllocatedType())));
799 if (
auto *
A = dyn_cast<Argument>(V)) {
800 assert(
A->hasByValAttr() &&
"Type reset for non-byval argument?");
804 ConstantInt::get(IntptrTy,
DL.getTypeAllocSize(
A->getParamByValType()));
806 auto *
I = cast<Instruction>(V);
807 if (
auto *
MI = dyn_cast<MemIntrinsic>(
I)) {
808 if (
MI->getDestAddressSpace() != 0)
811 Dest =
MI->getDest();
814 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
815 if (MTI->getSourceAddressSpace() == 0) {
816 Src = MTI->getSource();
817 NeedsMemMove = isa<MemMoveInst>(MTI);
820 }
else if (
auto *
II = dyn_cast<LifetimeIntrinsic>(
I)) {
821 auto *AI = dyn_cast<AllocaInst>(
II->getArgOperand(0));
825 Size = GetAllocaSize(AI);
826 Dest =
II->getArgOperand(0);
827 }
else if (
auto *AI = dyn_cast<AllocaInst>(
I)) {
834 Size = GetAllocaSize(AI);
842 ShadowBase = getShadowBase(*
F);
844 AppMemMask = getAppMemMask(*
F);
855 Align(1ull << PtrShift));
880 std::tie(TysanCtorFunction, std::ignore) =
885 TypeSanitizer TySan(M);
886 TySan.instrumentGlobals(M);
892 TySan.sanitizeFunction(
F, TLI);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static const char *const kTysanInitName
static Value * convertToShadowDataInt(IRBuilder<> &IRB, Value *Ptr, Type *IntptrTy, uint64_t PtrShift, Value *ShadowBase, Value *AppMemMask)
static const char *const kTysanShadowMemoryAddress
static const char *const kTysanGVNamePrefix
static const char *const kTysanModuleCtorName
static const char *const kTysanAppMemMask
void collectMemAccessInfo(Function &F, const TargetLibraryInfo &TLI, SmallVectorImpl< std::pair< Instruction *, MemoryLocation > > &MemoryAccesses, SmallSetVector< const MDNode *, 8 > &TBAAMetadata, SmallVectorImpl< Value * > &MemTypeResetInsts)
Collect all loads and stores, and for what TBAA nodes we need to generate type descriptors.
static cl::opt< bool > ClWritesAlwaysSetType("tysan-writes-always-set-type", cl::desc("Writes always set the type"), cl::Hidden, cl::init(false))
static const char *const kTysanCheckName
static std::string encodeName(StringRef Name)
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
LLVM Basic Block Representation.
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...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
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.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
LLVM_ABI void setComdat(Comdat *C)
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
BasicBlock::iterator GetInsertPoint() const
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
CallInst * CreateMemMove(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getFalse()
Get the constant value for i1 false.
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
LLVM_ABI void SetInstDebugLocation(Instruction *I) const
If this builder has a current debug location, set it on the specified instruction.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
LLVMContext & getContext() const
LLVM_ABI StringRef getString() const
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
const Value * Ptr
The address of the start of the location.
A Module instance is used to store all the information related to an LLVM module.
iterator_range< op_iterator > operands()
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
MDNode * TBAA
The tag for type-based alias analysis.
This struct is a compact representation of a valid (non-zero power of two) alignment.
LLVM_ABI SmallString< 32 > digest() const
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)