83static const unsigned Read = 1;
84static const unsigned Write = 2;
85static const unsigned Callee = 4;
86static const unsigned Branchee = 8;
119 Value *findValue(
Value *V,
bool OffsetOk)
const;
132 std::string Messages;
137 :
Mod(
Mod), TT(
Mod->getTargetTriple()),
DL(
DL), AA(AA), AC(AC), DT(DT),
138 TLI(TLI), MessagesStr(Messages) {}
141 for (
const Value *V : Vs) {
144 if (isa<Instruction>(V)) {
145 MessagesStr << *
V <<
'\n';
147 V->printAsOperand(MessagesStr,
true,
Mod);
157 void CheckFailed(
const Twine &Message) { MessagesStr << Message <<
'\n'; }
163 template <
typename T1,
typename... Ts>
164 void CheckFailed(
const Twine &Message,
const T1 &V1,
const Ts &... Vs) {
165 CheckFailed(Message);
166 WriteValues({V1, Vs...});
172#define Check(C, ...) \
175 CheckFailed(__VA_ARGS__); \
183 Check(
F.hasName() ||
F.hasLocalLinkage(),
184 "Unusual: Unnamed function with non-local linkage", &
F);
193 nullptr, MemRef::Callee);
195 if (
Function *
F = dyn_cast<Function>(findValue(Callee,
197 Check(
I.getCallingConv() ==
F->getCallingConv(),
198 "Undefined behavior: Caller and callee calling convention differ",
202 unsigned NumActualArgs =
I.arg_size();
204 Check(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
205 : FT->getNumParams() == NumActualArgs,
206 "Undefined behavior: Call argument count mismatches callee "
210 Check(FT->getReturnType() ==
I.getType(),
211 "Undefined behavior: Call return type mismatches "
212 "callee return type",
218 auto AI =
I.arg_begin(), AE =
I.arg_end();
219 for (; AI != AE; ++AI) {
224 "Undefined behavior: Call argument type mismatches "
225 "callee parameter type",
234 for (
auto *BI =
I.arg_begin(); BI != AE; ++BI, ++ArgNo) {
244 if (
I.doesNotAccessMemory(ArgNo))
246 if (AI != BI && (*BI)->getType()->isPointerTy() &&
247 !isa<ConstantPointerNull>(*BI)) {
251 "Unusual: noalias argument aliases another argument", &
I);
261 visitMemoryReference(
I, Loc,
DL->getABITypeAlign(Ty), Ty,
262 MemRef::Read | MemRef::Write);
266 unsigned ArgNo = AI->getOperandNo();
268 Attribute::ZExt, Attribute::SExt, Attribute::InReg,
269 Attribute::ByVal, Attribute::ByRef, Attribute::InAlloca,
270 Attribute::Preallocated, Attribute::StructRet};
276 Twine(
"Undefined behavior: ABI attribute ") +
278 " not present on both function and call-site",
282 Twine(
"Undefined behavior: ABI attribute ") +
284 " does not have same argument for function and call-site",
292 if (
const auto *CI = dyn_cast<CallInst>(&
I)) {
293 if (CI->isTailCall()) {
296 for (
Value *Arg :
I.args()) {
301 Value *Obj = findValue(Arg,
true);
302 Check(!isa<AllocaInst>(Obj),
303 "Undefined behavior: Call with \"tail\" keyword references "
311 switch (
II->getIntrinsicID()) {
317 case Intrinsic::memcpy:
318 case Intrinsic::memcpy_inline: {
330 dyn_cast<ConstantInt>(findValue(MCI->
getLength(),
332 if (
Len->getValue().isIntN(32))
336 "Undefined behavior: memcpy source and destination overlap", &
I);
339 case Intrinsic::memmove: {
347 case Intrinsic::memset:
348 case Intrinsic::memset_inline: {
354 case Intrinsic::vastart:
357 std::nullopt,
nullptr, MemRef::Read | MemRef::Write);
359 case Intrinsic::vacopy:
361 std::nullopt,
nullptr, MemRef::Write);
363 std::nullopt,
nullptr, MemRef::Read);
365 case Intrinsic::vaend:
367 std::nullopt,
nullptr, MemRef::Read | MemRef::Write);
370 case Intrinsic::stackrestore:
375 std::nullopt,
nullptr, MemRef::Read | MemRef::Write);
377 case Intrinsic::get_active_lane_mask:
378 if (
auto *TripCount = dyn_cast<ConstantInt>(
I.getArgOperand(1)))
379 Check(!TripCount->isZero(),
380 "get_active_lane_mask: operand #2 "
381 "must be greater than 0",
389 Check(!
F->doesNotReturn(),
390 "Unusual: Return statement in function with noreturn attribute", &
I);
392 if (
Value *V =
I.getReturnValue()) {
393 Value *Obj = findValue(V,
true);
394 Check(!isa<AllocaInst>(Obj),
"Unusual: Returning alloca value", &
I);
410 "Undefined behavior: Null pointer dereference", &
I);
412 "Undefined behavior: Undef pointer dereference", &
I);
415 "Unusual: All-ones pointer dereference", &
I);
418 "Unusual: Address one pointer dereference", &
I);
420 if (Flags & MemRef::Write) {
424 "Undefined behavior: Write to memory in const addrspace", &
I);
427 Check(!GV->isConstant(),
"Undefined behavior: Write to read-only memory",
431 "Undefined behavior: Write to text section", &
I);
433 if (Flags & MemRef::Read) {
437 "Undefined behavior: Load from block address", &
I);
439 if (Flags & MemRef::Callee) {
441 "Undefined behavior: Call to block address", &
I);
443 if (Flags & MemRef::Branchee) {
446 "Undefined behavior: Branch to non-blockaddress", &
I);
461 Type *ATy = AI->getAllocatedType();
463 BaseSize =
DL->getTypeAllocSize(ATy).getFixedValue();
464 BaseAlign = AI->getAlign();
468 if (GV->hasDefinitiveInitializer()) {
469 Type *GTy = GV->getValueType();
471 BaseSize =
DL->getTypeAllocSize(GTy);
472 BaseAlign = GV->getAlign();
473 if (!BaseAlign && GTy->
isSized())
474 BaseAlign =
DL->getABITypeAlign(GTy);
483 "Undefined behavior: Buffer overflow", &
I);
488 Align =
DL->getABITypeAlign(Ty);
489 if (BaseAlign &&
Align)
491 "Undefined behavior: Memory reference address is misaligned", &
I);
502 I.getOperand(0)->getType(), MemRef::Write);
507 I.getOperand(0)->getType(), MemRef::Write);
512 I.getOperand(0)->getType(), MemRef::Write);
516 Check(!isa<UndefValue>(
I.getOperand(0)) || !isa<UndefValue>(
I.getOperand(1)),
517 "Undefined result: xor(undef, undef)", &
I);
521 Check(!isa<UndefValue>(
I.getOperand(0)) || !isa<UndefValue>(
I.getOperand(1)),
522 "Undefined result: sub(undef, undef)", &
I);
526 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
528 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
529 "Undefined result: Shift count out of range", &
I);
534 dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
false)))
535 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
536 "Undefined result: Shift count out of range", &
I);
541 dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
false)))
542 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
543 "Undefined result: Shift count out of range", &
I);
549 if (isa<UndefValue>(V))
552 VectorType *VecTy = dyn_cast<VectorType>(V->getType());
563 if (
C->isZeroValue())
571 if (isa<UndefValue>(Elem))
584 "Undefined behavior: Division by zero", &
I);
589 "Undefined behavior: Division by zero", &
I);
594 "Undefined behavior: Division by zero", &
I);
599 "Undefined behavior: Division by zero", &
I);
603 if (isa<ConstantInt>(
I.getArraySize()))
605 Check(&
I.getParent()->getParent()->getEntryBlock() ==
I.getParent(),
606 "Pessimization: Static alloca outside of entry block", &
I);
613 MemRef::Read | MemRef::Write);
618 std::nullopt,
nullptr, MemRef::Branchee);
620 Check(
I.getNumDestinations() != 0,
621 "Undefined behavior: indirectbr with no destinations", &
I);
625 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getIndexOperand(),
628 Check(
EC.isScalable() || CI->getValue().ult(
EC.getFixedValue()),
629 "Undefined result: extractelement index out of range", &
I);
634 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getOperand(2),
637 Check(
EC.isScalable() || CI->getValue().ult(
EC.getFixedValue()),
638 "Undefined result: insertelement index out of range", &
I);
644 Check(&
I == &
I.getParent()->front() ||
645 std::prev(
I.getIterator())->mayHaveSideEffects(),
646 "Unusual: unreachable immediately preceded by instruction without "
658Value *Lint::findValue(
Value *V,
bool OffsetOk)
const {
660 return findValueImpl(V, OffsetOk, Visited);
664Value *Lint::findValueImpl(
Value *V,
bool OffsetOk,
667 if (!Visited.
insert(V).second)
676 if (
LoadInst *L = dyn_cast<LoadInst>(V)) {
682 if (!VisitedBlocks.
insert(BB).second)
686 return findValueImpl(U, OffsetOk, Visited);
687 if (BBI != BB->
begin())
694 }
else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
695 if (
Value *W = PN->hasConstantValue())
696 return findValueImpl(W, OffsetOk, Visited);
697 }
else if (
CastInst *CI = dyn_cast<CastInst>(V)) {
698 if (CI->isNoopCast(*
DL))
699 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
704 return findValueImpl(W, OffsetOk, Visited);
705 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
709 CE->getOperand(0)->getType(),
CE->getType(),
711 return findValueImpl(
CE->getOperand(0), OffsetOk, Visited);
716 if (
Instruction *Inst = dyn_cast<Instruction>(V)) {
718 return findValueImpl(W, OffsetOk, Visited);
719 }
else if (
auto *
C = dyn_cast<Constant>(V)) {
722 return findValueImpl(W, OffsetOk, Visited);
729 auto *
Mod =
F.getParent();
730 auto *
DL = &
F.getDataLayout();
735 Lint L(
Mod,
DL, AA, AC, DT, TLI);
737 dbgs() << L.MessagesStr.str();
738 if (AbortOnError && !L.MessagesStr.str().empty())
740 "linter found errors, aborting. (enabled by abort-on-error)",
false);
748 OS <<
"<abort-on-error>";
759 assert(!
F.isDeclaration() &&
"Cannot lint external functions");
779 if (!
F.isDeclaration())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU address space definition.
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This is the interface for LLVM's primary stateless and local alias analysis.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
static unsigned getNumElements(Type *Ty)
This is the interface for a metadata-based scoped no-alias analysis.
This file defines the SmallPtrSet class.
This is the interface for a metadata-based TBAA.
A manager for alias analyses.
void registerFunctionAnalysis()
Register a specific AA result.
A private abstract base class describing the concept of an individual alias analysis implementation.
LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
The possible results of an alias query.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
LLVM_ABI Type * getParamStructRetType() const
If this is an sret argument, return its type.
LLVM_ABI bool hasStructRetAttr() const
Return true if this argument has the sret attribute.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return the attribute object that exists at the arg index.
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the attribute exists for the given argument.
LLVM_ABI AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
bool isValid() const
Return true if the attribute is any kind of attribute.
Analysis pass providing a never-invalidated alias analysis result.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
InstListType::iterator iterator
Instruction iterators...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This is the base class for all instructions that perform data casts.
static LLVM_ABI bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, const DataLayout &DL)
A no-op cast is one that can be effected without changing any bits.
A constant value that is initialized with an expression using other constant values.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Indirect Branch Instruction.
This instruction inserts a single (scalar) element into a VectorType value.
Base class for instruction visitors.
RetTy visitIndirectBrInst(IndirectBrInst &I)
RetTy visitExtractElementInst(ExtractElementInst &I)
RetTy visitCallBase(CallBase &I)
void visitFunction(Function &F)
RetTy visitUnreachableInst(UnreachableInst &I)
RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I)
RetTy visitReturnInst(ReturnInst &I)
RetTy visitStoreInst(StoreInst &I)
RetTy visitInsertElementInst(InsertElementInst &I)
RetTy visitAtomicRMWInst(AtomicRMWInst &I)
RetTy visitAllocaInst(AllocaInst &I)
RetTy visitLoadInst(LoadInst &I)
RetTy visitVAArgInst(VAArgInst &I)
A wrapper class for inspecting calls to intrinsic functions.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
An instruction for reading from memory.
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
This class wraps the llvm.memcpy intrinsic.
Value * getLength() const
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
MaybeAlign getDestAlign() const
This class wraps the llvm.memmove intrinsic.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
MaybeAlign getSourceAlign() const
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it,...
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.
static LLVM_ABI MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
const Value * Ptr
The address of the start of the location.
static LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Return a value (possibly void), from a function.
Analysis pass providing a never-invalidated alias analysis result.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
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...
Analysis pass providing a never-invalidated alias analysis result.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
This function has undefined behavior.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
bool isConstantAddressSpace(unsigned AS)
@ C
The default llvm calling convention, compatible with C.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
LLVM_ABI Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, BatchAAResults *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
void lintModule(const Module &M, bool AbortOnError=false)
Lint a module.
LLVM_ABI cl::opt< unsigned > DefMaxInstsToScan
The default number of maximum instructions to scan in the block, used by FindAvailableLoadedValue().
@ Mod
The access may modify the value stored in memory.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI Value * FindInsertedValue(Value *V, ArrayRef< unsigned > idx_range, std::optional< BasicBlock::iterator > InsertBefore=std::nullopt)
Given an aggregate and an sequence of indices, see if the scalar value indexed is already around as a...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
void lintFunction(const Function &F, bool AbortOnError=false)
lintFunction - Check a function for errors, printing messages on stderr.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool isZero() const
Returns true if value is all zero.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)