aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/IR/Verifier.cpp
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/IR/Verifier.cpp')
-rw-r--r--lib/IR/Verifier.cpp921
1 files changed, 483 insertions, 438 deletions
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index da6b573..089ad1c 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -45,31 +45,30 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/Verifier.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
-#include "llvm/InstVisitor.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
-#include "llvm/PassManager.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -80,325 +79,258 @@ using namespace llvm;
static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier",
cl::init(true));
-namespace { // Anonymous namespace for class
- struct PreVerifier : public FunctionPass {
- static char ID; // Pass ID, replacement for typeid
-
- PreVerifier() : FunctionPass(ID) {
- initializePreVerifierPass(*PassRegistry::getPassRegistry());
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
-
- // Check that the prerequisites for successful DominatorTree construction
- // are satisfied.
- bool runOnFunction(Function &F) {
- bool Broken = false;
-
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
- if (I->empty() || !I->back().isTerminator()) {
- dbgs() << "Basic Block in function '" << F.getName()
- << "' does not have terminator!\n";
- WriteAsOperand(dbgs(), I, true);
- dbgs() << "\n";
- Broken = true;
- }
- }
-
- if (Broken)
- report_fatal_error("Broken module, no Basic Block terminator!");
-
- return false;
- }
- };
-}
-
-char PreVerifier::ID = 0;
-INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification",
- false, false)
-static char &PreVerifyID = PreVerifier::ID;
-
namespace {
- struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
- static char ID; // Pass ID, replacement for typeid
- bool Broken; // Is this module found to be broken?
- VerifierFailureAction action;
- // What to do if verification fails.
- Module *Mod; // Module we are verifying right now
- LLVMContext *Context; // Context within which we are verifying
- DominatorTree *DT; // Dominator Tree, caution can be null!
- const DataLayout *DL;
-
- std::string Messages;
- raw_string_ostream MessagesStr;
-
- /// InstInThisBlock - when verifying a basic block, keep track of all of the
- /// instructions we have seen so far. This allows us to do efficient
- /// dominance checks for the case when an instruction has an operand that is
- /// an instruction in the same block.
- SmallPtrSet<Instruction*, 16> InstsInThisBlock;
-
- /// MDNodes - keep track of the metadata nodes that have been checked
- /// already.
- SmallPtrSet<MDNode *, 32> MDNodes;
-
- /// PersonalityFn - The personality function referenced by the
- /// LandingPadInsts. All LandingPadInsts within the same function must use
- /// the same personality function.
- const Value *PersonalityFn;
-
- /// Finder keeps track of all debug info MDNodes in a Module.
- DebugInfoFinder Finder;
-
- Verifier()
- : FunctionPass(ID), Broken(false),
- action(AbortProcessAction), Mod(0), Context(0), DT(0), DL(0),
- MessagesStr(Messages), PersonalityFn(0) {
- initializeVerifierPass(*PassRegistry::getPassRegistry());
+class Verifier : public InstVisitor<Verifier> {
+ friend class InstVisitor<Verifier>;
+
+ raw_ostream &OS;
+ const Module *M;
+ LLVMContext *Context;
+ const DataLayout *DL;
+ DominatorTree DT;
+
+ /// \brief When verifying a basic block, keep track of all of the
+ /// instructions we have seen so far.
+ ///
+ /// This allows us to do efficient dominance checks for the case when an
+ /// instruction has an operand that is an instruction in the same block.
+ SmallPtrSet<Instruction *, 16> InstsInThisBlock;
+
+ /// \brief Keep track of the metadata nodes that have been checked already.
+ SmallPtrSet<MDNode *, 32> MDNodes;
+
+ /// \brief The personality function referenced by the LandingPadInsts.
+ /// All LandingPadInsts within the same function must use the same
+ /// personality function.
+ const Value *PersonalityFn;
+
+ /// \brief Finder keeps track of all debug info MDNodes in a Module.
+ DebugInfoFinder Finder;
+
+ /// \brief Track the brokenness of the module while recursively visiting.
+ bool Broken;
+
+public:
+ explicit Verifier(raw_ostream &OS = dbgs())
+ : OS(OS), M(0), Context(0), DL(0), PersonalityFn(0), Broken(false) {}
+
+ bool verify(const Function &F) {
+ M = F.getParent();
+ Context = &M->getContext();
+
+ // First ensure the function is well-enough formed to compute dominance
+ // information.
+ if (F.empty()) {
+ OS << "Function '" << F.getName()
+ << "' does not contain an entry block!\n";
+ return false;
}
- explicit Verifier(VerifierFailureAction ctn)
- : FunctionPass(ID), Broken(false), action(ctn), Mod(0),
- Context(0), DT(0), DL(0), MessagesStr(Messages), PersonalityFn(0) {
- initializeVerifierPass(*PassRegistry::getPassRegistry());
+ for (Function::const_iterator I = F.begin(), E = F.end(); I != E; ++I) {
+ if (I->empty() || !I->back().isTerminator()) {
+ OS << "Basic Block in function '" << F.getName()
+ << "' does not have terminator!\n";
+ I->printAsOperand(OS, true);
+ OS << "\n";
+ return false;
+ }
}
- bool doInitialization(Module &M) {
- Mod = &M;
- Context = &M.getContext();
+ // Now directly compute a dominance tree. We don't rely on the pass
+ // manager to provide this as it isolates us from a potentially
+ // out-of-date dominator tree and makes it significantly more complex to
+ // run this code outside of a pass manager.
+ // FIXME: It's really gross that we have to cast away constness here.
+ DT.recalculate(const_cast<Function &>(F));
- DL = getAnalysisIfAvailable<DataLayout>();
-
- // We must abort before returning back to the pass manager, or else the
- // pass manager may try to run other passes on the broken module.
- return abortIfBroken();
- }
+ Finder.reset();
+ Broken = false;
+ // FIXME: We strip const here because the inst visitor strips const.
+ visit(const_cast<Function &>(F));
+ InstsInThisBlock.clear();
+ PersonalityFn = 0;
- bool runOnFunction(Function &F) {
- // Get dominator information if we are being run by PassManager
- DT = &getAnalysis<DominatorTree>();
+ if (!DisableDebugInfoVerifier)
+ // Verify Debug Info.
+ verifyDebugInfo();
- Mod = F.getParent();
- if (!Context) Context = &F.getContext();
+ return !Broken;
+ }
- Finder.reset();
- visit(F);
- InstsInThisBlock.clear();
- PersonalityFn = 0;
+ bool verify(const Module &M) {
+ this->M = &M;
+ Context = &M.getContext();
+ Finder.reset();
+ Broken = false;
- if (!DisableDebugInfoVerifier)
- // Verify Debug Info.
- verifyDebugInfo();
+ // Scan through, checking all of the external function's linkage now...
+ for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
+ visitGlobalValue(*I);
- // We must abort before returning back to the pass manager, or else the
- // pass manager may try to run other passes on the broken module.
- return abortIfBroken();
+ // Check to make sure function prototypes are okay.
+ if (I->isDeclaration())
+ visitFunction(*I);
}
- bool doFinalization(Module &M) {
- // Scan through, checking all of the external function's linkage now...
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- visitGlobalValue(*I);
-
- // Check to make sure function prototypes are okay.
- if (I->isDeclaration()) visitFunction(*I);
- }
-
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- visitGlobalVariable(*I);
-
- for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I)
- visitGlobalAlias(*I);
-
- for (Module::named_metadata_iterator I = M.named_metadata_begin(),
- E = M.named_metadata_end(); I != E; ++I)
- visitNamedMDNode(*I);
+ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ visitGlobalVariable(*I);
- visitModuleFlags(M);
- visitModuleIdents(M);
+ for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E; ++I)
+ visitGlobalAlias(*I);
- if (!DisableDebugInfoVerifier) {
- Finder.reset();
- Finder.processModule(M);
- // Verify Debug Info.
- verifyDebugInfo();
- }
-
- // If the module is broken, abort at this time.
- return abortIfBroken();
- }
+ for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end();
+ I != E; ++I)
+ visitNamedMDNode(*I);
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequiredID(PreVerifyID);
- AU.addRequired<DominatorTree>();
- }
+ visitModuleFlags(M);
+ visitModuleIdents(M);
- /// abortIfBroken - If the module is broken and we are supposed to abort on
- /// this condition, do so.
- ///
- bool abortIfBroken() {
- if (!Broken) return false;
- MessagesStr << "Broken module found, ";
- switch (action) {
- case AbortProcessAction:
- MessagesStr << "compilation aborted!\n";
- dbgs() << MessagesStr.str();
- // Client should choose different reaction if abort is not desired
- abort();
- case PrintMessageAction:
- MessagesStr << "verification continues.\n";
- dbgs() << MessagesStr.str();
- return false;
- case ReturnStatusAction:
- MessagesStr << "compilation terminated.\n";
- return true;
- }
- llvm_unreachable("Invalid action");
+ if (!DisableDebugInfoVerifier) {
+ Finder.reset();
+ Finder.processModule(M);
+ // Verify Debug Info.
+ verifyDebugInfo();
}
+ return !Broken;
+ }
- // Verification methods...
- void visitGlobalValue(GlobalValue &GV);
- void visitGlobalVariable(GlobalVariable &GV);
- void visitGlobalAlias(GlobalAlias &GA);
- void visitNamedMDNode(NamedMDNode &NMD);
- void visitMDNode(MDNode &MD, Function *F);
- void visitModuleIdents(Module &M);
- void visitModuleFlags(Module &M);
- void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs,
- SmallVectorImpl<MDNode*> &Requirements);
- void visitFunction(Function &F);
- void visitBasicBlock(BasicBlock &BB);
- using InstVisitor<Verifier>::visit;
-
- void visit(Instruction &I);
-
- void visitTruncInst(TruncInst &I);
- void visitZExtInst(ZExtInst &I);
- void visitSExtInst(SExtInst &I);
- void visitFPTruncInst(FPTruncInst &I);
- void visitFPExtInst(FPExtInst &I);
- void visitFPToUIInst(FPToUIInst &I);
- void visitFPToSIInst(FPToSIInst &I);
- void visitUIToFPInst(UIToFPInst &I);
- void visitSIToFPInst(SIToFPInst &I);
- void visitIntToPtrInst(IntToPtrInst &I);
- void visitPtrToIntInst(PtrToIntInst &I);
- void visitBitCastInst(BitCastInst &I);
- void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
- void visitPHINode(PHINode &PN);
- void visitBinaryOperator(BinaryOperator &B);
- void visitICmpInst(ICmpInst &IC);
- void visitFCmpInst(FCmpInst &FC);
- void visitExtractElementInst(ExtractElementInst &EI);
- void visitInsertElementInst(InsertElementInst &EI);
- void visitShuffleVectorInst(ShuffleVectorInst &EI);
- void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
- void visitCallInst(CallInst &CI);
- void visitInvokeInst(InvokeInst &II);
- void visitGetElementPtrInst(GetElementPtrInst &GEP);
- void visitLoadInst(LoadInst &LI);
- void visitStoreInst(StoreInst &SI);
- void verifyDominatesUse(Instruction &I, unsigned i);
- void visitInstruction(Instruction &I);
- void visitTerminatorInst(TerminatorInst &I);
- void visitBranchInst(BranchInst &BI);
- void visitReturnInst(ReturnInst &RI);
- void visitSwitchInst(SwitchInst &SI);
- void visitIndirectBrInst(IndirectBrInst &BI);
- void visitSelectInst(SelectInst &SI);
- void visitUserOp1(Instruction &I);
- void visitUserOp2(Instruction &I) { visitUserOp1(I); }
- void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
- void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
- void visitAtomicRMWInst(AtomicRMWInst &RMWI);
- void visitFenceInst(FenceInst &FI);
- void visitAllocaInst(AllocaInst &AI);
- void visitExtractValueInst(ExtractValueInst &EVI);
- void visitInsertValueInst(InsertValueInst &IVI);
- void visitLandingPadInst(LandingPadInst &LPI);
-
- void VerifyCallSite(CallSite CS);
- bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty,
- int VT, unsigned ArgNo, std::string &Suffix);
- bool VerifyIntrinsicType(Type *Ty,
- ArrayRef<Intrinsic::IITDescriptor> &Infos,
- SmallVectorImpl<Type*> &ArgTys);
- bool VerifyIntrinsicIsVarArg(bool isVarArg,
- ArrayRef<Intrinsic::IITDescriptor> &Infos);
- bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
- void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
- bool isFunction, const Value *V);
- void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
- bool isReturnValue, const Value *V);
- void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
- const Value *V);
-
- void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
- void VerifyConstantExprBitcastType(const ConstantExpr *CE);
-
- void verifyDebugInfo();
-
- void WriteValue(const Value *V) {
- if (!V) return;
- if (isa<Instruction>(V)) {
- MessagesStr << *V << '\n';
- } else {
- WriteAsOperand(MessagesStr, V, true, Mod);
- MessagesStr << '\n';
- }
- }
-
- void WriteType(Type *T) {
- if (!T) return;
- MessagesStr << ' ' << *T;
+private:
+ // Verification methods...
+ void visitGlobalValue(const GlobalValue &GV);
+ void visitGlobalVariable(const GlobalVariable &GV);
+ void visitGlobalAlias(const GlobalAlias &GA);
+ void visitNamedMDNode(const NamedMDNode &NMD);
+ void visitMDNode(MDNode &MD, Function *F);
+ void visitModuleIdents(const Module &M);
+ void visitModuleFlags(const Module &M);
+ void visitModuleFlag(const MDNode *Op,
+ DenseMap<const MDString *, const MDNode *> &SeenIDs,
+ SmallVectorImpl<const MDNode *> &Requirements);
+ void visitFunction(const Function &F);
+ void visitBasicBlock(BasicBlock &BB);
+
+ // InstVisitor overrides...
+ using InstVisitor<Verifier>::visit;
+ void visit(Instruction &I);
+
+ void visitTruncInst(TruncInst &I);
+ void visitZExtInst(ZExtInst &I);
+ void visitSExtInst(SExtInst &I);
+ void visitFPTruncInst(FPTruncInst &I);
+ void visitFPExtInst(FPExtInst &I);
+ void visitFPToUIInst(FPToUIInst &I);
+ void visitFPToSIInst(FPToSIInst &I);
+ void visitUIToFPInst(UIToFPInst &I);
+ void visitSIToFPInst(SIToFPInst &I);
+ void visitIntToPtrInst(IntToPtrInst &I);
+ void visitPtrToIntInst(PtrToIntInst &I);
+ void visitBitCastInst(BitCastInst &I);
+ void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
+ void visitPHINode(PHINode &PN);
+ void visitBinaryOperator(BinaryOperator &B);
+ void visitICmpInst(ICmpInst &IC);
+ void visitFCmpInst(FCmpInst &FC);
+ void visitExtractElementInst(ExtractElementInst &EI);
+ void visitInsertElementInst(InsertElementInst &EI);
+ void visitShuffleVectorInst(ShuffleVectorInst &EI);
+ void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
+ void visitCallInst(CallInst &CI);
+ void visitInvokeInst(InvokeInst &II);
+ void visitGetElementPtrInst(GetElementPtrInst &GEP);
+ void visitLoadInst(LoadInst &LI);
+ void visitStoreInst(StoreInst &SI);
+ void verifyDominatesUse(Instruction &I, unsigned i);
+ void visitInstruction(Instruction &I);
+ void visitTerminatorInst(TerminatorInst &I);
+ void visitBranchInst(BranchInst &BI);
+ void visitReturnInst(ReturnInst &RI);
+ void visitSwitchInst(SwitchInst &SI);
+ void visitIndirectBrInst(IndirectBrInst &BI);
+ void visitSelectInst(SelectInst &SI);
+ void visitUserOp1(Instruction &I);
+ void visitUserOp2(Instruction &I) { visitUserOp1(I); }
+ void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
+ void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
+ void visitAtomicRMWInst(AtomicRMWInst &RMWI);
+ void visitFenceInst(FenceInst &FI);
+ void visitAllocaInst(AllocaInst &AI);
+ void visitExtractValueInst(ExtractValueInst &EVI);
+ void visitInsertValueInst(InsertValueInst &IVI);
+ void visitLandingPadInst(LandingPadInst &LPI);
+
+ void VerifyCallSite(CallSite CS);
+ bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT,
+ unsigned ArgNo, std::string &Suffix);
+ bool VerifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
+ SmallVectorImpl<Type *> &ArgTys);
+ bool VerifyIntrinsicIsVarArg(bool isVarArg,
+ ArrayRef<Intrinsic::IITDescriptor> &Infos);
+ bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
+ void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction,
+ const Value *V);
+ void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
+ bool isReturnValue, const Value *V);
+ void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
+ const Value *V);
+
+ void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
+ void VerifyConstantExprBitcastType(const ConstantExpr *CE);
+
+ void verifyDebugInfo();
+
+ void WriteValue(const Value *V) {
+ if (!V)
+ return;
+ if (isa<Instruction>(V)) {
+ OS << *V << '\n';
+ } else {
+ V->printAsOperand(OS, true, M);
+ OS << '\n';
}
+ }
+ void WriteType(Type *T) {
+ if (!T)
+ return;
+ OS << ' ' << *T;
+ }
- // CheckFailed - A check failed, so print out the condition and the message
- // that failed. This provides a nice place to put a breakpoint if you want
- // to see why something is not correct.
- void CheckFailed(const Twine &Message,
- const Value *V1 = 0, const Value *V2 = 0,
- const Value *V3 = 0, const Value *V4 = 0) {
- MessagesStr << Message.str() << "\n";
- WriteValue(V1);
- WriteValue(V2);
- WriteValue(V3);
- WriteValue(V4);
- Broken = true;
- }
+ // CheckFailed - A check failed, so print out the condition and the message
+ // that failed. This provides a nice place to put a breakpoint if you want
+ // to see why something is not correct.
+ void CheckFailed(const Twine &Message, const Value *V1 = 0,
+ const Value *V2 = 0, const Value *V3 = 0,
+ const Value *V4 = 0) {
+ OS << Message.str() << "\n";
+ WriteValue(V1);
+ WriteValue(V2);
+ WriteValue(V3);
+ WriteValue(V4);
+ Broken = true;
+ }
- void CheckFailed(const Twine &Message, const Value *V1,
- Type *T2, const Value *V3 = 0) {
- MessagesStr << Message.str() << "\n";
- WriteValue(V1);
- WriteType(T2);
- WriteValue(V3);
- Broken = true;
- }
+ void CheckFailed(const Twine &Message, const Value *V1, Type *T2,
+ const Value *V3 = 0) {
+ OS << Message.str() << "\n";
+ WriteValue(V1);
+ WriteType(T2);
+ WriteValue(V3);
+ Broken = true;
+ }
- void CheckFailed(const Twine &Message, Type *T1,
- Type *T2 = 0, Type *T3 = 0) {
- MessagesStr << Message.str() << "\n";
- WriteType(T1);
- WriteType(T2);
- WriteType(T3);
- Broken = true;
- }
- };
+ void CheckFailed(const Twine &Message, Type *T1, Type *T2 = 0, Type *T3 = 0) {
+ OS << Message.str() << "\n";
+ WriteType(T1);
+ WriteType(T2);
+ WriteType(T3);
+ Broken = true;
+ }
+};
} // End anonymous namespace
-char Verifier::ID = 0;
-INITIALIZE_PASS_BEGIN(Verifier, "verify", "Module Verifier", false, false)
-INITIALIZE_PASS_DEPENDENCY(PreVerifier)
-INITIALIZE_PASS_DEPENDENCY(DominatorTree)
-INITIALIZE_PASS_END(Verifier, "verify", "Module Verifier", false, false)
-
// Assert - We know that cond should be true, if not print an error message.
#define Assert(C, M) \
do { if (!(C)) { CheckFailed(M); return; } } while (0)
@@ -418,31 +350,27 @@ void Verifier::visit(Instruction &I) {
}
-void Verifier::visitGlobalValue(GlobalValue &GV) {
+void Verifier::visitGlobalValue(const GlobalValue &GV) {
Assert1(!GV.isDeclaration() ||
GV.isMaterializable() ||
GV.hasExternalLinkage() ||
- GV.hasDLLImportLinkage() ||
GV.hasExternalWeakLinkage() ||
(isa<GlobalAlias>(GV) &&
(GV.hasLocalLinkage() || GV.hasWeakLinkage())),
- "Global is external, but doesn't have external or dllimport or weak linkage!",
+ "Global is external, but doesn't have external or weak linkage!",
&GV);
- Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(),
- "Global is marked as dllimport, but not external", &GV);
-
Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
"Only global variables can have appending linkage!", &GV);
if (GV.hasAppendingLinkage()) {
- GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV);
+ const GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV);
Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(),
"Only global arrays can have appending linkage!", GVar);
}
}
-void Verifier::visitGlobalVariable(GlobalVariable &GV) {
+void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
if (GV.hasInitializer()) {
Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(),
"Global variable initializer type does not match global "
@@ -457,8 +385,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
&GV);
}
} else {
- Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() ||
- GV.hasExternalWeakLinkage(),
+ Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(),
"invalid linkage type for global declaration", &GV);
}
@@ -488,8 +415,8 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
Assert1(PTy, "wrong type for intrinsic global variable", &GV);
if (GV.hasInitializer()) {
- Constant *Init = GV.getInitializer();
- ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
+ const Constant *Init = GV.getInitializer();
+ const ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
Assert1(InitArray, "wrong initalizer for intrinsic global variable",
Init);
for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) {
@@ -503,6 +430,11 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
}
}
+ Assert1(!GV.hasDLLImportStorageClass() ||
+ (GV.isDeclaration() && GV.hasExternalLinkage()) ||
+ GV.hasAvailableExternallyLinkage(),
+ "Global is marked as dllimport, but not external", &GV);
+
if (!GV.hasInitializer()) {
visitGlobalValue(GV);
return;
@@ -533,7 +465,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
visitGlobalValue(GV);
}
-void Verifier::visitGlobalAlias(GlobalAlias &GA) {
+void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
Assert1(!GA.getName().empty(),
"Alias name cannot be empty!", &GA);
Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()),
@@ -543,20 +475,25 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) {
Assert1(GA.getType() == GA.getAliasee()->getType(),
"Alias and aliasee types should match!", &GA);
Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
+ Assert1(!GA.hasSection(), "Alias cannot have a section!", &GA);
+ Assert1(!GA.getAlignment(), "Alias connot have an alignment", &GA);
+
+ const Constant *Aliasee = GA.getAliasee();
+ const GlobalValue *GV = dyn_cast<GlobalValue>(Aliasee);
- Constant *Aliasee = GA.getAliasee();
+ if (!GV) {
+ const ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee);
+ if (CE && (CE->getOpcode() == Instruction::BitCast ||
+ CE->getOpcode() == Instruction::AddrSpaceCast ||
+ CE->getOpcode() == Instruction::GetElementPtr))
+ GV = dyn_cast<GlobalValue>(CE->getOperand(0));
- if (!isa<GlobalValue>(Aliasee)) {
- ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee);
- Assert1(CE &&
- (CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::GetElementPtr) &&
- isa<GlobalValue>(CE->getOperand(0)),
- "Aliasee should be either GlobalValue or bitcast of GlobalValue",
+ Assert1(GV, "Aliasee should be either GlobalValue, bitcast or "
+ "addrspacecast of GlobalValue",
&GA);
if (CE->getOpcode() == Instruction::BitCast) {
- unsigned SrcAS = CE->getOperand(0)->getType()->getPointerAddressSpace();
+ unsigned SrcAS = GV->getType()->getPointerAddressSpace();
unsigned DstAS = CE->getType()->getPointerAddressSpace();
Assert1(SrcAS == DstAS,
@@ -564,15 +501,20 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) {
&GA);
}
}
+ Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA);
+ if (const GlobalAlias *GAAliasee = dyn_cast<GlobalAlias>(GV)) {
+ Assert1(!GAAliasee->mayBeOverridden(), "Alias cannot point to a weak alias",
+ &GA);
+ }
- const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false);
- Assert1(Resolved,
- "Aliasing chain should end with function or global variable", &GA);
+ const GlobalValue *AG = GA.getAliasedGlobal();
+ Assert1(AG, "Aliasing chain should end with function or global variable",
+ &GA);
visitGlobalValue(GA);
}
-void Verifier::visitNamedMDNode(NamedMDNode &NMD) {
+void Verifier::visitNamedMDNode(const NamedMDNode &NMD) {
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) {
MDNode *MD = NMD.getOperand(i);
if (!MD)
@@ -620,7 +562,7 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) {
}
}
-void Verifier::visitModuleIdents(Module &M) {
+void Verifier::visitModuleIdents(const Module &M) {
const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident");
if (!Idents)
return;
@@ -638,24 +580,24 @@ void Verifier::visitModuleIdents(Module &M) {
}
}
-void Verifier::visitModuleFlags(Module &M) {
+void Verifier::visitModuleFlags(const Module &M) {
const NamedMDNode *Flags = M.getModuleFlagsMetadata();
if (!Flags) return;
// Scan each flag, and track the flags and requirements.
- DenseMap<MDString*, MDNode*> SeenIDs;
- SmallVector<MDNode*, 16> Requirements;
+ DenseMap<const MDString*, const MDNode*> SeenIDs;
+ SmallVector<const MDNode*, 16> Requirements;
for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) {
visitModuleFlag(Flags->getOperand(I), SeenIDs, Requirements);
}
// Validate that the requirements in the module are valid.
for (unsigned I = 0, E = Requirements.size(); I != E; ++I) {
- MDNode *Requirement = Requirements[I];
- MDString *Flag = cast<MDString>(Requirement->getOperand(0));
- Value *ReqValue = Requirement->getOperand(1);
+ const MDNode *Requirement = Requirements[I];
+ const MDString *Flag = cast<MDString>(Requirement->getOperand(0));
+ const Value *ReqValue = Requirement->getOperand(1);
- MDNode *Op = SeenIDs.lookup(Flag);
+ const MDNode *Op = SeenIDs.lookup(Flag);
if (!Op) {
CheckFailed("invalid requirement on flag, flag is not present in module",
Flag);
@@ -671,8 +613,10 @@ void Verifier::visitModuleFlags(Module &M) {
}
}
-void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs,
- SmallVectorImpl<MDNode*> &Requirements) {
+void
+Verifier::visitModuleFlag(const MDNode *Op,
+ DenseMap<const MDString *, const MDNode *> &SeenIDs,
+ SmallVectorImpl<const MDNode *> &Requirements) {
// Each module flag should have three arguments, the merge behavior (a
// constant int), the flag ID (an MDString), and the value.
Assert1(Op->getNumOperands() == 3,
@@ -813,26 +757,25 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
!Attrs.hasAttribute(Idx, Attribute::Nest) &&
!Attrs.hasAttribute(Idx, Attribute::StructRet) &&
!Attrs.hasAttribute(Idx, Attribute::NoCapture) &&
- !Attrs.hasAttribute(Idx, Attribute::Returned),
- "Attribute 'byval', 'nest', 'sret', 'nocapture', and 'returned' "
- "do not apply to return values!", V);
-
- // Check for mutually incompatible attributes.
- Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) &&
- Attrs.hasAttribute(Idx, Attribute::Nest)) ||
- (Attrs.hasAttribute(Idx, Attribute::ByVal) &&
- Attrs.hasAttribute(Idx, Attribute::StructRet)) ||
- (Attrs.hasAttribute(Idx, Attribute::Nest) &&
- Attrs.hasAttribute(Idx, Attribute::StructRet))), "Attributes "
- "'byval, nest, and sret' are incompatible!", V);
-
- Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) &&
- Attrs.hasAttribute(Idx, Attribute::Nest)) ||
- (Attrs.hasAttribute(Idx, Attribute::ByVal) &&
- Attrs.hasAttribute(Idx, Attribute::InReg)) ||
- (Attrs.hasAttribute(Idx, Attribute::Nest) &&
- Attrs.hasAttribute(Idx, Attribute::InReg))), "Attributes "
- "'byval, nest, and inreg' are incompatible!", V);
+ !Attrs.hasAttribute(Idx, Attribute::Returned) &&
+ !Attrs.hasAttribute(Idx, Attribute::InAlloca),
+ "Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', and "
+ "'returned' do not apply to return values!", V);
+
+ // Check for mutually incompatible attributes. Only inreg is compatible with
+ // sret.
+ unsigned AttrCount = 0;
+ AttrCount += Attrs.hasAttribute(Idx, Attribute::ByVal);
+ AttrCount += Attrs.hasAttribute(Idx, Attribute::InAlloca);
+ AttrCount += Attrs.hasAttribute(Idx, Attribute::StructRet) ||
+ Attrs.hasAttribute(Idx, Attribute::InReg);
+ AttrCount += Attrs.hasAttribute(Idx, Attribute::Nest);
+ Assert1(AttrCount <= 1, "Attributes 'byval', 'inalloca', 'inreg', 'nest', "
+ "and 'sret' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Idx, Attribute::InAlloca) &&
+ Attrs.hasAttribute(Idx, Attribute::ReadOnly)), "Attributes "
+ "'inalloca and readonly' are incompatible!", V);
Assert1(!(Attrs.hasAttribute(Idx, Attribute::StructRet) &&
Attrs.hasAttribute(Idx, Attribute::Returned)), "Attributes "
@@ -855,14 +798,18 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
"Wrong types for attribute: " +
AttributeFuncs::typeIncompatible(Ty, Idx).getAsString(Idx), V);
- if (PointerType *PTy = dyn_cast<PointerType>(Ty))
- Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) ||
- PTy->getElementType()->isSized(),
- "Attribute 'byval' does not support unsized types!", V);
- else
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
+ if (!PTy->getElementType()->isSized()) {
+ Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) &&
+ !Attrs.hasAttribute(Idx, Attribute::InAlloca),
+ "Attributes 'byval' and 'inalloca' do not support unsized types!",
+ V);
+ }
+ } else {
Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal),
"Attribute 'byval' only applies to parameters with pointer type!",
V);
+ }
}
// VerifyFunctionAttrs - Check parameter attributes against a function type.
@@ -906,6 +853,11 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
if (Attrs.hasAttribute(Idx, Attribute::StructRet))
Assert1(Idx == 1, "Attribute sret is not on first parameter!", V);
+
+ if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) {
+ Assert1(Idx == FT->getNumParams(),
+ "inalloca isn't on the last parameter!", V);
+ }
}
if (!Attrs.hasAttributes(AttributeSet::FunctionIndex))
@@ -1001,7 +953,7 @@ bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) {
// visitFunction - Verify that a function is ok.
//
-void Verifier::visitFunction(Function &F) {
+void Verifier::visitFunction(const Function &F) {
// Check function arguments.
FunctionType *FT = F.getFunctionType();
unsigned NumArgs = F.arg_size();
@@ -1059,8 +1011,8 @@ void Verifier::visitFunction(Function &F) {
// Check that the argument values match the function type for this function...
unsigned i = 0;
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
- I != E; ++I, ++i) {
+ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
+ ++I, ++i) {
Assert2(I->getType() == FT->getParamType(i),
"Argument value does not match function argument type!",
I, FT->getParamType(i));
@@ -1074,8 +1026,7 @@ void Verifier::visitFunction(Function &F) {
if (F.isMaterializable()) {
// Function has a body somewhere we can't see.
} else if (F.isDeclaration()) {
- Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() ||
- F.hasExternalWeakLinkage(),
+ Assert1(F.hasExternalLinkage() || F.hasExternalWeakLinkage(),
"invalid linkage type for function declaration", &F);
} else {
// Verify that this function (which has a body) is not named "llvm.*". It
@@ -1083,13 +1034,13 @@ void Verifier::visitFunction(Function &F) {
Assert1(!isLLVMdotName, "llvm intrinsics cannot be defined!", &F);
// Check the entry node
- BasicBlock *Entry = &F.getEntryBlock();
+ const BasicBlock *Entry = &F.getEntryBlock();
Assert1(pred_begin(Entry) == pred_end(Entry),
"Entry block to function must not have predecessors!", Entry);
// The address of the entry block cannot be taken, unless it is dead.
if (Entry->hasAddressTaken()) {
- Assert1(!BlockAddress::get(Entry)->isConstantUsed(),
+ Assert1(!BlockAddress::lookup(Entry)->isConstantUsed(),
"blockaddress may not be used with the entry block!", Entry);
}
}
@@ -1101,6 +1052,11 @@ void Verifier::visitFunction(Function &F) {
if (F.hasAddressTaken(&U))
Assert1(0, "Invalid user of intrinsic instruction!", U);
}
+
+ Assert1(!F.hasDLLImportStorageClass() ||
+ (F.isDeclaration() && F.hasExternalLinkage()) ||
+ F.hasAvailableExternallyLinkage(),
+ "Function is marked as dllimport, but not external.", &F);
}
// verifyBasicBlock - Verify that a basic block is well formed...
@@ -1566,6 +1522,10 @@ void Verifier::VerifyCallSite(CallSite CS) {
Assert1(!Attrs.hasAttribute(Idx, Attribute::StructRet),
"Attribute 'sret' cannot be used for vararg call arguments!", I);
+
+ if (Attrs.hasAttribute(Idx, Attribute::InAlloca))
+ Assert1(Idx == CS.arg_size(), "inalloca isn't on the last argument!",
+ I);
}
}
@@ -1861,22 +1821,37 @@ void Verifier::visitStoreInst(StoreInst &SI) {
}
void Verifier::visitAllocaInst(AllocaInst &AI) {
+ SmallPtrSet<const Type*, 4> Visited;
PointerType *PTy = AI.getType();
Assert1(PTy->getAddressSpace() == 0,
"Allocation instruction pointer not in the generic address space!",
&AI);
- Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type",
+ Assert1(PTy->getElementType()->isSized(&Visited), "Cannot allocate unsized type",
&AI);
Assert1(AI.getArraySize()->getType()->isIntegerTy(),
"Alloca array size must have integer type", &AI);
+
visitInstruction(AI);
}
void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) {
- Assert1(CXI.getOrdering() != NotAtomic,
+
+ // FIXME: more conditions???
+ Assert1(CXI.getSuccessOrdering() != NotAtomic,
"cmpxchg instructions must be atomic.", &CXI);
- Assert1(CXI.getOrdering() != Unordered,
+ Assert1(CXI.getFailureOrdering() != NotAtomic,
+ "cmpxchg instructions must be atomic.", &CXI);
+ Assert1(CXI.getSuccessOrdering() != Unordered,
+ "cmpxchg instructions cannot be unordered.", &CXI);
+ Assert1(CXI.getFailureOrdering() != Unordered,
"cmpxchg instructions cannot be unordered.", &CXI);
+ Assert1(CXI.getSuccessOrdering() >= CXI.getFailureOrdering(),
+ "cmpxchg instructions be at least as constrained on success as fail",
+ &CXI);
+ Assert1(CXI.getFailureOrdering() != Release &&
+ CXI.getFailureOrdering() != AcquireRelease,
+ "cmpxchg failure ordering cannot include release semantics", &CXI);
+
PointerType *PTy = dyn_cast<PointerType>(CXI.getOperand(0)->getType());
Assert1(PTy, "First cmpxchg operand must be a pointer.", &CXI);
Type *ElTy = PTy->getElementType();
@@ -2007,7 +1982,7 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
}
const Use &U = I.getOperandUse(i);
- Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, U),
+ Assert2(InstsInThisBlock.count(Op) || DT.dominates(Op, U),
"Instruction does not dominate all uses!", Op, &I);
}
@@ -2018,10 +1993,10 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(BB, "Instruction not embedded in basic block!", &I);
if (!isa<PHINode>(I)) { // Check that non-phi nodes are not self referential
- for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
- UI != UE; ++UI)
- Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB),
+ for (User *U : I.users()) {
+ Assert1(U != (User*)&I || !DT.isReachableFromEntry(BB),
"Only PHI nodes may reference their own value!", &I);
+ }
}
// Check that void typed values don't have names
@@ -2043,13 +2018,12 @@ void Verifier::visitInstruction(Instruction &I) {
// Check that all uses of the instruction, if they are instructions
// themselves, actually have parent basic blocks. If the use is not an
// instruction, it is an error!
- for (User::use_iterator UI = I.use_begin(), UE = I.use_end();
- UI != UE; ++UI) {
- if (Instruction *Used = dyn_cast<Instruction>(*UI))
+ for (Use &U : I.uses()) {
+ if (Instruction *Used = dyn_cast<Instruction>(U.getUser()))
Assert2(Used->getParent() != 0, "Instruction referencing instruction not"
" embedded in a basic block!", &I, Used);
else {
- CheckFailed("Use of instruction is not an instruction!", *UI);
+ CheckFailed("Use of instruction is not an instruction!", U);
return;
}
}
@@ -2071,7 +2045,7 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
F->getIntrinsicID() == Intrinsic::donothing,
"Cannot invoke an intrinsinc other than donothing", &I);
- Assert1(F->getParent() == Mod, "Referencing function in another module!",
+ Assert1(F->getParent() == M, "Referencing function in another module!",
&I);
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
Assert1(OpBB->getParent() == BB->getParent(),
@@ -2080,7 +2054,7 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(OpArg->getParent() == BB->getParent(),
"Referring to an argument in another function!", &I);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(I.getOperand(i))) {
- Assert1(GV->getParent() == Mod, "Referencing global in another module!",
+ Assert1(GV->getParent() == M, "Referencing global in another module!",
&I);
} else if (isa<Instruction>(I.getOperand(i))) {
verifyDominatesUse(I, i);
@@ -2131,7 +2105,7 @@ void Verifier::visitInstruction(Instruction &I) {
if (!DisableDebugInfoVerifier) {
MD = I.getMetadata(LLVMContext::MD_dbg);
- Finder.processLocation(*Mod, DILocation(MD));
+ Finder.processLocation(*M, DILocation(MD));
}
InstsInThisBlock.insert(&I);
@@ -2202,18 +2176,41 @@ bool Verifier::VerifyIntrinsicType(Type *Ty,
}
llvm_unreachable("all argument kinds not covered");
- case IITDescriptor::ExtendVecArgument:
+ case IITDescriptor::ExtendArgument: {
// This may only be used when referring to a previous vector argument.
- return D.getArgumentNumber() >= ArgTys.size() ||
- !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
- VectorType::getExtendedElementVectorType(
- cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
+ if (D.getArgumentNumber() >= ArgTys.size())
+ return true;
+
+ Type *NewTy = ArgTys[D.getArgumentNumber()];
+ if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
+ NewTy = VectorType::getExtendedElementVectorType(VTy);
+ else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
+ NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
+ else
+ return true;
+
+ return Ty != NewTy;
+ }
+ case IITDescriptor::TruncArgument: {
+ // This may only be used when referring to a previous vector argument.
+ if (D.getArgumentNumber() >= ArgTys.size())
+ return true;
- case IITDescriptor::TruncVecArgument:
+ Type *NewTy = ArgTys[D.getArgumentNumber()];
+ if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
+ NewTy = VectorType::getTruncatedElementVectorType(VTy);
+ else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
+ NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
+ else
+ return true;
+
+ return Ty != NewTy;
+ }
+ case IITDescriptor::HalfVecArgument:
// This may only be used when referring to a previous vector argument.
return D.getArgumentNumber() >= ArgTys.size() ||
!isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
- VectorType::getTruncatedElementVectorType(
+ VectorType::getHalfElementsVectorType(
cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
}
llvm_unreachable("unhandled");
@@ -2284,8 +2281,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
// know they are legal for the intrinsic!) get the intrinsic name through the
// usual means. This allows us to verify the mangling of argument types into
// the name.
- Assert1(Intrinsic::getName(ID, ArgTys) == IF->getName(),
- "Intrinsic name not mangled correctly for type arguments!", IF);
+ const std::string ExpectedName = Intrinsic::getName(ID, ArgTys);
+ Assert1(ExpectedName == IF->getName(),
+ "Intrinsic name not mangled correctly for type arguments! "
+ "Should be: " + ExpectedName, IF);
// If the intrinsic takes MDNode arguments, verify that they are either global
// or are local to *this* function.
@@ -2309,13 +2308,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(MD->getNumOperands() == 1,
"invalid llvm.dbg.declare intrinsic call 2", &CI);
if (!DisableDebugInfoVerifier)
- Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI));
+ Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI));
} break;
case Intrinsic::dbg_value: { //llvm.dbg.value
if (!DisableDebugInfoVerifier) {
Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)),
"invalid llvm.dbg.value intrinsic call 1", &CI);
- Finder.processValue(*Mod, cast<DbgValueInst>(&CI));
+ Finder.processValue(*M, cast<DbgValueInst>(&CI));
}
break;
}
@@ -2383,22 +2382,21 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
void Verifier::verifyDebugInfo() {
// Verify Debug Info.
if (!DisableDebugInfoVerifier) {
- for (DebugInfoFinder::iterator I = Finder.compile_unit_begin(),
- E = Finder.compile_unit_end(); I != E; ++I)
- Assert1(DICompileUnit(*I).Verify(), "DICompileUnit does not Verify!", *I);
- for (DebugInfoFinder::iterator I = Finder.subprogram_begin(),
- E = Finder.subprogram_end(); I != E; ++I)
- Assert1(DISubprogram(*I).Verify(), "DISubprogram does not Verify!", *I);
- for (DebugInfoFinder::iterator I = Finder.global_variable_begin(),
- E = Finder.global_variable_end(); I != E; ++I)
- Assert1(DIGlobalVariable(*I).Verify(),
- "DIGlobalVariable does not Verify!", *I);
- for (DebugInfoFinder::iterator I = Finder.type_begin(),
- E = Finder.type_end(); I != E; ++I)
- Assert1(DIType(*I).Verify(), "DIType does not Verify!", *I);
- for (DebugInfoFinder::iterator I = Finder.scope_begin(),
- E = Finder.scope_end(); I != E; ++I)
- Assert1(DIScope(*I).Verify(), "DIScope does not Verify!", *I);
+ for (DICompileUnit CU : Finder.compile_units()) {
+ Assert1(CU.Verify(), "DICompileUnit does not Verify!", CU);
+ }
+ for (DISubprogram S : Finder.subprograms()) {
+ Assert1(S.Verify(), "DISubprogram does not Verify!", S);
+ }
+ for (DIGlobalVariable GV : Finder.global_variables()) {
+ Assert1(GV.Verify(), "DIGlobalVariable does not Verify!", GV);
+ }
+ for (DIType T : Finder.types()) {
+ Assert1(T.Verify(), "DIType does not Verify!", T);
+ }
+ for (DIScope S : Finder.scopes()) {
+ Assert1(S.Verify(), "DIScope does not Verify!", S);
+ }
}
}
@@ -2406,37 +2404,84 @@ void Verifier::verifyDebugInfo() {
// Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
- return new Verifier(action);
+bool llvm::verifyFunction(const Function &f, raw_ostream *OS) {
+ Function &F = const_cast<Function &>(f);
+ assert(!F.isDeclaration() && "Cannot verify external functions");
+
+ raw_null_ostream NullStr;
+ Verifier V(OS ? *OS : NullStr);
+
+ // Note that this function's return value is inverted from what you would
+ // expect of a function called "verify".
+ return !V.verify(F);
}
+bool llvm::verifyModule(const Module &M, raw_ostream *OS) {
+ raw_null_ostream NullStr;
+ Verifier V(OS ? *OS : NullStr);
-/// verifyFunction - Check a function for errors, printing messages on stderr.
-/// Return true if the function is corrupt.
-///
-bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
- Function &F = const_cast<Function&>(f);
- assert(!F.isDeclaration() && "Cannot verify external functions");
+ bool Broken = false;
+ for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I->isDeclaration())
+ Broken |= !V.verify(*I);
- FunctionPassManager FPM(F.getParent());
- Verifier *V = new Verifier(action);
- FPM.add(V);
- FPM.doInitialization();
- FPM.run(F);
- return V->Broken;
+ // Note that this function's return value is inverted from what you would
+ // expect of a function called "verify".
+ return !V.verify(M) || Broken;
}
-/// verifyModule - Check a module for errors, printing messages on stderr.
-/// Return true if the module is corrupt.
-///
-bool llvm::verifyModule(const Module &M, VerifierFailureAction action,
- std::string *ErrorInfo) {
- PassManager PM;
- Verifier *V = new Verifier(action);
- PM.add(V);
- PM.run(const_cast<Module&>(M));
-
- if (ErrorInfo && V->Broken)
- *ErrorInfo = V->MessagesStr.str();
- return V->Broken;
+namespace {
+struct VerifierLegacyPass : public FunctionPass {
+ static char ID;
+
+ Verifier V;
+ bool FatalErrors;
+
+ VerifierLegacyPass() : FunctionPass(ID), FatalErrors(true) {
+ initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+ explicit VerifierLegacyPass(bool FatalErrors)
+ : FunctionPass(ID), V(dbgs()), FatalErrors(FatalErrors) {
+ initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ if (!V.verify(F) && FatalErrors)
+ report_fatal_error("Broken function found, compilation aborted!");
+
+ return false;
+ }
+
+ bool doFinalization(Module &M) override {
+ if (!V.verify(M) && FatalErrors)
+ report_fatal_error("Broken module found, compilation aborted!");
+
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+}
+
+char VerifierLegacyPass::ID = 0;
+INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)
+
+FunctionPass *llvm::createVerifierPass(bool FatalErrors) {
+ return new VerifierLegacyPass(FatalErrors);
+}
+
+PreservedAnalyses VerifierPass::run(Module *M) {
+ if (verifyModule(*M, &dbgs()) && FatalErrors)
+ report_fatal_error("Broken module found, compilation aborted!");
+
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses VerifierPass::run(Function *F) {
+ if (verifyFunction(*F, &dbgs()) && FatalErrors)
+ report_fatal_error("Broken function found, compilation aborted!");
+
+ return PreservedAnalyses::all();
}