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;
138 TLI(TLI), MessagesStr(Messages) {}
141 for (
const Value *V : Vs) {
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);
189void Lint::visitCallBase(CallBase &
I) {
193 nullptr, MemRef::Callee);
197 Check(
I.getCallingConv() ==
F->getCallingConv(),
198 "Undefined behavior: Caller and callee calling convention differ",
201 FunctionType *FT =
F->getFunctionType();
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",
232 AttributeList PAL =
I.getAttributes();
234 for (
auto *BI =
I.arg_begin(); BI != AE; ++BI, ++ArgNo) {
237 if (PAL.hasParamAttr(ArgNo, Attribute::ByVal))
244 if (
I.doesNotAccessMemory(ArgNo))
246 if (AI != BI && (*BI)->getType()->isPointerTy() &&
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();
267 Attribute::AttrKind ABIAttributes[] = {
268 Attribute::ZExt, Attribute::SExt, Attribute::InReg,
269 Attribute::ByVal, Attribute::ByRef, Attribute::InAlloca,
270 Attribute::Preallocated, Attribute::StructRet};
272 for (Attribute::AttrKind Attr : ABIAttributes) {
276 Twine(
"Undefined behavior: ABI attribute ") +
277 Attribute::getNameFromAttrKind(Attr) +
278 " not present on both function and call-site",
282 Twine(
"Undefined behavior: ABI attribute ") +
283 Attribute::getNameFromAttrKind(Attr) +
284 " does not have same argument for function and call-site",
293 if (CI->isTailCall()) {
294 const AttributeList &PAL = CI->getAttributes();
296 for (
Value *Arg :
I.args()) {
299 if (PAL.hasParamAttr(ArgNo++, Attribute::ByVal))
303 "Undefined behavior: Call with \"tail\" keyword references "
311 switch (
II->getIntrinsicID()) {
317 case Intrinsic::memcpy:
318 case Intrinsic::memcpy_inline: {
329 if (
const ConstantInt *Len =
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);
380void Lint::visitReturnInst(ReturnInst &
I) {
382 Check(!
F->doesNotReturn(),
383 "Unusual: Return statement in function with noreturn attribute", &
I);
385 if (
Value *V =
I.getReturnValue()) {
393void Lint::visitMemoryReference(Instruction &
I,
const MemoryLocation &Loc,
394 MaybeAlign Align,
Type *Ty,
unsigned Flags) {
401 Value *UnderlyingObject = findValue(Ptr,
true);
403 "Undefined behavior: Null pointer dereference", &
I);
405 "Undefined behavior: Undef pointer dereference", &
I);
408 "Unusual: All-ones pointer dereference", &
I);
411 "Unusual: Address one pointer dereference", &
I);
413 if (Flags & MemRef::Write) {
417 "Undefined behavior: Write to memory in const addrspace", &
I);
420 Check(!GV->isConstant(),
"Undefined behavior: Write to read-only memory",
424 "Undefined behavior: Write to text section", &
I);
426 if (Flags & MemRef::Read) {
430 "Undefined behavior: Load from block address", &
I);
432 if (Flags & MemRef::Callee) {
434 "Undefined behavior: Call to block address", &
I);
436 if (Flags & MemRef::Branchee) {
439 "Undefined behavior: Branch to non-blockaddress", &
I);
451 MaybeAlign BaseAlign;
454 std::optional<TypeSize> ATy = AI->getAllocationSize(*
DL);
455 if (ATy && !ATy->isScalable())
456 BaseSize = ATy->getFixedValue();
457 BaseAlign = AI->getAlign();
461 if (GV->hasDefinitiveInitializer()) {
462 Type *GTy = GV->getValueType();
464 BaseSize =
DL->getTypeAllocSize(GTy);
465 BaseAlign = GV->getAlign();
466 if (!BaseAlign && GTy->
isSized())
467 BaseAlign =
DL->getABITypeAlign(GTy);
476 "Undefined behavior: Buffer overflow", &
I);
480 if (!Align && Ty && Ty->
isSized())
481 Align =
DL->getABITypeAlign(Ty);
482 if (BaseAlign && Align)
484 "Undefined behavior: Memory reference address is misaligned", &
I);
488void Lint::visitLoadInst(LoadInst &
I) {
493void Lint::visitStoreInst(StoreInst &
I) {
495 I.getOperand(0)->getType(), MemRef::Write);
498void Lint::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
500 I.getOperand(0)->getType(), MemRef::Write);
503void Lint::visitAtomicRMWInst(AtomicRMWInst &
I) {
505 I.getOperand(0)->getType(), MemRef::Write);
508void Lint::visitXor(BinaryOperator &
I) {
510 "Undefined result: xor(undef, undef)", &
I);
513void Lint::visitSub(BinaryOperator &
I) {
515 "Undefined result: sub(undef, undef)", &
I);
518void Lint::visitLShr(BinaryOperator &
I) {
522 "Undefined result: Shift count out of range", &
I);
525void Lint::visitAShr(BinaryOperator &
I) {
526 if (ConstantInt *CI =
529 "Undefined result: Shift count out of range", &
I);
532void Lint::visitShl(BinaryOperator &
I) {
533 if (ConstantInt *CI =
536 "Undefined result: Shift count out of range", &
I);
548 return Known.isZero();
556 if (
C->isNullValue())
575void Lint::visitSDiv(BinaryOperator &
I) {
577 "Undefined behavior: Division by zero", &
I);
580void Lint::visitUDiv(BinaryOperator &
I) {
582 "Undefined behavior: Division by zero", &
I);
585void Lint::visitSRem(BinaryOperator &
I) {
587 "Undefined behavior: Division by zero", &
I);
590void Lint::visitURem(BinaryOperator &
I) {
592 "Undefined behavior: Division by zero", &
I);
595void Lint::visitAllocaInst(AllocaInst &
I) {
598 Check(&
I.getParent()->getParent()->getEntryBlock() ==
I.getParent(),
599 "Pessimization: Static alloca outside of entry block", &
I);
604void Lint::visitVAArgInst(VAArgInst &
I) {
606 MemRef::Read | MemRef::Write);
609void Lint::visitIndirectBrInst(IndirectBrInst &
I) {
611 std::nullopt,
nullptr, MemRef::Branchee);
613 Check(
I.getNumDestinations() != 0,
614 "Undefined behavior: indirectbr with no destinations", &
I);
617void Lint::visitExtractElementInst(ExtractElementInst &
I) {
620 ElementCount
EC =
I.getVectorOperandType()->getElementCount();
621 Check(
EC.isScalable() || CI->getValue().ult(
EC.getFixedValue()),
622 "Undefined result: extractelement index out of range", &
I);
626void Lint::visitInsertElementInst(InsertElementInst &
I) {
629 ElementCount
EC =
I.getType()->getElementCount();
630 Check(
EC.isScalable() || CI->getValue().ult(
EC.getFixedValue()),
631 "Undefined result: insertelement index out of range", &
I);
635void Lint::visitUnreachableInst(UnreachableInst &
I) {
637 Check(&
I == &
I.getParent()->front() ||
638 std::prev(
I.getIterator())->mayHaveSideEffects(),
639 "Unusual: unreachable immediately preceded by instruction without "
651Value *Lint::findValue(
Value *V,
bool OffsetOk)
const {
652 SmallPtrSet<Value *, 4> Visited;
653 return findValueImpl(V, OffsetOk, Visited);
657Value *Lint::findValueImpl(
Value *V,
bool OffsetOk,
658 SmallPtrSetImpl<Value *> &Visited)
const {
660 if (!Visited.
insert(V).second)
673 BatchAAResults BatchAA(*AA);
679 return findValueImpl(U, OffsetOk, Visited);
680 if (BBI != BB->
begin())
688 if (
Value *W = PN->hasConstantValue())
689 return findValueImpl(W, OffsetOk, Visited);
691 if (CI->isNoopCast(*
DL))
692 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
697 return findValueImpl(W, OffsetOk, Visited);
702 CE->getOperand(0)->getType(),
CE->getType(),
704 return findValueImpl(
CE->getOperand(0), OffsetOk, Visited);
711 return findValueImpl(W, OffsetOk, Visited);
715 return findValueImpl(W, OffsetOk, Visited);
722 auto *
Mod =
F.getParent();
723 auto *
DL = &
F.getDataLayout();
728 Lint L(
Mod,
DL,
AA, AC, DT, TLI);
730 dbgs() << L.MessagesStr.str();
731 if (AbortOnError && !L.MessagesStr.str().empty())
733 "linter found errors, aborting. (enabled by abort-on-error)",
false);
741 OS <<
"<abort-on-error>";
752 assert(!
F.isDeclaration() &&
"Cannot lint external functions");
758 FAM.registerPass([&] {
772 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.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
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
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.
LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
@ 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
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
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,...
bool isValid() const
Return true if the attribute is any kind of attribute.
Analysis pass providing a never-invalidated alias analysis result.
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...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
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.
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.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI 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).
Value * getLength() const
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
MaybeAlign getDestAlign() const
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.
An instruction for storing to memory.
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.
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 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.
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.
Abstract Attribute helper functions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool isConstantAddressSpace(unsigned AS)
@ BasicBlock
Various leaf nodes.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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 ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
LLVM_ABI 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().
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Mod
The access may modify the value stored in memory.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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....
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI 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 (power of two) or undefined (0) alignment.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)