LLVM: lib/Analysis/Lint.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

74#include

75#include

76#include

77#include

78

79using namespace llvm;

80

84 cl::desc("In the Lint pass, abort on errors."));

85

86namespace {

88static const unsigned Read = 1;

89static const unsigned Write = 2;

90static const unsigned Callee = 4;

91static const unsigned Branchee = 8;

92}

93

96

98

102

123

124 Value *findValue(Value *V, bool OffsetOk) const;

125 Value *findValueImpl(Value *V, bool OffsetOk,

127

128public:

136

137 std::string Messages;

139

142 : Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())), DL(DL), AA(AA),

143 AC(AC), DT(DT), TLI(TLI), MessagesStr(Messages) {}

144

146 for (const Value *V : Vs) {

147 if (!V)

148 continue;

149 if (isa(V)) {

150 MessagesStr << *V << '\n';

151 } else {

152 V->printAsOperand(MessagesStr, true, Mod);

153 MessagesStr << '\n';

154 }

155 }

156 }

157

158

159

160

161

162 void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; }

163

164

165

166

167

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}

175

176

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

187

188 Check(F.hasName() || F.hasLocalLinkage(),

189 "Unusual: Unnamed function with non-local linkage", &F);

190

191

192}

193

194void Lint::visitCallBase(CallBase &I) {

196

198 nullptr, MemRef::Callee);

199

200 if (Function *F = dyn_cast(findValue(Callee,

201 false))) {

202 Check(I.getCallingConv() == F->getCallingConv(),

203 "Undefined behavior: Caller and callee calling convention differ",

204 &I);

205

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

221

223 auto AI = I.arg_begin(), AE = I.arg_end();

224 for (; AI != AE; ++AI) {

225 Value *Actual = *AI;

226 if (PI != PE) {

229 "Undefined behavior: Call argument type mismatches "

230 "callee parameter type",

231 &I);

232

233

234

235

238 unsigned ArgNo = 0;

239 for (auto *BI = I.arg_begin(); BI != AE; ++BI, ++ArgNo) {

240

241

242 if (PAL.hasParamAttr(ArgNo, Attribute::ByVal))

243 continue;

244

246 continue;

247

248

249 if (I.doesNotAccessMemory(ArgNo))

250 continue;

251 if (AI != BI && (*BI)->getType()->isPointerTy() &&

252 !isa(*BI)) {

256 "Unusual: noalias argument aliases another argument", &I);

257 }

258 }

259 }

260

261

266 visitMemoryReference(I, Loc, DL->getABITypeAlign(Ty), Ty,

267 MemRef::Read | MemRef::Write);

268 }

269

270

271 unsigned ArgNo = AI->getOperandNo();

273 Attribute::ZExt, Attribute::SExt, Attribute::InReg,

274 Attribute::ByVal, Attribute::ByRef, Attribute::InAlloca,

275 Attribute::Preallocated, Attribute::StructRet};

281 Twine("Undefined behavior: ABI attribute ") +

283 " not present on both function and call-site",

284 &I);

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(&I)) {

298 if (CI->isTailCall()) {

300 unsigned ArgNo = 0;

301 for (Value *Arg : I.args()) {

302

303

304 if (PAL.hasParamAttr(ArgNo++, Attribute::ByVal))

305 continue;

306 Value *Obj = findValue(Arg, true);

307 Check(!isa(Obj),

308 "Undefined behavior: Call with \"tail\" keyword references "

309 "alloca",

310 &I);

311 }

312 }

313 }

314

316 switch (II->getIntrinsicID()) {

317 default:

318 break;

319

320

321

322 case Intrinsic::memcpy:

323 case Intrinsic::memcpy_inline: {

326 MCI->getDestAlign(), nullptr, MemRef::Write);

329

330

331

332

335 dyn_cast(findValue(MCI->getLength(),

336 false)))

337 if (Len->getValue().isIntN(32))

341 "Undefined behavior: memcpy source and destination overlap", &I);

342 break;

343 }

344 case Intrinsic::memmove: {

347 MMI->getDestAlign(), nullptr, MemRef::Write);

350 break;

351 }

