1e440b493SArthur Eubanks //===-- Lint.cpp - Check for common errors in LLVM IR ---------------------===// 2e440b493SArthur Eubanks // 3e440b493SArthur Eubanks // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e440b493SArthur Eubanks // See https://llvm.org/LICENSE.txt for license information. 5e440b493SArthur Eubanks // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e440b493SArthur Eubanks // 7e440b493SArthur Eubanks //===----------------------------------------------------------------------===// 8e440b493SArthur Eubanks // 9e440b493SArthur Eubanks // This pass statically checks for common and easily-identified constructs 10e440b493SArthur Eubanks // which produce undefined or likely unintended behavior in LLVM IR. 11e440b493SArthur Eubanks // 12e440b493SArthur Eubanks // It is not a guarantee of correctness, in two ways. First, it isn't 13e440b493SArthur Eubanks // comprehensive. There are checks which could be done statically which are 14e440b493SArthur Eubanks // not yet implemented. Some of these are indicated by TODO comments, but 15e440b493SArthur Eubanks // those aren't comprehensive either. Second, many conditions cannot be 16e440b493SArthur Eubanks // checked statically. This pass does no dynamic instrumentation, so it 17e440b493SArthur Eubanks // can't check for all possible problems. 18e440b493SArthur Eubanks // 19e440b493SArthur Eubanks // Another limitation is that it assumes all code will be executed. A store 20e440b493SArthur Eubanks // through a null pointer in a basic block which is never reached is harmless, 21e440b493SArthur Eubanks // but this pass will warn about it anyway. This is the main reason why most 22e440b493SArthur Eubanks // of these checks live here instead of in the Verifier pass. 23e440b493SArthur Eubanks // 24e440b493SArthur Eubanks // Optimization passes may make conditions that this pass checks for more or 25e440b493SArthur Eubanks // less obvious. If an optimization pass appears to be introducing a warning, 26e440b493SArthur Eubanks // it may be that the optimization pass is merely exposing an existing 27e440b493SArthur Eubanks // condition in the code. 28e440b493SArthur Eubanks // 29e440b493SArthur Eubanks // This code may be run before instcombine. In many cases, instcombine checks 30e440b493SArthur Eubanks // for the same kinds of things and turns instructions with undefined behavior 31e440b493SArthur Eubanks // into unreachable (or equivalent). Because of this, this pass makes some 32e440b493SArthur Eubanks // effort to look through bitcasts and so on. 33e440b493SArthur Eubanks // 34e440b493SArthur Eubanks //===----------------------------------------------------------------------===// 35e440b493SArthur Eubanks 36e440b493SArthur Eubanks #include "llvm/Analysis/Lint.h" 37e440b493SArthur Eubanks #include "llvm/ADT/APInt.h" 38e440b493SArthur Eubanks #include "llvm/ADT/ArrayRef.h" 39e440b493SArthur Eubanks #include "llvm/ADT/SmallPtrSet.h" 40e440b493SArthur Eubanks #include "llvm/ADT/Twine.h" 41e440b493SArthur Eubanks #include "llvm/Analysis/AliasAnalysis.h" 42e440b493SArthur Eubanks #include "llvm/Analysis/AssumptionCache.h" 43e440b493SArthur Eubanks #include "llvm/Analysis/ConstantFolding.h" 44e440b493SArthur Eubanks #include "llvm/Analysis/InstructionSimplify.h" 45e440b493SArthur Eubanks #include "llvm/Analysis/Loads.h" 46e440b493SArthur Eubanks #include "llvm/Analysis/MemoryLocation.h" 47e440b493SArthur Eubanks #include "llvm/Analysis/Passes.h" 48e440b493SArthur Eubanks #include "llvm/Analysis/TargetLibraryInfo.h" 49e440b493SArthur Eubanks #include "llvm/Analysis/ValueTracking.h" 50e440b493SArthur Eubanks #include "llvm/IR/Argument.h" 51e440b493SArthur Eubanks #include "llvm/IR/BasicBlock.h" 52e440b493SArthur Eubanks #include "llvm/IR/Constant.h" 53e440b493SArthur Eubanks #include "llvm/IR/Constants.h" 54e440b493SArthur Eubanks #include "llvm/IR/DataLayout.h" 55e440b493SArthur Eubanks #include "llvm/IR/DerivedTypes.h" 56e440b493SArthur Eubanks #include "llvm/IR/Dominators.h" 57e440b493SArthur Eubanks #include "llvm/IR/Function.h" 58e440b493SArthur Eubanks #include "llvm/IR/GlobalVariable.h" 59e440b493SArthur Eubanks #include "llvm/IR/InstVisitor.h" 60e440b493SArthur Eubanks #include "llvm/IR/InstrTypes.h" 61e440b493SArthur Eubanks #include "llvm/IR/Instruction.h" 62e440b493SArthur Eubanks #include "llvm/IR/Instructions.h" 63e440b493SArthur Eubanks #include "llvm/IR/IntrinsicInst.h" 64e440b493SArthur Eubanks #include "llvm/IR/LegacyPassManager.h" 65e440b493SArthur Eubanks #include "llvm/IR/Module.h" 66c9771391SArthur Eubanks #include "llvm/IR/PassManager.h" 67e440b493SArthur Eubanks #include "llvm/IR/Type.h" 68e440b493SArthur Eubanks #include "llvm/IR/Value.h" 69e440b493SArthur Eubanks #include "llvm/InitializePasses.h" 70e440b493SArthur Eubanks #include "llvm/Pass.h" 71e440b493SArthur Eubanks #include "llvm/Support/Casting.h" 72e440b493SArthur Eubanks #include "llvm/Support/Debug.h" 73e440b493SArthur Eubanks #include "llvm/Support/KnownBits.h" 74e440b493SArthur Eubanks #include "llvm/Support/MathExtras.h" 75e440b493SArthur Eubanks #include "llvm/Support/raw_ostream.h" 76e440b493SArthur Eubanks #include <cassert> 77e440b493SArthur Eubanks #include <cstdint> 78e440b493SArthur Eubanks #include <iterator> 79e440b493SArthur Eubanks #include <string> 80e440b493SArthur Eubanks 81e440b493SArthur Eubanks using namespace llvm; 82e440b493SArthur Eubanks 83e440b493SArthur Eubanks namespace { 84e440b493SArthur Eubanks namespace MemRef { 85e440b493SArthur Eubanks static const unsigned Read = 1; 86e440b493SArthur Eubanks static const unsigned Write = 2; 87e440b493SArthur Eubanks static const unsigned Callee = 4; 88e440b493SArthur Eubanks static const unsigned Branchee = 8; 89e440b493SArthur Eubanks } // end namespace MemRef 90e440b493SArthur Eubanks 91c9771391SArthur Eubanks class Lint : public InstVisitor<Lint> { 92e440b493SArthur Eubanks friend class InstVisitor<Lint>; 93e440b493SArthur Eubanks 94e440b493SArthur Eubanks void visitFunction(Function &F); 95e440b493SArthur Eubanks 96e440b493SArthur Eubanks void visitCallBase(CallBase &CB); 9722ec72f8SNikita Popov void visitMemoryReference(Instruction &I, const MemoryLocation &Loc, 98e440b493SArthur Eubanks MaybeAlign Alignment, Type *Ty, unsigned Flags); 99e440b493SArthur Eubanks void visitEHBeginCatch(IntrinsicInst *II); 100e440b493SArthur Eubanks void visitEHEndCatch(IntrinsicInst *II); 101e440b493SArthur Eubanks 102e440b493SArthur Eubanks void visitReturnInst(ReturnInst &I); 103e440b493SArthur Eubanks void visitLoadInst(LoadInst &I); 104e440b493SArthur Eubanks void visitStoreInst(StoreInst &I); 105e440b493SArthur Eubanks void visitXor(BinaryOperator &I); 106e440b493SArthur Eubanks void visitSub(BinaryOperator &I); 107e440b493SArthur Eubanks void visitLShr(BinaryOperator &I); 108e440b493SArthur Eubanks void visitAShr(BinaryOperator &I); 109e440b493SArthur Eubanks void visitShl(BinaryOperator &I); 110e440b493SArthur Eubanks void visitSDiv(BinaryOperator &I); 111e440b493SArthur Eubanks void visitUDiv(BinaryOperator &I); 112e440b493SArthur Eubanks void visitSRem(BinaryOperator &I); 113e440b493SArthur Eubanks void visitURem(BinaryOperator &I); 114e440b493SArthur Eubanks void visitAllocaInst(AllocaInst &I); 115e440b493SArthur Eubanks void visitVAArgInst(VAArgInst &I); 116e440b493SArthur Eubanks void visitIndirectBrInst(IndirectBrInst &I); 117e440b493SArthur Eubanks void visitExtractElementInst(ExtractElementInst &I); 118e440b493SArthur Eubanks void visitInsertElementInst(InsertElementInst &I); 119e440b493SArthur Eubanks void visitUnreachableInst(UnreachableInst &I); 120e440b493SArthur Eubanks 121e440b493SArthur Eubanks Value *findValue(Value *V, bool OffsetOk) const; 122e440b493SArthur Eubanks Value *findValueImpl(Value *V, bool OffsetOk, 123e440b493SArthur Eubanks SmallPtrSetImpl<Value *> &Visited) const; 124e440b493SArthur Eubanks 125e440b493SArthur Eubanks public: 126e440b493SArthur Eubanks Module *Mod; 127e440b493SArthur Eubanks const DataLayout *DL; 128e440b493SArthur Eubanks AliasAnalysis *AA; 129e440b493SArthur Eubanks AssumptionCache *AC; 130e440b493SArthur Eubanks DominatorTree *DT; 131e440b493SArthur Eubanks TargetLibraryInfo *TLI; 132e440b493SArthur Eubanks 133e440b493SArthur Eubanks std::string Messages; 134e440b493SArthur Eubanks raw_string_ostream MessagesStr; 135e440b493SArthur Eubanks 136c9771391SArthur Eubanks Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA, 137c9771391SArthur Eubanks AssumptionCache *AC, DominatorTree *DT, TargetLibraryInfo *TLI) 138c9771391SArthur Eubanks : Mod(Mod), DL(DL), AA(AA), AC(AC), DT(DT), TLI(TLI), 139c9771391SArthur Eubanks MessagesStr(Messages) {} 140e440b493SArthur Eubanks 141e440b493SArthur Eubanks void WriteValues(ArrayRef<const Value *> Vs) { 142e440b493SArthur Eubanks for (const Value *V : Vs) { 143e440b493SArthur Eubanks if (!V) 144e440b493SArthur Eubanks continue; 145e440b493SArthur Eubanks if (isa<Instruction>(V)) { 146e440b493SArthur Eubanks MessagesStr << *V << '\n'; 147e440b493SArthur Eubanks } else { 148e440b493SArthur Eubanks V->printAsOperand(MessagesStr, true, Mod); 149e440b493SArthur Eubanks MessagesStr << '\n'; 150e440b493SArthur Eubanks } 151e440b493SArthur Eubanks } 152e440b493SArthur Eubanks } 153e440b493SArthur Eubanks 154e440b493SArthur Eubanks /// A check failed, so printout out the condition and the message. 155e440b493SArthur Eubanks /// 156e440b493SArthur Eubanks /// This provides a nice place to put a breakpoint if you want to see why 157e440b493SArthur Eubanks /// something is not correct. 158e440b493SArthur Eubanks void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; } 159e440b493SArthur Eubanks 160e440b493SArthur Eubanks /// A check failed (with values to print). 161e440b493SArthur Eubanks /// 162e440b493SArthur Eubanks /// This calls the Message-only version so that the above is easier to set 163e440b493SArthur Eubanks /// a breakpoint on. 164e440b493SArthur Eubanks template <typename T1, typename... Ts> 165e440b493SArthur Eubanks void CheckFailed(const Twine &Message, const T1 &V1, const Ts &... Vs) { 166e440b493SArthur Eubanks CheckFailed(Message); 167e440b493SArthur Eubanks WriteValues({V1, Vs...}); 168e440b493SArthur Eubanks } 169e440b493SArthur Eubanks }; 170e440b493SArthur Eubanks } // end anonymous namespace 171e440b493SArthur Eubanks 172e440b493SArthur Eubanks // Assert - We know that cond should be true, if not print an error message. 173e440b493SArthur Eubanks #define Assert(C, ...) \ 174c9771391SArthur Eubanks do { \ 175c9771391SArthur Eubanks if (!(C)) { \ 176c9771391SArthur Eubanks CheckFailed(__VA_ARGS__); \ 177c9771391SArthur Eubanks return; \ 178c9771391SArthur Eubanks } \ 179c9771391SArthur Eubanks } while (false) 180e440b493SArthur Eubanks 181e440b493SArthur Eubanks void Lint::visitFunction(Function &F) { 182e440b493SArthur Eubanks // This isn't undefined behavior, it's just a little unusual, and it's a 183e440b493SArthur Eubanks // fairly common mistake to neglect to name a function. 184e440b493SArthur Eubanks Assert(F.hasName() || F.hasLocalLinkage(), 185e440b493SArthur Eubanks "Unusual: Unnamed function with non-local linkage", &F); 186e440b493SArthur Eubanks 187e440b493SArthur Eubanks // TODO: Check for irreducible control flow. 188e440b493SArthur Eubanks } 189e440b493SArthur Eubanks 190e440b493SArthur Eubanks void Lint::visitCallBase(CallBase &I) { 191e440b493SArthur Eubanks Value *Callee = I.getCalledOperand(); 192e440b493SArthur Eubanks 1934df8efceSNikita Popov visitMemoryReference(I, MemoryLocation::getAfter(Callee), None, nullptr, 1944df8efceSNikita Popov MemRef::Callee); 195e440b493SArthur Eubanks 196e440b493SArthur Eubanks if (Function *F = dyn_cast<Function>(findValue(Callee, 197e440b493SArthur Eubanks /*OffsetOk=*/false))) { 198e440b493SArthur Eubanks Assert(I.getCallingConv() == F->getCallingConv(), 199e440b493SArthur Eubanks "Undefined behavior: Caller and callee calling convention differ", 200e440b493SArthur Eubanks &I); 201e440b493SArthur Eubanks 202e440b493SArthur Eubanks FunctionType *FT = F->getFunctionType(); 203e440b493SArthur Eubanks unsigned NumActualArgs = I.arg_size(); 204e440b493SArthur Eubanks 205e440b493SArthur Eubanks Assert(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs 206e440b493SArthur Eubanks : FT->getNumParams() == NumActualArgs, 207e440b493SArthur Eubanks "Undefined behavior: Call argument count mismatches callee " 208e440b493SArthur Eubanks "argument count", 209e440b493SArthur Eubanks &I); 210e440b493SArthur Eubanks 211e440b493SArthur Eubanks Assert(FT->getReturnType() == I.getType(), 212e440b493SArthur Eubanks "Undefined behavior: Call return type mismatches " 213e440b493SArthur Eubanks "callee return type", 214e440b493SArthur Eubanks &I); 215e440b493SArthur Eubanks 216e440b493SArthur Eubanks // Check argument types (in case the callee was casted) and attributes. 217e440b493SArthur Eubanks // TODO: Verify that caller and callee attributes are compatible. 218e440b493SArthur Eubanks Function::arg_iterator PI = F->arg_begin(), PE = F->arg_end(); 219e440b493SArthur Eubanks auto AI = I.arg_begin(), AE = I.arg_end(); 220e440b493SArthur Eubanks for (; AI != AE; ++AI) { 221e440b493SArthur Eubanks Value *Actual = *AI; 222e440b493SArthur Eubanks if (PI != PE) { 223e440b493SArthur Eubanks Argument *Formal = &*PI++; 224e440b493SArthur Eubanks Assert(Formal->getType() == Actual->getType(), 225e440b493SArthur Eubanks "Undefined behavior: Call argument type mismatches " 226e440b493SArthur Eubanks "callee parameter type", 227e440b493SArthur Eubanks &I); 228e440b493SArthur Eubanks 229e440b493SArthur Eubanks // Check that noalias arguments don't alias other arguments. This is 230e440b493SArthur Eubanks // not fully precise because we don't know the sizes of the dereferenced 231e440b493SArthur Eubanks // memory regions. 232e440b493SArthur Eubanks if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) { 233e440b493SArthur Eubanks AttributeList PAL = I.getAttributes(); 234e440b493SArthur Eubanks unsigned ArgNo = 0; 235e440b493SArthur Eubanks for (auto BI = I.arg_begin(); BI != AE; ++BI, ++ArgNo) { 236e440b493SArthur Eubanks // Skip ByVal arguments since they will be memcpy'd to the callee's 237e440b493SArthur Eubanks // stack so we're not really passing the pointer anyway. 238a0c42ca5SArthur Eubanks if (PAL.hasParamAttr(ArgNo, Attribute::ByVal)) 239e440b493SArthur Eubanks continue; 240e440b493SArthur Eubanks // If both arguments are readonly, they have no dependence. 241e440b493SArthur Eubanks if (Formal->onlyReadsMemory() && I.onlyReadsMemory(ArgNo)) 242e440b493SArthur Eubanks continue; 243e440b493SArthur Eubanks if (AI != BI && (*BI)->getType()->isPointerTy()) { 244e440b493SArthur Eubanks AliasResult Result = AA->alias(*AI, *BI); 245d0660797Sdfukalov Assert(Result != AliasResult::MustAlias && 246d0660797Sdfukalov Result != AliasResult::PartialAlias, 247e440b493SArthur Eubanks "Unusual: noalias argument aliases another argument", &I); 248e440b493SArthur Eubanks } 249e440b493SArthur Eubanks } 250e440b493SArthur Eubanks } 251e440b493SArthur Eubanks 252e440b493SArthur Eubanks // Check that an sret argument points to valid memory. 253e440b493SArthur Eubanks if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { 254d65a7003SMatt Arsenault Type *Ty = Formal->getParamStructRetType(); 25522ec72f8SNikita Popov MemoryLocation Loc( 25622ec72f8SNikita Popov Actual, LocationSize::precise(DL->getTypeStoreSize(Ty))); 25722ec72f8SNikita Popov visitMemoryReference(I, Loc, DL->getABITypeAlign(Ty), Ty, 258e440b493SArthur Eubanks MemRef::Read | MemRef::Write); 259e440b493SArthur Eubanks } 260e440b493SArthur Eubanks } 261e440b493SArthur Eubanks } 262e440b493SArthur Eubanks } 263e440b493SArthur Eubanks 264e440b493SArthur Eubanks if (const auto *CI = dyn_cast<CallInst>(&I)) { 265e440b493SArthur Eubanks if (CI->isTailCall()) { 266e440b493SArthur Eubanks const AttributeList &PAL = CI->getAttributes(); 267e440b493SArthur Eubanks unsigned ArgNo = 0; 268e440b493SArthur Eubanks for (Value *Arg : I.args()) { 269e440b493SArthur Eubanks // Skip ByVal arguments since they will be memcpy'd to the callee's 270e440b493SArthur Eubanks // stack anyway. 271a0c42ca5SArthur Eubanks if (PAL.hasParamAttr(ArgNo++, Attribute::ByVal)) 272e440b493SArthur Eubanks continue; 273e440b493SArthur Eubanks Value *Obj = findValue(Arg, /*OffsetOk=*/true); 274e440b493SArthur Eubanks Assert(!isa<AllocaInst>(Obj), 275e440b493SArthur Eubanks "Undefined behavior: Call with \"tail\" keyword references " 276e440b493SArthur Eubanks "alloca", 277e440b493SArthur Eubanks &I); 278e440b493SArthur Eubanks } 279e440b493SArthur Eubanks } 280e440b493SArthur Eubanks } 281e440b493SArthur Eubanks 282e440b493SArthur Eubanks if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) 283e440b493SArthur Eubanks switch (II->getIntrinsicID()) { 284c9771391SArthur Eubanks default: 285c9771391SArthur Eubanks break; 286e440b493SArthur Eubanks 287e440b493SArthur Eubanks // TODO: Check more intrinsics 288e440b493SArthur Eubanks 289e440b493SArthur Eubanks case Intrinsic::memcpy: { 290e440b493SArthur Eubanks MemCpyInst *MCI = cast<MemCpyInst>(&I); 29122ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForDest(MCI), 292e440b493SArthur Eubanks MCI->getDestAlign(), nullptr, MemRef::Write); 29322ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForSource(MCI), 294e440b493SArthur Eubanks MCI->getSourceAlign(), nullptr, MemRef::Read); 295e440b493SArthur Eubanks 296e440b493SArthur Eubanks // Check that the memcpy arguments don't overlap. The AliasAnalysis API 297e440b493SArthur Eubanks // isn't expressive enough for what we really want to do. Known partial 298e440b493SArthur Eubanks // overlap is not distinguished from the case where nothing is known. 2994df8efceSNikita Popov auto Size = LocationSize::afterPointer(); 300e440b493SArthur Eubanks if (const ConstantInt *Len = 301e440b493SArthur Eubanks dyn_cast<ConstantInt>(findValue(MCI->getLength(), 302e440b493SArthur Eubanks /*OffsetOk=*/false))) 303e440b493SArthur Eubanks if (Len->getValue().isIntN(32)) 304e440b493SArthur Eubanks Size = LocationSize::precise(Len->getValue().getZExtValue()); 305e440b493SArthur Eubanks Assert(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) != 306d0660797Sdfukalov AliasResult::MustAlias, 307e440b493SArthur Eubanks "Undefined behavior: memcpy source and destination overlap", &I); 308e440b493SArthur Eubanks break; 309e440b493SArthur Eubanks } 310e440b493SArthur Eubanks case Intrinsic::memcpy_inline: { 311e440b493SArthur Eubanks MemCpyInlineInst *MCII = cast<MemCpyInlineInst>(&I); 312e440b493SArthur Eubanks const uint64_t Size = MCII->getLength()->getValue().getLimitedValue(); 31322ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForDest(MCII), 31422ec72f8SNikita Popov MCII->getDestAlign(), nullptr, MemRef::Write); 31522ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForSource(MCII), 31622ec72f8SNikita Popov MCII->getSourceAlign(), nullptr, MemRef::Read); 317e440b493SArthur Eubanks 318e440b493SArthur Eubanks // Check that the memcpy arguments don't overlap. The AliasAnalysis API 319e440b493SArthur Eubanks // isn't expressive enough for what we really want to do. Known partial 320e440b493SArthur Eubanks // overlap is not distinguished from the case where nothing is known. 321e440b493SArthur Eubanks const LocationSize LS = LocationSize::precise(Size); 322d0660797Sdfukalov Assert(AA->alias(MCII->getSource(), LS, MCII->getDest(), LS) != 323d0660797Sdfukalov AliasResult::MustAlias, 324e440b493SArthur Eubanks "Undefined behavior: memcpy source and destination overlap", &I); 325e440b493SArthur Eubanks break; 326e440b493SArthur Eubanks } 327e440b493SArthur Eubanks case Intrinsic::memmove: { 328e440b493SArthur Eubanks MemMoveInst *MMI = cast<MemMoveInst>(&I); 32922ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForDest(MMI), 330e440b493SArthur Eubanks MMI->getDestAlign(), nullptr, MemRef::Write); 33122ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForSource(MMI), 332e440b493SArthur Eubanks MMI->getSourceAlign(), nullptr, MemRef::Read); 333e440b493SArthur Eubanks break; 334e440b493SArthur Eubanks } 335e440b493SArthur Eubanks case Intrinsic::memset: { 336e440b493SArthur Eubanks MemSetInst *MSI = cast<MemSetInst>(&I); 33722ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForDest(MSI), 338e440b493SArthur Eubanks MSI->getDestAlign(), nullptr, MemRef::Write); 339e440b493SArthur Eubanks break; 340e440b493SArthur Eubanks } 341e440b493SArthur Eubanks 342e440b493SArthur Eubanks case Intrinsic::vastart: 343e440b493SArthur Eubanks Assert(I.getParent()->getParent()->isVarArg(), 344e440b493SArthur Eubanks "Undefined behavior: va_start called in a non-varargs function", 345e440b493SArthur Eubanks &I); 346e440b493SArthur Eubanks 34722ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None, 34822ec72f8SNikita Popov nullptr, MemRef::Read | MemRef::Write); 349e440b493SArthur Eubanks break; 350e440b493SArthur Eubanks case Intrinsic::vacopy: 35122ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None, 35222ec72f8SNikita Popov nullptr, MemRef::Write); 35322ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForArgument(&I, 1, TLI), None, 35422ec72f8SNikita Popov nullptr, MemRef::Read); 355e440b493SArthur Eubanks break; 356e440b493SArthur Eubanks case Intrinsic::vaend: 35722ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None, 35822ec72f8SNikita Popov nullptr, MemRef::Read | MemRef::Write); 359e440b493SArthur Eubanks break; 360e440b493SArthur Eubanks 361e440b493SArthur Eubanks case Intrinsic::stackrestore: 362e440b493SArthur Eubanks // Stackrestore doesn't read or write memory, but it sets the 363e440b493SArthur Eubanks // stack pointer, which the compiler may read from or write to 364e440b493SArthur Eubanks // at any time, so check it for both readability and writeability. 36522ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None, 36622ec72f8SNikita Popov nullptr, MemRef::Read | MemRef::Write); 367e440b493SArthur Eubanks break; 3686637d72dSSjoerd Meijer case Intrinsic::get_active_lane_mask: 3696637d72dSSjoerd Meijer if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand(1))) 3706637d72dSSjoerd Meijer Assert(!TripCount->isZero(), "get_active_lane_mask: operand #2 " 3716637d72dSSjoerd Meijer "must be greater than 0", &I); 3726637d72dSSjoerd Meijer break; 373e440b493SArthur Eubanks } 374e440b493SArthur Eubanks } 375e440b493SArthur Eubanks 376e440b493SArthur Eubanks void Lint::visitReturnInst(ReturnInst &I) { 377e440b493SArthur Eubanks Function *F = I.getParent()->getParent(); 378e440b493SArthur Eubanks Assert(!F->doesNotReturn(), 379e440b493SArthur Eubanks "Unusual: Return statement in function with noreturn attribute", &I); 380e440b493SArthur Eubanks 381e440b493SArthur Eubanks if (Value *V = I.getReturnValue()) { 382e440b493SArthur Eubanks Value *Obj = findValue(V, /*OffsetOk=*/true); 383e440b493SArthur Eubanks Assert(!isa<AllocaInst>(Obj), "Unusual: Returning alloca value", &I); 384e440b493SArthur Eubanks } 385e440b493SArthur Eubanks } 386e440b493SArthur Eubanks 387e440b493SArthur Eubanks // TODO: Check that the reference is in bounds. 388e440b493SArthur Eubanks // TODO: Check readnone/readonly function attributes. 38922ec72f8SNikita Popov void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc, 390e440b493SArthur Eubanks MaybeAlign Align, Type *Ty, unsigned Flags) { 391e440b493SArthur Eubanks // If no memory is being referenced, it doesn't matter if the pointer 392e440b493SArthur Eubanks // is valid. 39322ec72f8SNikita Popov if (Loc.Size.isZero()) 394e440b493SArthur Eubanks return; 395e440b493SArthur Eubanks 39622ec72f8SNikita Popov Value *Ptr = const_cast<Value *>(Loc.Ptr); 397e440b493SArthur Eubanks Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true); 398e440b493SArthur Eubanks Assert(!isa<ConstantPointerNull>(UnderlyingObject), 399e440b493SArthur Eubanks "Undefined behavior: Null pointer dereference", &I); 400e440b493SArthur Eubanks Assert(!isa<UndefValue>(UnderlyingObject), 401e440b493SArthur Eubanks "Undefined behavior: Undef pointer dereference", &I); 402e440b493SArthur Eubanks Assert(!isa<ConstantInt>(UnderlyingObject) || 403e440b493SArthur Eubanks !cast<ConstantInt>(UnderlyingObject)->isMinusOne(), 404e440b493SArthur Eubanks "Unusual: All-ones pointer dereference", &I); 405e440b493SArthur Eubanks Assert(!isa<ConstantInt>(UnderlyingObject) || 406e440b493SArthur Eubanks !cast<ConstantInt>(UnderlyingObject)->isOne(), 407e440b493SArthur Eubanks "Unusual: Address one pointer dereference", &I); 408e440b493SArthur Eubanks 409e440b493SArthur Eubanks if (Flags & MemRef::Write) { 410e440b493SArthur Eubanks if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject)) 411e440b493SArthur Eubanks Assert(!GV->isConstant(), "Undefined behavior: Write to read-only memory", 412e440b493SArthur Eubanks &I); 413e440b493SArthur Eubanks Assert(!isa<Function>(UnderlyingObject) && 414e440b493SArthur Eubanks !isa<BlockAddress>(UnderlyingObject), 415e440b493SArthur Eubanks "Undefined behavior: Write to text section", &I); 416e440b493SArthur Eubanks } 417e440b493SArthur Eubanks if (Flags & MemRef::Read) { 418e440b493SArthur Eubanks Assert(!isa<Function>(UnderlyingObject), "Unusual: Load from function body", 419e440b493SArthur Eubanks &I); 420e440b493SArthur Eubanks Assert(!isa<BlockAddress>(UnderlyingObject), 421e440b493SArthur Eubanks "Undefined behavior: Load from block address", &I); 422e440b493SArthur Eubanks } 423e440b493SArthur Eubanks if (Flags & MemRef::Callee) { 424e440b493SArthur Eubanks Assert(!isa<BlockAddress>(UnderlyingObject), 425e440b493SArthur Eubanks "Undefined behavior: Call to block address", &I); 426e440b493SArthur Eubanks } 427e440b493SArthur Eubanks if (Flags & MemRef::Branchee) { 428e440b493SArthur Eubanks Assert(!isa<Constant>(UnderlyingObject) || 429e440b493SArthur Eubanks isa<BlockAddress>(UnderlyingObject), 430e440b493SArthur Eubanks "Undefined behavior: Branch to non-blockaddress", &I); 431e440b493SArthur Eubanks } 432e440b493SArthur Eubanks 433e440b493SArthur Eubanks // Check for buffer overflows and misalignment. 434e440b493SArthur Eubanks // Only handles memory references that read/write something simple like an 435e440b493SArthur Eubanks // alloca instruction or a global variable. 436e440b493SArthur Eubanks int64_t Offset = 0; 437e440b493SArthur Eubanks if (Value *Base = GetPointerBaseWithConstantOffset(Ptr, Offset, *DL)) { 438e440b493SArthur Eubanks // OK, so the access is to a constant offset from Ptr. Check that Ptr is 439e440b493SArthur Eubanks // something we can handle and if so extract the size of this base object 440e440b493SArthur Eubanks // along with its alignment. 441e440b493SArthur Eubanks uint64_t BaseSize = MemoryLocation::UnknownSize; 442e440b493SArthur Eubanks MaybeAlign BaseAlign; 443e440b493SArthur Eubanks 444e440b493SArthur Eubanks if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) { 445e440b493SArthur Eubanks Type *ATy = AI->getAllocatedType(); 446e440b493SArthur Eubanks if (!AI->isArrayAllocation() && ATy->isSized()) 447e440b493SArthur Eubanks BaseSize = DL->getTypeAllocSize(ATy); 448e440b493SArthur Eubanks BaseAlign = AI->getAlign(); 449e440b493SArthur Eubanks } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { 450e440b493SArthur Eubanks // If the global may be defined differently in another compilation unit 451e440b493SArthur Eubanks // then don't warn about funky memory accesses. 452e440b493SArthur Eubanks if (GV->hasDefinitiveInitializer()) { 453e440b493SArthur Eubanks Type *GTy = GV->getValueType(); 454e440b493SArthur Eubanks if (GTy->isSized()) 455e440b493SArthur Eubanks BaseSize = DL->getTypeAllocSize(GTy); 456e440b493SArthur Eubanks BaseAlign = GV->getAlign(); 457e440b493SArthur Eubanks if (!BaseAlign && GTy->isSized()) 458e440b493SArthur Eubanks BaseAlign = DL->getABITypeAlign(GTy); 459e440b493SArthur Eubanks } 460e440b493SArthur Eubanks } 461e440b493SArthur Eubanks 462e440b493SArthur Eubanks // Accesses from before the start or after the end of the object are not 463e440b493SArthur Eubanks // defined. 46422ec72f8SNikita Popov Assert(!Loc.Size.hasValue() || BaseSize == MemoryLocation::UnknownSize || 46522ec72f8SNikita Popov (Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize), 466e440b493SArthur Eubanks "Undefined behavior: Buffer overflow", &I); 467e440b493SArthur Eubanks 468e440b493SArthur Eubanks // Accesses that say that the memory is more aligned than it is are not 469e440b493SArthur Eubanks // defined. 470e440b493SArthur Eubanks if (!Align && Ty && Ty->isSized()) 471e440b493SArthur Eubanks Align = DL->getABITypeAlign(Ty); 472e440b493SArthur Eubanks if (BaseAlign && Align) 473e440b493SArthur Eubanks Assert(*Align <= commonAlignment(*BaseAlign, Offset), 474e440b493SArthur Eubanks "Undefined behavior: Memory reference address is misaligned", &I); 475e440b493SArthur Eubanks } 476e440b493SArthur Eubanks } 477e440b493SArthur Eubanks 478e440b493SArthur Eubanks void Lint::visitLoadInst(LoadInst &I) { 47922ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(), I.getType(), 48022ec72f8SNikita Popov MemRef::Read); 481e440b493SArthur Eubanks } 482e440b493SArthur Eubanks 483e440b493SArthur Eubanks void Lint::visitStoreInst(StoreInst &I) { 48422ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(), 48522ec72f8SNikita Popov I.getOperand(0)->getType(), MemRef::Write); 486e440b493SArthur Eubanks } 487e440b493SArthur Eubanks 488e440b493SArthur Eubanks void Lint::visitXor(BinaryOperator &I) { 489e440b493SArthur Eubanks Assert(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)), 490e440b493SArthur Eubanks "Undefined result: xor(undef, undef)", &I); 491e440b493SArthur Eubanks } 492e440b493SArthur Eubanks 493e440b493SArthur Eubanks void Lint::visitSub(BinaryOperator &I) { 494e440b493SArthur Eubanks Assert(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)), 495e440b493SArthur Eubanks "Undefined result: sub(undef, undef)", &I); 496e440b493SArthur Eubanks } 497e440b493SArthur Eubanks 498e440b493SArthur Eubanks void Lint::visitLShr(BinaryOperator &I) { 499e440b493SArthur Eubanks if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(1), 500e440b493SArthur Eubanks /*OffsetOk=*/false))) 501e440b493SArthur Eubanks Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()), 502e440b493SArthur Eubanks "Undefined result: Shift count out of range", &I); 503e440b493SArthur Eubanks } 504e440b493SArthur Eubanks 505e440b493SArthur Eubanks void Lint::visitAShr(BinaryOperator &I) { 506e440b493SArthur Eubanks if (ConstantInt *CI = 507e440b493SArthur Eubanks dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false))) 508e440b493SArthur Eubanks Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()), 509e440b493SArthur Eubanks "Undefined result: Shift count out of range", &I); 510e440b493SArthur Eubanks } 511e440b493SArthur Eubanks 512e440b493SArthur Eubanks void Lint::visitShl(BinaryOperator &I) { 513e440b493SArthur Eubanks if (ConstantInt *CI = 514e440b493SArthur Eubanks dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false))) 515e440b493SArthur Eubanks Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()), 516e440b493SArthur Eubanks "Undefined result: Shift count out of range", &I); 517e440b493SArthur Eubanks } 518e440b493SArthur Eubanks 519e440b493SArthur Eubanks static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, 520e440b493SArthur Eubanks AssumptionCache *AC) { 521e440b493SArthur Eubanks // Assume undef could be zero. 522e440b493SArthur Eubanks if (isa<UndefValue>(V)) 523e440b493SArthur Eubanks return true; 524e440b493SArthur Eubanks 525e440b493SArthur Eubanks VectorType *VecTy = dyn_cast<VectorType>(V->getType()); 526e440b493SArthur Eubanks if (!VecTy) { 527c9771391SArthur Eubanks KnownBits Known = 528c9771391SArthur Eubanks computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT); 529e440b493SArthur Eubanks return Known.isZero(); 530e440b493SArthur Eubanks } 531e440b493SArthur Eubanks 532e440b493SArthur Eubanks // Per-component check doesn't work with zeroinitializer 533e440b493SArthur Eubanks Constant *C = dyn_cast<Constant>(V); 534e440b493SArthur Eubanks if (!C) 535e440b493SArthur Eubanks return false; 536e440b493SArthur Eubanks 537e440b493SArthur Eubanks if (C->isZeroValue()) 538e440b493SArthur Eubanks return true; 539e440b493SArthur Eubanks 540e440b493SArthur Eubanks // For a vector, KnownZero will only be true if all values are zero, so check 541e440b493SArthur Eubanks // this per component 542e440b493SArthur Eubanks for (unsigned I = 0, N = cast<FixedVectorType>(VecTy)->getNumElements(); 543e440b493SArthur Eubanks I != N; ++I) { 544e440b493SArthur Eubanks Constant *Elem = C->getAggregateElement(I); 545e440b493SArthur Eubanks if (isa<UndefValue>(Elem)) 546e440b493SArthur Eubanks return true; 547e440b493SArthur Eubanks 548e440b493SArthur Eubanks KnownBits Known = computeKnownBits(Elem, DL); 549e440b493SArthur Eubanks if (Known.isZero()) 550e440b493SArthur Eubanks return true; 551e440b493SArthur Eubanks } 552e440b493SArthur Eubanks 553e440b493SArthur Eubanks return false; 554e440b493SArthur Eubanks } 555e440b493SArthur Eubanks 556e440b493SArthur Eubanks void Lint::visitSDiv(BinaryOperator &I) { 557e440b493SArthur Eubanks Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC), 558e440b493SArthur Eubanks "Undefined behavior: Division by zero", &I); 559e440b493SArthur Eubanks } 560e440b493SArthur Eubanks 561e440b493SArthur Eubanks void Lint::visitUDiv(BinaryOperator &I) { 562e440b493SArthur Eubanks Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC), 563e440b493SArthur Eubanks "Undefined behavior: Division by zero", &I); 564e440b493SArthur Eubanks } 565e440b493SArthur Eubanks 566e440b493SArthur Eubanks void Lint::visitSRem(BinaryOperator &I) { 567e440b493SArthur Eubanks Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC), 568e440b493SArthur Eubanks "Undefined behavior: Division by zero", &I); 569e440b493SArthur Eubanks } 570e440b493SArthur Eubanks 571e440b493SArthur Eubanks void Lint::visitURem(BinaryOperator &I) { 572e440b493SArthur Eubanks Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC), 573e440b493SArthur Eubanks "Undefined behavior: Division by zero", &I); 574e440b493SArthur Eubanks } 575e440b493SArthur Eubanks 576e440b493SArthur Eubanks void Lint::visitAllocaInst(AllocaInst &I) { 577e440b493SArthur Eubanks if (isa<ConstantInt>(I.getArraySize())) 578e440b493SArthur Eubanks // This isn't undefined behavior, it's just an obvious pessimization. 579e440b493SArthur Eubanks Assert(&I.getParent()->getParent()->getEntryBlock() == I.getParent(), 580e440b493SArthur Eubanks "Pessimization: Static alloca outside of entry block", &I); 581e440b493SArthur Eubanks 582e440b493SArthur Eubanks // TODO: Check for an unusual size (MSB set?) 583e440b493SArthur Eubanks } 584e440b493SArthur Eubanks 585e440b493SArthur Eubanks void Lint::visitVAArgInst(VAArgInst &I) { 58622ec72f8SNikita Popov visitMemoryReference(I, MemoryLocation::get(&I), None, nullptr, 58722ec72f8SNikita Popov MemRef::Read | MemRef::Write); 588e440b493SArthur Eubanks } 589e440b493SArthur Eubanks 590e440b493SArthur Eubanks void Lint::visitIndirectBrInst(IndirectBrInst &I) { 5914df8efceSNikita Popov visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()), None, 5924df8efceSNikita Popov nullptr, MemRef::Branchee); 593e440b493SArthur Eubanks 594e440b493SArthur Eubanks Assert(I.getNumDestinations() != 0, 595e440b493SArthur Eubanks "Undefined behavior: indirectbr with no destinations", &I); 596e440b493SArthur Eubanks } 597e440b493SArthur Eubanks 598e440b493SArthur Eubanks void Lint::visitExtractElementInst(ExtractElementInst &I) { 599e440b493SArthur Eubanks if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getIndexOperand(), 600e440b493SArthur Eubanks /*OffsetOk=*/false))) 601e440b493SArthur Eubanks Assert( 602e440b493SArthur Eubanks CI->getValue().ult( 603e440b493SArthur Eubanks cast<FixedVectorType>(I.getVectorOperandType())->getNumElements()), 604e440b493SArthur Eubanks "Undefined result: extractelement index out of range", &I); 605e440b493SArthur Eubanks } 606e440b493SArthur Eubanks 607e440b493SArthur Eubanks void Lint::visitInsertElementInst(InsertElementInst &I) { 608e440b493SArthur Eubanks if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(2), 609e440b493SArthur Eubanks /*OffsetOk=*/false))) 610e440b493SArthur Eubanks Assert(CI->getValue().ult( 611e440b493SArthur Eubanks cast<FixedVectorType>(I.getType())->getNumElements()), 612e440b493SArthur Eubanks "Undefined result: insertelement index out of range", &I); 613e440b493SArthur Eubanks } 614e440b493SArthur Eubanks 615e440b493SArthur Eubanks void Lint::visitUnreachableInst(UnreachableInst &I) { 616e440b493SArthur Eubanks // This isn't undefined behavior, it's merely suspicious. 617e440b493SArthur Eubanks Assert(&I == &I.getParent()->front() || 618e440b493SArthur Eubanks std::prev(I.getIterator())->mayHaveSideEffects(), 619e440b493SArthur Eubanks "Unusual: unreachable immediately preceded by instruction without " 620e440b493SArthur Eubanks "side effects", 621e440b493SArthur Eubanks &I); 622e440b493SArthur Eubanks } 623e440b493SArthur Eubanks 624e440b493SArthur Eubanks /// findValue - Look through bitcasts and simple memory reference patterns 625e440b493SArthur Eubanks /// to identify an equivalent, but more informative, value. If OffsetOk 626e440b493SArthur Eubanks /// is true, look through getelementptrs with non-zero offsets too. 627e440b493SArthur Eubanks /// 628e440b493SArthur Eubanks /// Most analysis passes don't require this logic, because instcombine 629e440b493SArthur Eubanks /// will simplify most of these kinds of things away. But it's a goal of 630e440b493SArthur Eubanks /// this Lint pass to be useful even on non-optimized IR. 631e440b493SArthur Eubanks Value *Lint::findValue(Value *V, bool OffsetOk) const { 632e440b493SArthur Eubanks SmallPtrSet<Value *, 4> Visited; 633e440b493SArthur Eubanks return findValueImpl(V, OffsetOk, Visited); 634e440b493SArthur Eubanks } 635e440b493SArthur Eubanks 636e440b493SArthur Eubanks /// findValueImpl - Implementation helper for findValue. 637e440b493SArthur Eubanks Value *Lint::findValueImpl(Value *V, bool OffsetOk, 638e440b493SArthur Eubanks SmallPtrSetImpl<Value *> &Visited) const { 639e440b493SArthur Eubanks // Detect self-referential values. 640e440b493SArthur Eubanks if (!Visited.insert(V).second) 641e440b493SArthur Eubanks return UndefValue::get(V->getType()); 642e440b493SArthur Eubanks 643e440b493SArthur Eubanks // TODO: Look through sext or zext cast, when the result is known to 644e440b493SArthur Eubanks // be interpreted as signed or unsigned, respectively. 645e440b493SArthur Eubanks // TODO: Look through eliminable cast pairs. 646e440b493SArthur Eubanks // TODO: Look through calls with unique return values. 647e440b493SArthur Eubanks // TODO: Look through vector insert/extract/shuffle. 648e440b493SArthur Eubanks V = OffsetOk ? getUnderlyingObject(V) : V->stripPointerCasts(); 649e440b493SArthur Eubanks if (LoadInst *L = dyn_cast<LoadInst>(V)) { 650e440b493SArthur Eubanks BasicBlock::iterator BBI = L->getIterator(); 651e440b493SArthur Eubanks BasicBlock *BB = L->getParent(); 652e440b493SArthur Eubanks SmallPtrSet<BasicBlock *, 4> VisitedBlocks; 653e440b493SArthur Eubanks for (;;) { 654e440b493SArthur Eubanks if (!VisitedBlocks.insert(BB).second) 655e440b493SArthur Eubanks break; 656e440b493SArthur Eubanks if (Value *U = 657e440b493SArthur Eubanks FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA)) 658e440b493SArthur Eubanks return findValueImpl(U, OffsetOk, Visited); 659c9771391SArthur Eubanks if (BBI != BB->begin()) 660c9771391SArthur Eubanks break; 661e440b493SArthur Eubanks BB = BB->getUniquePredecessor(); 662c9771391SArthur Eubanks if (!BB) 663c9771391SArthur Eubanks break; 664e440b493SArthur Eubanks BBI = BB->end(); 665e440b493SArthur Eubanks } 666e440b493SArthur Eubanks } else if (PHINode *PN = dyn_cast<PHINode>(V)) { 667e440b493SArthur Eubanks if (Value *W = PN->hasConstantValue()) 668e440b493SArthur Eubanks return findValueImpl(W, OffsetOk, Visited); 669e440b493SArthur Eubanks } else if (CastInst *CI = dyn_cast<CastInst>(V)) { 670e440b493SArthur Eubanks if (CI->isNoopCast(*DL)) 671e440b493SArthur Eubanks return findValueImpl(CI->getOperand(0), OffsetOk, Visited); 672e440b493SArthur Eubanks } else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) { 673c9771391SArthur Eubanks if (Value *W = 674c9771391SArthur Eubanks FindInsertedValue(Ex->getAggregateOperand(), Ex->getIndices())) 675e440b493SArthur Eubanks if (W != V) 676e440b493SArthur Eubanks return findValueImpl(W, OffsetOk, Visited); 677e440b493SArthur Eubanks } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { 678e440b493SArthur Eubanks // Same as above, but for ConstantExpr instead of Instruction. 679e440b493SArthur Eubanks if (Instruction::isCast(CE->getOpcode())) { 680e440b493SArthur Eubanks if (CastInst::isNoopCast(Instruction::CastOps(CE->getOpcode()), 681e440b493SArthur Eubanks CE->getOperand(0)->getType(), CE->getType(), 682e440b493SArthur Eubanks *DL)) 683e440b493SArthur Eubanks return findValueImpl(CE->getOperand(0), OffsetOk, Visited); 684e440b493SArthur Eubanks } else if (CE->getOpcode() == Instruction::ExtractValue) { 685e440b493SArthur Eubanks ArrayRef<unsigned> Indices = CE->getIndices(); 686e440b493SArthur Eubanks if (Value *W = FindInsertedValue(CE->getOperand(0), Indices)) 687e440b493SArthur Eubanks if (W != V) 688e440b493SArthur Eubanks return findValueImpl(W, OffsetOk, Visited); 689e440b493SArthur Eubanks } 690e440b493SArthur Eubanks } 691e440b493SArthur Eubanks 692e440b493SArthur Eubanks // As a last resort, try SimplifyInstruction or constant folding. 693e440b493SArthur Eubanks if (Instruction *Inst = dyn_cast<Instruction>(V)) { 694e440b493SArthur Eubanks if (Value *W = SimplifyInstruction(Inst, {*DL, TLI, DT, AC})) 695e440b493SArthur Eubanks return findValueImpl(W, OffsetOk, Visited); 696e440b493SArthur Eubanks } else if (auto *C = dyn_cast<Constant>(V)) { 697e440b493SArthur Eubanks Value *W = ConstantFoldConstant(C, *DL, TLI); 698e440b493SArthur Eubanks if (W != V) 699e440b493SArthur Eubanks return findValueImpl(W, OffsetOk, Visited); 700e440b493SArthur Eubanks } 701e440b493SArthur Eubanks 702e440b493SArthur Eubanks return V; 703e440b493SArthur Eubanks } 704e440b493SArthur Eubanks 705c9771391SArthur Eubanks PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) { 706c9771391SArthur Eubanks auto *Mod = F.getParent(); 707c9771391SArthur Eubanks auto *DL = &F.getParent()->getDataLayout(); 708c9771391SArthur Eubanks auto *AA = &AM.getResult<AAManager>(F); 709c9771391SArthur Eubanks auto *AC = &AM.getResult<AssumptionAnalysis>(F); 710c9771391SArthur Eubanks auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); 711c9771391SArthur Eubanks auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F); 712c9771391SArthur Eubanks Lint L(Mod, DL, AA, AC, DT, TLI); 713c9771391SArthur Eubanks L.visit(F); 714c9771391SArthur Eubanks dbgs() << L.MessagesStr.str(); 715c9771391SArthur Eubanks return PreservedAnalyses::all(); 716c9771391SArthur Eubanks } 717c9771391SArthur Eubanks 718*9b8b1645SBenjamin Kramer namespace { 719c9771391SArthur Eubanks class LintLegacyPass : public FunctionPass { 720c9771391SArthur Eubanks public: 721c9771391SArthur Eubanks static char ID; // Pass identification, replacement for typeid 722c9771391SArthur Eubanks LintLegacyPass() : FunctionPass(ID) { 723c9771391SArthur Eubanks initializeLintLegacyPassPass(*PassRegistry::getPassRegistry()); 724c9771391SArthur Eubanks } 725c9771391SArthur Eubanks 726c9771391SArthur Eubanks bool runOnFunction(Function &F) override; 727c9771391SArthur Eubanks 728c9771391SArthur Eubanks void getAnalysisUsage(AnalysisUsage &AU) const override { 729c9771391SArthur Eubanks AU.setPreservesAll(); 730c9771391SArthur Eubanks AU.addRequired<AAResultsWrapperPass>(); 731c9771391SArthur Eubanks AU.addRequired<AssumptionCacheTracker>(); 732c9771391SArthur Eubanks AU.addRequired<TargetLibraryInfoWrapperPass>(); 733c9771391SArthur Eubanks AU.addRequired<DominatorTreeWrapperPass>(); 734c9771391SArthur Eubanks } 735c9771391SArthur Eubanks void print(raw_ostream &O, const Module *M) const override {} 736c9771391SArthur Eubanks }; 737*9b8b1645SBenjamin Kramer } // namespace 738c9771391SArthur Eubanks 739c9771391SArthur Eubanks char LintLegacyPass::ID = 0; 740c9771391SArthur Eubanks INITIALIZE_PASS_BEGIN(LintLegacyPass, "lint", "Statically lint-checks LLVM IR", 741c9771391SArthur Eubanks false, true) 742c9771391SArthur Eubanks INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 743c9771391SArthur Eubanks INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 744c9771391SArthur Eubanks INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 745c9771391SArthur Eubanks INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 746c9771391SArthur Eubanks INITIALIZE_PASS_END(LintLegacyPass, "lint", "Statically lint-checks LLVM IR", 747c9771391SArthur Eubanks false, true) 748c9771391SArthur Eubanks 749c9771391SArthur Eubanks bool LintLegacyPass::runOnFunction(Function &F) { 750c9771391SArthur Eubanks auto *Mod = F.getParent(); 751c9771391SArthur Eubanks auto *DL = &F.getParent()->getDataLayout(); 752c9771391SArthur Eubanks auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); 753c9771391SArthur Eubanks auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); 754c9771391SArthur Eubanks auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 755c9771391SArthur Eubanks auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 756c9771391SArthur Eubanks Lint L(Mod, DL, AA, AC, DT, TLI); 757c9771391SArthur Eubanks L.visit(F); 758c9771391SArthur Eubanks dbgs() << L.MessagesStr.str(); 759c9771391SArthur Eubanks return false; 760c9771391SArthur Eubanks } 761c9771391SArthur Eubanks 762e440b493SArthur Eubanks //===----------------------------------------------------------------------===// 763e440b493SArthur Eubanks // Implement the public interfaces to this file... 764e440b493SArthur Eubanks //===----------------------------------------------------------------------===// 765e440b493SArthur Eubanks 766c9771391SArthur Eubanks FunctionPass *llvm::createLintLegacyPassPass() { return new LintLegacyPass(); } 767e440b493SArthur Eubanks 768e440b493SArthur Eubanks /// lintFunction - Check a function for errors, printing messages on stderr. 769e440b493SArthur Eubanks /// 770e440b493SArthur Eubanks void llvm::lintFunction(const Function &f) { 771e440b493SArthur Eubanks Function &F = const_cast<Function &>(f); 772e440b493SArthur Eubanks assert(!F.isDeclaration() && "Cannot lint external functions"); 773e440b493SArthur Eubanks 774e440b493SArthur Eubanks legacy::FunctionPassManager FPM(F.getParent()); 775c9771391SArthur Eubanks auto *V = new LintLegacyPass(); 776e440b493SArthur Eubanks FPM.add(V); 777e440b493SArthur Eubanks FPM.run(F); 778e440b493SArthur Eubanks } 779e440b493SArthur Eubanks 780e440b493SArthur Eubanks /// lintModule - Check a module for errors, printing messages on stderr. 781e440b493SArthur Eubanks /// 782e440b493SArthur Eubanks void llvm::lintModule(const Module &M) { 783e440b493SArthur Eubanks legacy::PassManager PM; 784c9771391SArthur Eubanks auto *V = new LintLegacyPass(); 785e440b493SArthur Eubanks PM.add(V); 786e440b493SArthur Eubanks PM.run(const_cast<Module &>(M)); 787e440b493SArthur Eubanks } 788