LLVM 20.0.0git
Lint.cpp
Go to the documentation of this file.
1//===-- Lint.cpp - Check for common errors in LLVM IR ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass statically checks for common and easily-identified constructs
10// which produce undefined or likely unintended behavior in LLVM IR.
11//
12// It is not a guarantee of correctness, in two ways. First, it isn't
13// comprehensive. There are checks which could be done statically which are
14// not yet implemented. Some of these are indicated by TODO comments, but
15// those aren't comprehensive either. Second, many conditions cannot be
16// checked statically. This pass does no dynamic instrumentation, so it
17// can't check for all possible problems.
18//
19// Another limitation is that it assumes all code will be executed. A store
20// through a null pointer in a basic block which is never reached is harmless,
21// but this pass will warn about it anyway. This is the main reason why most
22// of these checks live here instead of in the Verifier pass.
23//
24// Optimization passes may make conditions that this pass checks for more or
25// less obvious. If an optimization pass appears to be introducing a warning,
26// it may be that the optimization pass is merely exposing an existing
27// condition in the code.
28//
29// This code may be run before instcombine. In many cases, instcombine checks
30// for the same kinds of things and turns instructions with undefined behavior
31// into unreachable (or equivalent). Because of this, this pass makes some
32// effort to look through bitcasts and so on.
33//
34//===----------------------------------------------------------------------===//
35
36#include "llvm/Analysis/Lint.h"
37#include "llvm/ADT/APInt.h"
38#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/Twine.h"
46#include "llvm/Analysis/Loads.h"
52#include "llvm/IR/Argument.h"
53#include "llvm/IR/BasicBlock.h"
54#include "llvm/IR/Constant.h"
55#include "llvm/IR/Constants.h"
56#include "llvm/IR/DataLayout.h"
58#include "llvm/IR/Dominators.h"
59#include "llvm/IR/Function.h"
61#include "llvm/IR/InstVisitor.h"
62#include "llvm/IR/InstrTypes.h"
63#include "llvm/IR/Instruction.h"
66#include "llvm/IR/Module.h"
67#include "llvm/IR/PassManager.h"
68#include "llvm/IR/Type.h"
69#include "llvm/IR/Value.h"
74#include <cassert>
75#include <cstdint>
76#include <iterator>
77#include <string>
78
79using namespace llvm;
80
81static const char LintAbortOnErrorArgName[] = "lint-abort-on-error";
82static cl::opt<bool>
84 cl::desc("In the Lint pass, abort on errors."));
85
86namespace {
87namespace MemRef {
88static const unsigned Read = 1;
89static const unsigned Write = 2;
90static const unsigned Callee = 4;
91static const unsigned Branchee = 8;
92} // end namespace MemRef
93
94class Lint : public InstVisitor<Lint> {
95 friend class InstVisitor<Lint>;
96
98
99 void visitCallBase(CallBase &CB);
100 void visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
101 MaybeAlign Alignment, Type *Ty, unsigned Flags);
102
104 void visitLoadInst(LoadInst &I);
108 void visitXor(BinaryOperator &I);
109 void visitSub(BinaryOperator &I);
110 void visitLShr(BinaryOperator &I);
111 void visitAShr(BinaryOperator &I);
112 void visitShl(BinaryOperator &I);
113 void visitSDiv(BinaryOperator &I);
114 void visitUDiv(BinaryOperator &I);
115 void visitSRem(BinaryOperator &I);
116 void visitURem(BinaryOperator &I);
123
124 Value *findValue(Value *V, bool OffsetOk) const;
125 Value *findValueImpl(Value *V, bool OffsetOk,
126 SmallPtrSetImpl<Value *> &Visited) const;
127
128public:
129 Module *Mod;
130 Triple TT;
131 const DataLayout *DL;
132 AliasAnalysis *AA;
133 AssumptionCache *AC;
134 DominatorTree *DT;
136
137 std::string Messages;
138 raw_string_ostream MessagesStr;
139
140 Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA,
142 : Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())), DL(DL), AA(AA),
143 AC(AC), DT(DT), TLI(TLI), MessagesStr(Messages) {}
144
145 void WriteValues(ArrayRef<const Value *> Vs) {
146 for (const Value *V : Vs) {
147 if (!V)
148 continue;
149 if (isa<Instruction>(V)) {
150 MessagesStr << *V << '\n';
151 } else {
152 V->printAsOperand(MessagesStr, true, Mod);
153 MessagesStr << '\n';
154 }
155 }
156 }
157
158 /// A check failed, so printout out the condition and the message.
159 ///
160 /// This provides a nice place to put a breakpoint if you want to see why
161 /// something is not correct.
162 void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; }
163
164 /// A check failed (with values to print).
165 ///
166 /// This calls the Message-only version so that the above is easier to set
167 /// a breakpoint on.
168 template <typename T1, typename... Ts>
169 void CheckFailed(const Twine &Message, const T1 &V1, const Ts &... Vs) {
170 CheckFailed(Message);
171 WriteValues({V1, Vs...});
172 }
173};
174} // end anonymous namespace
175
176// Check - We know that cond should be true, if not print an error message.
177#define Check(C, ...) \
178 do { \
179 if (!(C)) { \
180 CheckFailed(__VA_ARGS__); \
181 return; \
182 } \
183 } while (false)
184
185void Lint::visitFunction(Function &F) {
186 // This isn't undefined behavior, it's just a little unusual, and it's a
187 // fairly common mistake to neglect to name a function.
188 Check(F.hasName() || F.hasLocalLinkage(),
189 "Unusual: Unnamed function with non-local linkage", &F);
190
191 // TODO: Check for irreducible control flow.
192}
193
194void Lint::visitCallBase(CallBase &I) {
195 Value *Callee = I.getCalledOperand();
196
197 visitMemoryReference(I, MemoryLocation::getAfter(Callee), std::nullopt,
198 nullptr, MemRef::Callee);
199
200 if (Function *F = dyn_cast<Function>(findValue(Callee,
201 /*OffsetOk=*/false))) {
202 Check(I.getCallingConv() == F->getCallingConv(),
203 "Undefined behavior: Caller and callee calling convention differ",
204 &I);
205
206 FunctionType *FT = F->getFunctionType();
207 unsigned NumActualArgs = I.arg_size();
208
209 Check(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
210 : FT->getNumParams() == NumActualArgs,
211 "Undefined behavior: Call argument count mismatches callee "
212 "argument count",
213 &I);
214
215 Check(FT->getReturnType() == I.getType(),
216 "Undefined behavior: Call return type mismatches "
217 "callee return type",
218 &I);
219
220 // Check argument types (in case the callee was casted) and attributes.
221 // TODO: Verify that caller and callee attributes are compatible.
222 Function::arg_iterator PI = F->arg_begin(), PE = F->arg_end();
223 auto AI = I.arg_begin(), AE = I.arg_end();
224 for (; AI != AE; ++AI) {
225 Value *Actual = *AI;
226 if (PI != PE) {
227 Argument *Formal = &*PI++;
228 Check(Formal->getType() == Actual->getType(),
229 "Undefined behavior: Call argument type mismatches "
230 "callee parameter type",
231 &I);
232
233 // Check that noalias arguments don't alias other arguments. This is
234 // not fully precise because we don't know the sizes of the dereferenced
235 // memory regions.
236 if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) {
237 AttributeList PAL = I.getAttributes();
238 unsigned ArgNo = 0;
239 for (auto *BI = I.arg_begin(); BI != AE; ++BI, ++ArgNo) {
240 // Skip ByVal arguments since they will be memcpy'd to the callee's
241 // stack so we're not really passing the pointer anyway.
242 if (PAL.hasParamAttr(ArgNo, Attribute::ByVal))
243 continue;
244 // If both arguments are readonly, they have no dependence.
245 if (Formal->onlyReadsMemory() && I.onlyReadsMemory(ArgNo))
246 continue;
247 // Skip readnone arguments since those are guaranteed not to be
248 // dereferenced anyway.
249 if (I.doesNotAccessMemory(ArgNo))
250 continue;
251 if (AI != BI && (*BI)->getType()->isPointerTy() &&
252 !isa<ConstantPointerNull>(*BI)) {
253 AliasResult Result = AA->alias(*AI, *BI);
254 Check(Result != AliasResult::MustAlias &&
256 "Unusual: noalias argument aliases another argument", &I);
257 }
258 }
259 }
260
261 // Check that an sret argument points to valid memory.
262 if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
263 Type *Ty = Formal->getParamStructRetType();
264 MemoryLocation Loc(
265 Actual, LocationSize::precise(DL->getTypeStoreSize(Ty)));
266 visitMemoryReference(I, Loc, DL->getABITypeAlign(Ty), Ty,
267 MemRef::Read | MemRef::Write);
268 }
269
270 // Check that ABI attributes for the function and call-site match.
271 unsigned ArgNo = AI->getOperandNo();
272 Attribute::AttrKind ABIAttributes[] = {
273 Attribute::ZExt, Attribute::SExt, Attribute::InReg,
274 Attribute::ByVal, Attribute::ByRef, Attribute::InAlloca,
275 Attribute::Preallocated, Attribute::StructRet};
276 AttributeList CallAttrs = I.getAttributes();
277 for (Attribute::AttrKind Attr : ABIAttributes) {
278 Attribute CallAttr = CallAttrs.getParamAttr(ArgNo, Attr);
279 Attribute FnAttr = F->getParamAttribute(ArgNo, Attr);
280 Check(CallAttr.isValid() == FnAttr.isValid(),
281 Twine("Undefined behavior: ABI attribute ") +
283 " not present on both function and call-site",
284 &I);
285 if (CallAttr.isValid() && FnAttr.isValid()) {
286 Check(CallAttr == FnAttr,
287 Twine("Undefined behavior: ABI attribute ") +
289 " does not have same argument for function and call-site",
290 &I);
291 }
292 }
293 }
294 }
295 }
296
297 if (const auto *CI = dyn_cast<CallInst>(&I)) {
298 if (CI->isTailCall()) {
299 const AttributeList &PAL = CI->getAttributes();
300 unsigned ArgNo = 0;
301 for (Value *Arg : I.args()) {
302 // Skip ByVal arguments since they will be memcpy'd to the callee's
303 // stack anyway.
304 if (PAL.hasParamAttr(ArgNo++, Attribute::ByVal))
305 continue;
306 Value *Obj = findValue(Arg, /*OffsetOk=*/true);
307 Check(!isa<AllocaInst>(Obj),
308 "Undefined behavior: Call with \"tail\" keyword references "
309 "alloca",
310 &I);
311 }
312 }
313 }
314
315 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I))
316 switch (II->getIntrinsicID()) {
317 default:
318 break;
319
320 // TODO: Check more intrinsics
321
322 case Intrinsic::memcpy:
323 case Intrinsic::memcpy_inline: {
324 MemCpyInst *MCI = cast<MemCpyInst>(&I);
325 visitMemoryReference(I, MemoryLocation::getForDest(MCI),
326 MCI->getDestAlign(), nullptr, MemRef::Write);
327 visitMemoryReference(I, MemoryLocation::getForSource(MCI),
328 MCI->getSourceAlign(), nullptr, MemRef::Read);
329
330 // Check that the memcpy arguments don't overlap. The AliasAnalysis API
331 // isn't expressive enough for what we really want to do. Known partial
332 // overlap is not distinguished from the case where nothing is known.
334 if (const ConstantInt *Len =
335 dyn_cast<ConstantInt>(findValue(MCI->getLength(),
336 /*OffsetOk=*/false)))
337 if (Len->getValue().isIntN(32))
338 Size = LocationSize::precise(Len->getValue().getZExtValue());
339 Check(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) !=
341 "Undefined behavior: memcpy source and destination overlap", &I);
342 break;
343 }
344 case Intrinsic::memmove: {
345 MemMoveInst *MMI = cast<MemMoveInst>(&I);
346 visitMemoryReference(I, MemoryLocation::getForDest(MMI),
347 MMI->getDestAlign(), nullptr, MemRef::Write);
348 visitMemoryReference(I, MemoryLocation::getForSource(MMI),
349 MMI->getSourceAlign(), nullptr, MemRef::Read);
350 break;
351 }
352 case Intrinsic::memset: {
353 MemSetInst *MSI = cast<MemSetInst>(&I);
354 visitMemoryReference(I, MemoryLocation::getForDest(MSI),
355 MSI->getDestAlign(), nullptr, MemRef::Write);
356 break;
357 }
358 case Intrinsic::memset_inline: {
359 MemSetInlineInst *MSII = cast<MemSetInlineInst>(&I);
360 visitMemoryReference(I, MemoryLocation::getForDest(MSII),
361 MSII->getDestAlign(), nullptr, MemRef::Write);
362 break;
363 }
364
365 case Intrinsic::vastart:
366 // vastart in non-varargs function is rejected by the verifier
367 visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI),
368 std::nullopt, nullptr, MemRef::Read | MemRef::Write);
369 break;
370 case Intrinsic::vacopy:
371 visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI),
372 std::nullopt, nullptr, MemRef::Write);
373 visitMemoryReference(I, MemoryLocation::getForArgument(&I, 1, TLI),
374 std::nullopt, nullptr, MemRef::Read);
375 break;
376 case Intrinsic::vaend:
377 visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI),
378 std::nullopt, nullptr, MemRef::Read | MemRef::Write);
379 break;
380
381 case Intrinsic::stackrestore:
382 // Stackrestore doesn't read or write memory, but it sets the
383 // stack pointer, which the compiler may read from or write to
384 // at any time, so check it for both readability and writeability.
385 visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI),
386 std::nullopt, nullptr, MemRef::Read | MemRef::Write);
387 break;
388 case Intrinsic::get_active_lane_mask:
389 if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand(1)))
390 Check(!TripCount->isZero(),
391 "get_active_lane_mask: operand #2 "
392 "must be greater than 0",
393 &I);
394 break;
395 }
396}
397
398void Lint::visitReturnInst(ReturnInst &I) {
399 Function *F = I.getParent()->getParent();
400 Check(!F->doesNotReturn(),
401 "Unusual: Return statement in function with noreturn attribute", &I);
402
403 if (Value *V = I.getReturnValue()) {
404 Value *Obj = findValue(V, /*OffsetOk=*/true);
405 Check(!isa<AllocaInst>(Obj), "Unusual: Returning alloca value", &I);
406 }
407}
408
409// TODO: Check that the reference is in bounds.
410// TODO: Check readnone/readonly function attributes.
411void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
412 MaybeAlign Align, Type *Ty, unsigned Flags) {
413 // If no memory is being referenced, it doesn't matter if the pointer
414 // is valid.
415 if (Loc.Size.isZero())
416 return;
417
418 Value *Ptr = const_cast<Value *>(Loc.Ptr);
419 Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true);
420 Check(!isa<ConstantPointerNull>(UnderlyingObject),
421 "Undefined behavior: Null pointer dereference", &I);
422 Check(!isa<UndefValue>(UnderlyingObject),
423 "Undefined behavior: Undef pointer dereference", &I);
424 Check(!isa<ConstantInt>(UnderlyingObject) ||
425 !cast<ConstantInt>(UnderlyingObject)->isMinusOne(),
426 "Unusual: All-ones pointer dereference", &I);
427 Check(!isa<ConstantInt>(UnderlyingObject) ||
428 !cast<ConstantInt>(UnderlyingObject)->isOne(),
429 "Unusual: Address one pointer dereference", &I);
430
431 if (Flags & MemRef::Write) {
432 if (TT.isAMDGPU())
434 UnderlyingObject->getType()->getPointerAddressSpace()),
435 "Undefined behavior: Write to memory in const addrspace", &I);
436
437 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
438 Check(!GV->isConstant(), "Undefined behavior: Write to read-only memory",
439 &I);
440 Check(!isa<Function>(UnderlyingObject) &&
441 !isa<BlockAddress>(UnderlyingObject),
442 "Undefined behavior: Write to text section", &I);
443 }
444 if (Flags & MemRef::Read) {
445 Check(!isa<Function>(UnderlyingObject), "Unusual: Load from function body",
446 &I);
447 Check(!isa<BlockAddress>(UnderlyingObject),
448 "Undefined behavior: Load from block address", &I);
449 }
450 if (Flags & MemRef::Callee) {
451 Check(!isa<BlockAddress>(UnderlyingObject),
452 "Undefined behavior: Call to block address", &I);
453 }
454 if (Flags & MemRef::Branchee) {
455 Check(!isa<Constant>(UnderlyingObject) ||
456 isa<BlockAddress>(UnderlyingObject),
457 "Undefined behavior: Branch to non-blockaddress", &I);
458 }
459
460 // Check for buffer overflows and misalignment.
461 // Only handles memory references that read/write something simple like an
462 // alloca instruction or a global variable.
463 int64_t Offset = 0;
465 // OK, so the access is to a constant offset from Ptr. Check that Ptr is
466 // something we can handle and if so extract the size of this base object
467 // along with its alignment.
469 MaybeAlign BaseAlign;
470
471 if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
472 Type *ATy = AI->getAllocatedType();
473 if (!AI->isArrayAllocation() && ATy->isSized() && !ATy->isScalableTy())
474 BaseSize = DL->getTypeAllocSize(ATy).getFixedValue();
475 BaseAlign = AI->getAlign();
476 } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
477 // If the global may be defined differently in another compilation unit
478 // then don't warn about funky memory accesses.
479 if (GV->hasDefinitiveInitializer()) {
480 Type *GTy = GV->getValueType();
481 if (GTy->isSized())
482 BaseSize = DL->getTypeAllocSize(GTy);
483 BaseAlign = GV->getAlign();
484 if (!BaseAlign && GTy->isSized())
485 BaseAlign = DL->getABITypeAlign(GTy);
486 }
487 }
488
489 // Accesses from before the start or after the end of the object are not
490 // defined.
491 Check(!Loc.Size.hasValue() || Loc.Size.isScalable() ||
492 BaseSize == MemoryLocation::UnknownSize ||
493 (Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize),
494 "Undefined behavior: Buffer overflow", &I);
495
496 // Accesses that say that the memory is more aligned than it is are not
497 // defined.
498 if (!Align && Ty && Ty->isSized())
499 Align = DL->getABITypeAlign(Ty);
500 if (BaseAlign && Align)
501 Check(*Align <= commonAlignment(*BaseAlign, Offset),
502 "Undefined behavior: Memory reference address is misaligned", &I);
503 }
504}
505
506void Lint::visitLoadInst(LoadInst &I) {
507 visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(), I.getType(),
508 MemRef::Read);
509}
510
511void Lint::visitStoreInst(StoreInst &I) {
512 visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
513 I.getOperand(0)->getType(), MemRef::Write);
514}
515
516void Lint::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
517 visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
518 I.getOperand(0)->getType(), MemRef::Write);
519}
520
521void Lint::visitAtomicRMWInst(AtomicRMWInst &I) {
522 visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
523 I.getOperand(0)->getType(), MemRef::Write);
524}
525
526void Lint::visitXor(BinaryOperator &I) {
527 Check(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
528 "Undefined result: xor(undef, undef)", &I);
529}
530
531void Lint::visitSub(BinaryOperator &I) {
532 Check(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
533 "Undefined result: sub(undef, undef)", &I);
534}
535
536void Lint::visitLShr(BinaryOperator &I) {
537 if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(1),
538 /*OffsetOk=*/false)))
539 Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
540 "Undefined result: Shift count out of range", &I);
541}
542
543void Lint::visitAShr(BinaryOperator &I) {
544 if (ConstantInt *CI =
545 dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false)))
546 Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
547 "Undefined result: Shift count out of range", &I);
548}
549
550void Lint::visitShl(BinaryOperator &I) {
551 if (ConstantInt *CI =
552 dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false)))
553 Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
554 "Undefined result: Shift count out of range", &I);
555}
556
557static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
558 AssumptionCache *AC) {
559 // Assume undef could be zero.
560 if (isa<UndefValue>(V))
561 return true;
562
563 VectorType *VecTy = dyn_cast<VectorType>(V->getType());
564 if (!VecTy) {
565 KnownBits Known =
566 computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT);
567 return Known.isZero();
568 }
569
570 // Per-component check doesn't work with zeroinitializer
571 Constant *C = dyn_cast<Constant>(V);
572 if (!C)
573 return false;
574
575 if (C->isZeroValue())
576 return true;
577
578 // For a vector, KnownZero will only be true if all values are zero, so check
579 // this per component
580 for (unsigned I = 0, N = cast<FixedVectorType>(VecTy)->getNumElements();
581 I != N; ++I) {
582 Constant *Elem = C->getAggregateElement(I);
583 if (isa<UndefValue>(Elem))
584 return true;
585
586 KnownBits Known = computeKnownBits(Elem, DL);
587 if (Known.isZero())
588 return true;
589 }
590
591 return false;
592}
593
594void Lint::visitSDiv(BinaryOperator &I) {
595 Check(!isZero(I.getOperand(1), I.getDataLayout(), DT, AC),
596 "Undefined behavior: Division by zero", &I);
597}
598
599void Lint::visitUDiv(BinaryOperator &I) {
600 Check(!isZero(I.getOperand(1), I.getDataLayout(), DT, AC),
601 "Undefined behavior: Division by zero", &I);
602}
603
604void Lint::visitSRem(BinaryOperator &I) {
605 Check(!isZero(I.getOperand(1), I.getDataLayout(), DT, AC),
606 "Undefined behavior: Division by zero", &I);
607}
608
609void Lint::visitURem(BinaryOperator &I) {
610 Check(!isZero(I.getOperand(1), I.getDataLayout(), DT, AC),
611 "Undefined behavior: Division by zero", &I);
612}
613
614void Lint::visitAllocaInst(AllocaInst &I) {
615 if (isa<ConstantInt>(I.getArraySize()))
616 // This isn't undefined behavior, it's just an obvious pessimization.
617 Check(&I.getParent()->getParent()->getEntryBlock() == I.getParent(),
618 "Pessimization: Static alloca outside of entry block", &I);
619
620 // TODO: Check for an unusual size (MSB set?)
621}
622
623void Lint::visitVAArgInst(VAArgInst &I) {
624 visitMemoryReference(I, MemoryLocation::get(&I), std::nullopt, nullptr,
625 MemRef::Read | MemRef::Write);
626}
627
628void Lint::visitIndirectBrInst(IndirectBrInst &I) {
629 visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()),
630 std::nullopt, nullptr, MemRef::Branchee);
631
632 Check(I.getNumDestinations() != 0,
633 "Undefined behavior: indirectbr with no destinations", &I);
634}
635
636void Lint::visitExtractElementInst(ExtractElementInst &I) {
637 if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getIndexOperand(),
638 /*OffsetOk=*/false))) {
639 ElementCount EC = I.getVectorOperandType()->getElementCount();
640 Check(EC.isScalable() || CI->getValue().ult(EC.getFixedValue()),
641 "Undefined result: extractelement index out of range", &I);
642 }
643}
644
645void Lint::visitInsertElementInst(InsertElementInst &I) {
646 if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(2),
647 /*OffsetOk=*/false))) {
648 ElementCount EC = I.getType()->getElementCount();
649 Check(EC.isScalable() || CI->getValue().ult(EC.getFixedValue()),
650 "Undefined result: insertelement index out of range", &I);
651 }
652}
653
654void Lint::visitUnreachableInst(UnreachableInst &I) {
655 // This isn't undefined behavior, it's merely suspicious.
656 Check(&I == &I.getParent()->front() ||
657 std::prev(I.getIterator())->mayHaveSideEffects(),
658 "Unusual: unreachable immediately preceded by instruction without "
659 "side effects",
660 &I);
661}
662
663/// findValue - Look through bitcasts and simple memory reference patterns
664/// to identify an equivalent, but more informative, value. If OffsetOk
665/// is true, look through getelementptrs with non-zero offsets too.
666///
667/// Most analysis passes don't require this logic, because instcombine
668/// will simplify most of these kinds of things away. But it's a goal of
669/// this Lint pass to be useful even on non-optimized IR.
670Value *Lint::findValue(Value *V, bool OffsetOk) const {
672 return findValueImpl(V, OffsetOk, Visited);
673}
674
675/// findValueImpl - Implementation helper for findValue.
676Value *Lint::findValueImpl(Value *V, bool OffsetOk,
677 SmallPtrSetImpl<Value *> &Visited) const {
678 // Detect self-referential values.
679 if (!Visited.insert(V).second)
680 return PoisonValue::get(V->getType());
681
682 // TODO: Look through sext or zext cast, when the result is known to
683 // be interpreted as signed or unsigned, respectively.
684 // TODO: Look through eliminable cast pairs.
685 // TODO: Look through calls with unique return values.
686 // TODO: Look through vector insert/extract/shuffle.
687 V = OffsetOk ? getUnderlyingObject(V) : V->stripPointerCasts();
688 if (LoadInst *L = dyn_cast<LoadInst>(V)) {
689 BasicBlock::iterator BBI = L->getIterator();
690 BasicBlock *BB = L->getParent();
691 SmallPtrSet<BasicBlock *, 4> VisitedBlocks;
692 BatchAAResults BatchAA(*AA);
693 for (;;) {
694 if (!VisitedBlocks.insert(BB).second)
695 break;
696 if (Value *U =
697 FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, &BatchAA))
698 return findValueImpl(U, OffsetOk, Visited);
699 if (BBI != BB->begin())
700 break;
701 BB = BB->getUniquePredecessor();
702 if (!BB)
703 break;
704 BBI = BB->end();
705 }
706 } else if (PHINode *PN = dyn_cast<PHINode>(V)) {
707 if (Value *W = PN->hasConstantValue())
708 return findValueImpl(W, OffsetOk, Visited);
709 } else if (CastInst *CI = dyn_cast<CastInst>(V)) {
710 if (CI->isNoopCast(*DL))
711 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
712 } else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
713 if (Value *W =
714 FindInsertedValue(Ex->getAggregateOperand(), Ex->getIndices()))
715 if (W != V)
716 return findValueImpl(W, OffsetOk, Visited);
717 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
718 // Same as above, but for ConstantExpr instead of Instruction.
719 if (Instruction::isCast(CE->getOpcode())) {
721 CE->getOperand(0)->getType(), CE->getType(),
722 *DL))
723 return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
724 }
725 }
726
727 // As a last resort, try SimplifyInstruction or constant folding.
728 if (Instruction *Inst = dyn_cast<Instruction>(V)) {
729 if (Value *W = simplifyInstruction(Inst, {*DL, TLI, DT, AC}))
730 return findValueImpl(W, OffsetOk, Visited);
731 } else if (auto *C = dyn_cast<Constant>(V)) {
732 Value *W = ConstantFoldConstant(C, *DL, TLI);
733 if (W != V)
734 return findValueImpl(W, OffsetOk, Visited);
735 }
736
737 return V;
738}
739
741 auto *Mod = F.getParent();
742 auto *DL = &F.getDataLayout();
743 auto *AA = &AM.getResult<AAManager>(F);
744 auto *AC = &AM.getResult<AssumptionAnalysis>(F);
745 auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
746 auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
747 Lint L(Mod, DL, AA, AC, DT, TLI);
748 L.visit(F);
749 dbgs() << L.MessagesStr.str();
750 if (LintAbortOnError && !L.MessagesStr.str().empty())
751 report_fatal_error(Twine("Linter found errors, aborting. (enabled by --") +
753 false);
754 return PreservedAnalyses::all();
755}
756
757//===----------------------------------------------------------------------===//
758// Implement the public interfaces to this file...
759//===----------------------------------------------------------------------===//
760
761/// lintFunction - Check a function for errors, printing messages on stderr.
762///
764 Function &F = const_cast<Function &>(f);
765 assert(!F.isDeclaration() && "Cannot lint external functions");
766
768 FAM.registerPass([&] { return TargetLibraryAnalysis(); });
769 FAM.registerPass([&] { return DominatorTreeAnalysis(); });
770 FAM.registerPass([&] { return AssumptionAnalysis(); });
771 FAM.registerPass([&] {
772 AAManager AA;
776 return AA;
777 });
778 LintPass().run(F, FAM);
779}
780
781/// lintModule - Check a module for errors, printing messages on stderr.
782///
783void llvm::lintModule(const Module &M) {
784 for (const Function &F : M) {
785 if (!F.isDeclaration())
787 }
788}
AMDGPU address space definition.
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
@ FnAttr
Definition: Attributes.cpp:750
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...
uint64_t Size
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define Check(C,...)
Definition: Lint.cpp:177
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition: Lint.cpp:557
static const char LintAbortOnErrorArgName[]
Definition: Lint.cpp:81
static cl::opt< bool > LintAbortOnError(LintAbortOnErrorArgName, cl::init(false), cl::desc("In the Lint pass, abort on errors."))
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file provides utility analysis objects describing memory locations.
#define T1
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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.
Definition: AliasAnalysis.h:77
@ 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
Definition: Instructions.h:63
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:471
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition: Function.cpp:283
bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition: Function.cpp:319
Type * getParamStructRetType() const
If this is an sret argument, return its type.
Definition: Function.cpp:240
bool hasStructRetAttr() const
Return true if this argument has the sret attribute.
Definition: Function.cpp:298
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
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,...
Definition: Instructions.h:501
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:704
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return the attribute object that exists at the arg index.
Definition: Attributes.h:882
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the attribute exists for the given argument.
Definition: Attributes.h:833
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
Definition: Attributes.cpp:314
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:86
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:208
Analysis pass providing a never-invalidated alias analysis result.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
iterator end()
Definition: BasicBlock.h:461
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:448
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
Definition: BasicBlock.cpp:467
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:177
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...
Definition: InstrTypes.h:1112
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:444
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 constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1108
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
This is an important base class in LLVM.
Definition: Constant.h:42
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
Indirect Branch Instruction.
This instruction inserts a single (scalar) element into a VectorType value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
RetTy visitIndirectBrInst(IndirectBrInst &I)
Definition: InstVisitor.h:238
RetTy visitExtractElementInst(ExtractElementInst &I)
Definition: InstVisitor.h:191
RetTy visitCallBase(CallBase &I)
Definition: InstVisitor.h:270
void visitFunction(Function &F)
Definition: InstVisitor.h:142
RetTy visitUnreachableInst(UnreachableInst &I)
Definition: InstVisitor.h:244
RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I)
Definition: InstVisitor.h:171
RetTy visitReturnInst(ReturnInst &I)
Definition: InstVisitor.h:229
RetTy visitStoreInst(StoreInst &I)
Definition: InstVisitor.h:170
RetTy visitInsertElementInst(InsertElementInst &I)
Definition: InstVisitor.h:192
RetTy visitAtomicRMWInst(AtomicRMWInst &I)
Definition: InstVisitor.h:172
RetTy visitAllocaInst(AllocaInst &I)
Definition: InstVisitor.h:168
RetTy visitLoadInst(LoadInst &I)
Definition: InstVisitor.h:169
RetTy visitVAArgInst(VAArgInst &I)
Definition: InstVisitor.h:190
bool isCast() const
Definition: Instruction.h:283
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: Lint.cpp:740
An instruction for reading from memory.
Definition: Instructions.h:176
bool hasValue() const
static LocationSize precise(uint64_t Value)
bool isScalable() const
TypeSize getValue() const
bool isZero() 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.inline 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 MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static 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 MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static 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.
Definition: Module.h:65
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1878
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
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...
Definition: SmallPtrSet.h:363
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
An instruction for storing to memory.
Definition: Instructions.h:292
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.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
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.
Definition: Type.h:45
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:264
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:310
bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
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.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
Definition: Lint.cpp:87
bool isConstantAddressSpace(unsigned AS)
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ Read
Definition: CodeGenData.h:107
@ Write
Definition: CodeGenData.h:108
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.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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 ...
Definition: Loads.cpp:491
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
void lintModule(const Module &M)
Lint a module.
Definition: Lint.cpp:783
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.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition: Alignment.h:212
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...
void lintFunction(const Function &F)
lintFunction - Check a function for errors, printing messages on stderr.
Definition: Lint.cpp:763
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
bool isZero() const
Returns true if value is all zero.
Definition: KnownBits.h:79
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117