352 case Intrinsic::memset: {

355 MSI->getDestAlign(), nullptr, MemRef::Write);

356 break;

357 }

358 case Intrinsic::memset_inline: {

361 MSII->getDestAlign(), nullptr, MemRef::Write);

362 break;

363 }

364

365 case Intrinsic::vastart:

366

368 std::nullopt, nullptr, MemRef::Read | MemRef::Write);

369 break;

370 case Intrinsic::vacopy:

372 std::nullopt, nullptr, MemRef::Write);

374 std::nullopt, nullptr, MemRef::Read);

375 break;

376 case Intrinsic::vaend:

378 std::nullopt, nullptr, MemRef::Read | MemRef::Write);

379 break;

380

381 case Intrinsic::stackrestore:

382

383

384

386 std::nullopt, nullptr, MemRef::Read | MemRef::Write);

387 break;

388 case Intrinsic::get_active_lane_mask:

389 if (auto *TripCount = dyn_cast(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, true);

405 Check(!isa(Obj), "Unusual: Returning alloca value", &I);

406 }

407}

408

409

410

413

414

416 return;

417

421 "Undefined behavior: Null pointer dereference", &I);

423 "Undefined behavior: Undef pointer dereference", &I);

426 "Unusual: All-ones pointer dereference", &I);

429 "Unusual: Address one pointer dereference", &I);

430

431 if (Flags & MemRef::Write) {

432 if (TT.isAMDGPU())

435 "Undefined behavior: Write to memory in const addrspace", &I);

436

438 Check(!GV->isConstant(), "Undefined behavior: Write to read-only memory",

439 &I);

442 "Undefined behavior: Write to text section", &I);

443 }

444 if (Flags & MemRef::Read) {

446 &I);

448 "Undefined behavior: Load from block address", &I);

449 }

450 if (Flags & MemRef::Callee) {

452 "Undefined behavior: Call to block address", &I);

453 }

454 if (Flags & MemRef::Branchee) {

457 "Undefined behavior: Branch to non-blockaddress", &I);

458 }

459

460

461

462

465

466

467

470

472 Type *ATy = AI->getAllocatedType();

474 BaseSize = DL->getTypeAllocSize(ATy).getFixedValue();

475 BaseAlign = AI->getAlign();

477

478

479 if (GV->hasDefinitiveInitializer()) {

480 Type *GTy = GV->getValueType();

482 BaseSize = DL->getTypeAllocSize(GTy);

483 BaseAlign = GV->getAlign();

484 if (!BaseAlign && GTy->isSized())

485 BaseAlign = DL->getABITypeAlign(GTy);

486 }

487 }

488

489

490

494 "Undefined behavior: Buffer overflow", &I);

495

496

497

499 Align = DL->getABITypeAlign(Ty);

500 if (BaseAlign && Align)

502 "Undefined behavior: Memory reference address is misaligned", &I);

503 }

504}

505

506void Lint::visitLoadInst(LoadInst &I) {

508 MemRef::Read);

509}

510

511void Lint::visitStoreInst(StoreInst &I) {

513 I.getOperand(0)->getType(), MemRef::Write);

514}

515

518 I.getOperand(0)->getType(), MemRef::Write);

519}

520

523 I.getOperand(0)->getType(), MemRef::Write);

524}

525

527 Check(!isa(I.getOperand(0)) || !isa(I.getOperand(1)),

528 "Undefined result: xor(undef, undef)", &I);

529}

530

532 Check(!isa(I.getOperand(0)) || !isa(I.getOperand(1)),

533 "Undefined result: sub(undef, undef)", &I);

534}

535

537 if (ConstantInt *CI = dyn_cast(findValue(I.getOperand(1),

538 false)))

539 Check(CI->getValue().ult(cast(I.getType())->getBitWidth()),

540 "Undefined result: Shift count out of range", &I);

541}

542

545 dyn_cast(findValue(I.getOperand(1), false)))

546 Check(CI->getValue().ult(cast(I.getType())->getBitWidth()),

547 "Undefined result: Shift count out of range", &I);

548}

549

552 dyn_cast(findValue(I.getOperand(1), false)))

