Go to the documentation of this file.
82 static const unsigned Read = 1;
83 static const unsigned Write = 2;
84 static const unsigned Callee = 4;
85 static const unsigned Branchee = 8;
118 Value *findValue(
Value *V,
bool OffsetOk)
const;
130 std::string Messages;
136 MessagesStr(Messages) {}
139 for (
const Value *V : Vs) {
142 if (isa<Instruction>(V)) {
143 MessagesStr << *V <<
'\n';
145 V->printAsOperand(MessagesStr,
true,
Mod);
155 void CheckFailed(
const Twine &Message) { MessagesStr << Message <<
'\n'; }
161 template <
typename T1,
typename... Ts>
162 void CheckFailed(
const Twine &Message,
const T1 &V1,
const Ts &... Vs) {
163 CheckFailed(Message);
164 WriteValues({V1, Vs...});
170 #define Check(C, ...) \
173 CheckFailed(__VA_ARGS__); \
181 Check(
F.hasName() ||
F.hasLocalLinkage(),
182 "Unusual: Unnamed function with non-local linkage", &
F);
195 Check(
I.getCallingConv() ==
F->getCallingConv(),
196 "Undefined behavior: Caller and callee calling convention differ",
200 unsigned NumActualArgs =
I.arg_size();
204 "Undefined behavior: Call argument count mismatches callee "
209 "Undefined behavior: Call return type mismatches "
210 "callee return type",
216 auto AI =
I.arg_begin(), AE =
I.arg_end();
217 for (; AI != AE; ++AI) {
222 "Undefined behavior: Call argument type mismatches "
223 "callee parameter type",
232 for (
auto BI =
I.arg_begin(); BI != AE; ++BI, ++ArgNo) {
240 if (AI != BI && (*BI)->getType()->isPointerTy()) {
244 "Unusual: noalias argument aliases another argument", &
I);
254 visitMemoryReference(
I, Loc,
DL->getABITypeAlign(Ty), Ty,
255 MemRef::Read | MemRef::Write);
261 if (
const auto *CI = dyn_cast<CallInst>(&
I)) {
262 if (CI->isTailCall()) {
271 Check(!isa<AllocaInst>(Obj),
272 "Undefined behavior: Call with \"tail\" keyword references "
280 switch (II->getIntrinsicID()) {
298 dyn_cast<ConstantInt>(findValue(MCI->
getLength(),
300 if (Len->getValue().isIntN(32))
304 "Undefined behavior: memcpy source and destination overlap", &
I);
307 case Intrinsic::memcpy_inline: {
321 "Undefined behavior: memcpy source and destination overlap", &
I);
324 case Intrinsic::memmove: {
332 case Intrinsic::memset: {
338 case Intrinsic::memset_inline: {
345 case Intrinsic::vastart:
346 Check(
I.getParent()->getParent()->isVarArg(),
347 "Undefined behavior: va_start called in a non-varargs function",
351 nullptr, MemRef::Read | MemRef::Write);
353 case Intrinsic::vacopy:
355 nullptr, MemRef::Write);
357 nullptr, MemRef::Read);
359 case Intrinsic::vaend:
361 nullptr, MemRef::Read | MemRef::Write);
364 case Intrinsic::stackrestore:
369 nullptr, MemRef::Read | MemRef::Write);
371 case Intrinsic::get_active_lane_mask:
372 if (
auto *TripCount = dyn_cast<ConstantInt>(
I.getArgOperand(1)))
373 Check(!TripCount->isZero(),
374 "get_active_lane_mask: operand #2 "
375 "must be greater than 0",
383 Check(!
F->doesNotReturn(),
384 "Unusual: Return statement in function with noreturn attribute", &
I);
386 if (
Value *V =
I.getReturnValue()) {
387 Value *Obj = findValue(V,
true);
388 Check(!isa<AllocaInst>(Obj),
"Unusual: Returning alloca value", &
I);
404 "Undefined behavior: Null pointer dereference", &
I);
406 "Undefined behavior: Undef pointer dereference", &
I);
409 "Unusual: All-ones pointer dereference", &
I);
412 "Unusual: Address one pointer dereference", &
I);
414 if (Flags & MemRef::Write) {
416 Check(!GV->isConstant(),
"Undefined behavior: Write to read-only memory",
420 "Undefined behavior: Write to text section", &
I);
422 if (Flags & MemRef::Read) {
426 "Undefined behavior: Load from block address", &
I);
428 if (Flags & MemRef::Callee) {
430 "Undefined behavior: Call to block address", &
I);
432 if (Flags & MemRef::Branchee) {
435 "Undefined behavior: Branch to non-blockaddress", &
I);
450 Type *ATy = AI->getAllocatedType();
451 if (!AI->isArrayAllocation() && ATy->
isSized())
452 BaseSize =
DL->getTypeAllocSize(ATy);
453 BaseAlign = AI->getAlign();
457 if (GV->hasDefinitiveInitializer()) {
458 Type *GTy = GV->getValueType();
460 BaseSize =
DL->getTypeAllocSize(GTy);
461 BaseAlign = GV->getAlign();
462 if (!BaseAlign && GTy->
isSized())
463 BaseAlign =
DL->getABITypeAlign(GTy);
471 "Undefined behavior: Buffer overflow", &
I);
476 Align =
DL->getABITypeAlign(Ty);
477 if (BaseAlign &&
Align)
479 "Undefined behavior: Memory reference address is misaligned", &
I);
490 I.getOperand(0)->getType(), MemRef::Write);
494 Check(!isa<UndefValue>(
I.getOperand(0)) || !isa<UndefValue>(
I.getOperand(1)),
495 "Undefined result: xor(undef, undef)", &
I);
499 Check(!isa<UndefValue>(
I.getOperand(0)) || !isa<UndefValue>(
I.getOperand(1)),
500 "Undefined result: sub(undef, undef)", &
I);
504 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
506 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
507 "Undefined result: Shift count out of range", &
I);
512 dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
false)))
513 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
514 "Undefined result: Shift count out of range", &
I);
519 dyn_cast<ConstantInt>(findValue(
I.getOperand(1),
false)))
520 Check(CI->getValue().ult(cast<IntegerType>(
I.getType())->getBitWidth()),
521 "Undefined result: Shift count out of range", &
I);
527 if (isa<UndefValue>(V))
542 if (
C->isZeroValue())
547 for (
unsigned I = 0,
N = cast<FixedVectorType>(VecTy)->getNumElements();
550 if (isa<UndefValue>(Elem))
562 Check(!
isZero(
I.getOperand(1),
I.getModule()->getDataLayout(), DT, AC),
563 "Undefined behavior: Division by zero", &
I);
567 Check(!
isZero(
I.getOperand(1),
I.getModule()->getDataLayout(), DT, AC),
568 "Undefined behavior: Division by zero", &
I);
572 Check(!
isZero(
I.getOperand(1),
I.getModule()->getDataLayout(), DT, AC),
573 "Undefined behavior: Division by zero", &
I);
577 Check(!
isZero(
I.getOperand(1),
I.getModule()->getDataLayout(), DT, AC),
578 "Undefined behavior: Division by zero", &
I);
582 if (isa<ConstantInt>(
I.getArraySize()))
584 Check(&
I.getParent()->getParent()->getEntryBlock() ==
I.getParent(),
585 "Pessimization: Static alloca outside of entry block", &
I);
592 MemRef::Read | MemRef::Write);
597 nullptr, MemRef::Branchee);
599 Check(
I.getNumDestinations() != 0,
600 "Undefined behavior: indirectbr with no destinations", &
I);
604 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getIndexOperand(),
608 cast<FixedVectorType>(
I.getVectorOperandType())->getNumElements()),
609 "Undefined result: extractelement index out of range", &
I);
613 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
I.getOperand(2),
615 Check(CI->getValue().ult(
616 cast<FixedVectorType>(
I.getType())->getNumElements()),
617 "Undefined result: insertelement index out of range", &
I);
622 Check(&
I == &
I.getParent()->front() ||
623 std::prev(
I.getIterator())->mayHaveSideEffects(),
624 "Unusual: unreachable immediately preceded by instruction without "
636 Value *Lint::findValue(
Value *V,
bool OffsetOk)
const {
638 return findValueImpl(V, OffsetOk, Visited);
642 Value *Lint::findValueImpl(
Value *V,
bool OffsetOk,
645 if (!Visited.
insert(V).second)
654 if (
LoadInst *L = dyn_cast<LoadInst>(V)) {
659 if (!VisitedBlocks.
insert(
BB).second)
663 return findValueImpl(U, OffsetOk, Visited);
664 if (BBI !=
BB->begin())
666 BB =
BB->getUniquePredecessor();
671 }
else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
672 if (
Value *
W = PN->hasConstantValue())
673 return findValueImpl(
W, OffsetOk, Visited);
674 }
else if (
CastInst *CI = dyn_cast<CastInst>(V)) {
675 if (CI->isNoopCast(*
DL))
676 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
681 return findValueImpl(
W, OffsetOk, Visited);
682 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
686 CE->getOperand(0)->getType(),
CE->getType(),
688 return findValueImpl(
CE->getOperand(0), OffsetOk, Visited);
689 }
else if (
CE->getOpcode() == Instruction::ExtractValue) {
693 return findValueImpl(
W, OffsetOk, Visited);
698 if (
Instruction *Inst = dyn_cast<Instruction>(V)) {
700 return findValueImpl(
W, OffsetOk, Visited);
701 }
else if (
auto *
C = dyn_cast<Constant>(V)) {
704 return findValueImpl(
W, OffsetOk, Visited);
711 auto *
Mod =
F.getParent();
712 auto *
DL = &
F.getParent()->getDataLayout();
717 Lint L(
Mod,
DL,
AA, AC, DT, TLI);
719 dbgs() << L.MessagesStr.str();
755 auto *
Mod =
F.getParent();
756 auto *
DL = &
F.getParent()->getDataLayout();
757 auto *
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
758 auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F);
759 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
760 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
761 Lint L(
Mod,
DL,
AA, AC, DT, TLI);
763 dbgs() << L.MessagesStr.str();
777 assert(!
F.isDeclaration() &&
"Cannot lint external functions");
780 auto *V =
new LintLegacyPass();
789 auto *V =
new LintLegacyPass();
A set of analyses that are preserved following a run of a transformation pass.
This class represents an incoming formal argument to a Function.
A manager for alias analyses.
bool hasStructRetAttr() const
Return true if this argument has the sret attribute.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
ConstantInt * getLength() const
@ PartialAlias
The two locations alias, but only due to a partial overlap.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Return a value (possibly void), from a function.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
static 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 parsed version of the target data layout string in and methods for querying it.
constexpr static LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
InstListType::iterator iterator
Instruction iterators...
bool isPointerTy() const
True if this is an instance of PointerType.
MaybeAlign getDestAlign() const
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const Value * Ptr
The address of the start of the location.
This class wraps the llvm.memmove intrinsic.
A raw_ostream that writes to an std::string.
const APInt & getValue() const
Return the constant as an APInt value reference.
FunctionPass * createLintLegacyPassPass()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void lintModule(const Module &M)
Lint a module.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isZero() const
Returns true if value is all zero.
The possible results of an alias query.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
void initializeLintLegacyPassPass(PassRegistry &)
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This is the shared class of boolean and integer constants.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Itanium Name Demangler i e convert the string _Z1fv into f()". You can also use the CRTP base ManglingParser to perform some simple analysis on the mangled name
(vector float) vec_cmpeq(*A, *B) C
Represent the analysis usage information of a pass.
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
uint64_t getValue() const
This class wraps the llvm.memcpy.inline intrinsic.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
This instruction inserts a single (scalar) element into a VectorType value.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Legacy analysis pass which computes a DominatorTree.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
This class implements an extremely fast bulk output stream that can only output to a stream.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
This class wraps the llvm.memset.inline intrinsic.
static LocationSize precise(uint64_t Value)
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
Statically lint checks LLVM IR
This struct is a compact representation of a valid (non-zero power of two) alignment.
MaybeAlign getSourceAlign() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Type * getParamStructRetType() const
If this is an sret argument, return its type.
Base class of all SIMD vector types.
An instruction for storing to memory.
This is an important base class in LLVM.
A function analysis which provides an AssumptionCache.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE=nullptr)
See if we can compute a simplified version of this instruction.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
@ CE
Windows NT (Windows on ARM)
A Module instance is used to store all the information related to an LLVM module.
void add(Pass *P) override
Add a pass to the queue of passes to run.
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
An immutable pass that tracks lazily created AssumptionCache objects.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Type * getType() const
All values are typed, get the type of this value.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
@ MustAlias
The two locations precisely alias each other.
Base class for instruction visitors.
This is the base class for all instructions that perform data casts.
void lintFunction(const Function &F)
lintFunction - Check a function for errors, printing messages on stderr.
An instruction for reading from memory.
amdgpu Simplify well known AMD library false FunctionCallee Callee
static bool runOnFunction(Function &F, bool PostInlining)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Value * FindInsertedValue(Value *V, ArrayRef< unsigned > idx_range, Instruction *InsertBefore=nullptr)
Given an aggregate and an sequence of indices, see if the scalar value indexed is already around as a...
Align commonAlignment(Align A, Align B)
Returns the alignment that satisfies both alignments.
A constant value that is initialized with an expression using other constant values.
bool run(Function &F)
run - Execute all of the passes scheduled for execution.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Value * getLength() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PassManager manages ModulePassManagers.
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AAResults *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 ...
Provides information about what library functions are available for the current target.
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.
void add(Pass *P) override
Add a pass to the queue of passes to run.
Indirect Branch Instruction.
A wrapper class for inspecting calls to intrinsic functions.
Analysis pass which computes a DominatorTree.
This class wraps the llvm.memcpy intrinsic.
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...
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
FunctionPassManager manages FunctionPasses.
bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
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
This function has undefined behavior.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
AnalysisUsage & addRequired()
an instruction to allocate memory on the stack
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the attribute exists for the given argument.
bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
INITIALIZE_PASS_BEGIN(LintLegacyPass, "lint", "Statically lint-checks LLVM IR", false, true) INITIALIZE_PASS_END(LintLegacyPass
Type * getReturnType() const
LLVM Value Representation.
Analysis pass providing the TargetLibraryInfo.
Representation for a specific memory location.
cl::opt< unsigned > DefMaxInstsToScan
The default number of maximum instructions to scan in the block, used by FindAvailableLoadedValue().
Class to represent function types.
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it,...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)