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};
 
  271        AttributeList CallAttrs = 
I.getAttributes();
 
  272        for (Attribute::AttrKind Attr : ABIAttributes) {
 
  273          Attribute CallAttr = CallAttrs.getParamAttr(ArgNo, Attr);
 
  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))
 
  301        Value *Obj = findValue(Arg, 
true);
 
  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()) {
 
  386    Value *Obj = findValue(V, 
true);
 
  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      Type *ATy = AI->getAllocatedType();
 
  456        BaseSize = 
DL->getTypeAllocSize(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);
 
  556  if (
C->isZeroValue())
 
 
  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.
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
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.
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.
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).
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.
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.
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.
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 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)
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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 ...
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().
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.
void lintFunction(const Function &F, bool AbortOnError=false)
lintFunction - Check a function for errors, printing messages on stderr.
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)