553 Check(CI->getValue().ult(cast(I.getType())->getBitWidth()),

554 "Undefined result: Shift count out of range", &I);

555}

556

559

560 if (isa(V))

561 return true;

562

563 VectorType *VecTy = dyn_cast(V->getType());

564 if (!VecTy) {

567 return Known.isZero();

568 }

569

570

571 Constant *C = dyn_cast(V);

572 if (C)

573 return false;

574

575 if (C->isZeroValue())

576 return true;

577

578

579

580 for (unsigned I = 0, N = cast(VecTy)->getNumElements();

581 I != N; ++I) {

582 Constant *Elem = C->getAggregateElement(I);

583 if (isa(Elem))

584 return true;

585

588 return true;

589 }

590

591 return false;

592}

593

595 Check(isZero(I.getOperand(1), I.getDataLayout(), DT, AC),

596 "Undefined behavior: Division by zero", &I);

597}

598

600 Check(isZero(I.getOperand(1), I.getDataLayout(), DT, AC),

601 "Undefined behavior: Division by zero", &I);

602}

603

605 Check(isZero(I.getOperand(1), I.getDataLayout(), DT, AC),

606 "Undefined behavior: Division by zero", &I);

607}

608

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(I.getArraySize()))

616

617 Check(&I.getParent()->getParent()->getEntryBlock() == I.getParent(),

618 "Pessimization: Static alloca outside of entry block", &I);

619

620

621}

622

623void Lint::visitVAArgInst(VAArgInst &I) {

625 MemRef::Read | MemRef::Write);

626}

627

630 std::nullopt, nullptr, MemRef::Branchee);

631

632 Check(I.getNumDestinations() != 0,

633 "Undefined behavior: indirectbr with no destinations", &I);

634}

635

637 if (ConstantInt *CI = dyn_cast(findValue(I.getIndexOperand(),

638 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

646 if (ConstantInt *CI = dyn_cast(findValue(I.getOperand(2),

647 false))) {

649 Check(EC.isScalable() || CI->getValue().ult(EC.getFixedValue()),

650 "Undefined result: insertelement index out of range", &I);

651 }

652}

653

655

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

664

665

666

667

668

669

670Value *Lint::findValue(Value *V, bool OffsetOk) const {

672 return findValueImpl(V, OffsetOk, Visited);

673}

674

675

676Value *Lint::findValueImpl(Value *V, bool OffsetOk,

678

679 if (!Visited.insert(V).second)

681

682

683

684

685

686

688 if (LoadInst *L = dyn_cast(V)) {

693 for (;;) {

694 if (!VisitedBlocks.insert(BB).second)

695 break;

698 return findValueImpl(U, OffsetOk, Visited);

699 if (BBI != BB->begin())

700 break;

702 if (!BB)

703 break;

704 BBI = BB->end();

705 }

706 } else if (PHINode *PN = dyn_cast(V)) {

707 if (Value *W = PN->hasConstantValue())

708 return findValueImpl(W, OffsetOk, Visited);

709 } else if (CastInst *CI = dyn_cast(V)) {

710 if (CI->isNoopCast(*DL))

711 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);

712 } else if (ExtractValueInst *Ex = dyn_cast(V)) {

715 if (W != V)

716 return findValueImpl(W, OffsetOk, Visited);

717 } else if (ConstantExpr *CE = dyn_cast(V)) {

718

721 CE->getOperand(0)->getType(), CE->getType(),

722 *DL))

723 return findValueImpl(CE->getOperand(0), OffsetOk, Visited);

724 }

725 }

726

727

728 if (Instruction *Inst = dyn_cast(V)) {

730 return findValueImpl(W, OffsetOk, Visited);

731 } else if (auto *C = dyn_cast(V)) {

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();

747 Lint L(Mod, DL, AA, AC, DT, TLI);

748 L.visit(F);

749 dbgs() << L.MessagesStr.str();

753 false);

755}

756

757

758

759

760

761

762

765 assert(F.isDeclaration() && "Cannot lint external functions");

766

776 return AA;

777 });

779}

780

781

782

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

This is the interface for LLVM's primary stateless and local alias analysis.

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)

static const char LintAbortOnErrorArgName[]

static cl::opt< bool > LintAbortOnError(LintAbortOnErrorArgName, cl::init(false), cl::desc("In the Lint pass, abort on errors."))

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

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.

@ PartialAlias

The two locations alias, but only due to a partial overlap.

@ MustAlias

The two locations precisely alias each other.

an instruction to allocate memory on the stack

A container for analyses that lazily runs them and caches their results.

bool registerPass(PassBuilderT &&PassBuilder)

Register an analysis pass with the manager.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

This class represents an incoming formal argument to a Function.

bool hasNoAliasAttr() const

Return true if this argument has the noalias attribute.

bool onlyReadsMemory() const

Return true if this argument has the readonly or readnone attribute.

Type * getParamStructRetType() const

If this is an sret argument, return its type.

bool hasStructRetAttr() const

Return true if this argument has the sret attribute.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

A function analysis which provides an AssumptionCache.

A cache of @llvm.assume calls within a function.

An instruction that atomically checks whether a specified value is in a memory location,...

an instruction that atomically reads a memory location, combines it with another value,...

Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const

Return the attribute object that exists at the arg index.

bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const

Return true if the attribute exists for the given argument.

AttributeSet getAttributes(unsigned Index) const

The attributes for the specified index are returned.

static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)

AttrKind

This enumeration lists the attributes that can be associated with parameters, function results,...

bool isValid() const

Return true if the attribute is any kind of attribute.

Analysis pass providing a never-invalidated alias analysis result.

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

const BasicBlock * getUniquePredecessor() const

Return the predecessor of this block if it has a unique predecessor block.

InstListType::iterator iterator

Instruction iterators...

This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

This is the base class for all instructions that perform data casts.

static bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, const DataLayout &DL)

A no-op cast is one that can be effected without changing any bits.

A constant value that is initialized with an expression using other constant values.

This is the shared class of boolean and integer constants.

This is an important base class in LLVM.

A parsed version of the target data layout string in and methods for querying it.

Analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

Indirect Branch Instruction.

This instruction inserts a single (scalar) element into a VectorType value.

Base class for instruction visitors.

RetTy visitIndirectBrInst(IndirectBrInst &I)

RetTy visitExtractElementInst(ExtractElementInst &I)

RetTy visitCallBase(CallBase &I)

void visitFunction(Function &F)

RetTy visitUnreachableInst(UnreachableInst &I)

RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I)

RetTy visitReturnInst(ReturnInst &I)

RetTy visitStoreInst(StoreInst &I)

RetTy visitInsertElementInst(InsertElementInst &I)

RetTy visitAtomicRMWInst(AtomicRMWInst &I)

RetTy visitAllocaInst(AllocaInst &I)

RetTy visitLoadInst(LoadInst &I)

RetTy visitVAArgInst(VAArgInst &I)

A wrapper class for inspecting calls to intrinsic functions.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

An instruction for reading from memory.

static LocationSize precise(uint64_t Value)

TypeSize getValue() const

static constexpr LocationSize afterPointer()

Any location after the base pointer (but still within the underlying object).

This class wraps the llvm.memcpy intrinsic.

Value * getLength() const

Value * getDest() const

This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...

MaybeAlign getDestAlign() const

This class wraps the llvm.memmove intrinsic.

This class wraps the llvm.memset.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.

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Return a value (possibly void), from a function.

Analysis pass providing a never-invalidated alias analysis result.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

An instruction for storing to memory.

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

Analysis pass providing a never-invalidated alias analysis result.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isPointerTy() const

True if this is an instance of PointerType.

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

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.

Type * getType() const

All values are typed, get the type of this value.

A raw_ostream that writes to an std::string.

bool isConstantAddressSpace(unsigned AS)

@ C

The default llvm calling convention, compatible with C.

@ CE

Windows NT (Windows on ARM)

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)

Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.

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 ...

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.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

void lintModule(const Module &M)

Lint a module.

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.

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.

This struct is a compact representation of a valid (non-zero power of two) alignment.

bool isZero() const

Returns true if value is all zero.

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.