diff options
Diffstat (limited to 'lib/VMCore/Verifier.cpp')
-rw-r--r-- | lib/VMCore/Verifier.cpp | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 5b9b2a5..47baef3 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -51,6 +51,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/Pass.h" @@ -117,7 +118,6 @@ 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? - bool RealPass; // Are we not being run by a PassManager? VerifierFailureAction action; // What to do if verification fails. Module *Mod; // Module we are verifying right now @@ -143,13 +143,13 @@ namespace { const Value *PersonalityFn; Verifier() - : FunctionPass(ID), Broken(false), RealPass(true), + : FunctionPass(ID), Broken(false), action(AbortProcessAction), Mod(0), Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) { initializeVerifierPass(*PassRegistry::getPassRegistry()); } explicit Verifier(VerifierFailureAction ctn) - : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0), + : FunctionPass(ID), Broken(false), action(ctn), Mod(0), Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) { initializeVerifierPass(*PassRegistry::getPassRegistry()); } @@ -158,17 +158,14 @@ namespace { Mod = &M; Context = &M.getContext(); - // If this is a real pass, in a pass manager, 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. - if (RealPass) - return abortIfBroken(); - return false; + // 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(); } bool runOnFunction(Function &F) { // Get dominator information if we are being run by PassManager - if (RealPass) DT = &getAnalysis<DominatorTree>(); + DT = &getAnalysis<DominatorTree>(); Mod = F.getParent(); if (!Context) Context = &F.getContext(); @@ -177,13 +174,9 @@ namespace { InstsInThisBlock.clear(); PersonalityFn = 0; - // If this is a real pass, in a pass manager, 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. - if (RealPass) - return abortIfBroken(); - - return false; + // 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(); } bool doFinalization(Module &M) { @@ -214,8 +207,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredID(PreVerifyID); - if (RealPass) - AU.addRequired<DominatorTree>(); + AU.addRequired<DominatorTree>(); } /// abortIfBroken - If the module is broken and we are supposed to abort on @@ -1369,6 +1361,25 @@ void Verifier::visitLoadInst(LoadInst &LI) { Assert1(LI.getSynchScope() == CrossThread, "Non-atomic load cannot have SynchronizationScope specified", &LI); } + + if (MDNode *Range = LI.getMetadata(LLVMContext::MD_range)) { + unsigned NumOperands = Range->getNumOperands(); + Assert1(NumOperands % 2 == 0, "Unfinished range!", Range); + unsigned NumRanges = NumOperands / 2; + Assert1(NumRanges >= 1, "It should have at least one range!", Range); + for (unsigned i = 0; i < NumRanges; ++i) { + ConstantInt *Low = dyn_cast<ConstantInt>(Range->getOperand(2*i)); + Assert1(Low, "The lower limit must be an integer!", Low); + ConstantInt *High = dyn_cast<ConstantInt>(Range->getOperand(2*i + 1)); + Assert1(High, "The upper limit must be an integer!", High); + Assert1(High->getType() == Low->getType() && + High->getType() == ElTy, "Range types must match load type!", + &LI); + Assert1(High->getValue() != Low->getValue(), "Range must not be empty!", + Range); + } + } + visitInstruction(LI); } @@ -1641,6 +1652,24 @@ void Verifier::visitInstruction(Instruction &I) { "Cannot take the address of an inline asm!", &I); } } + + if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpmath)) { + Assert1(I.getType()->isFPOrFPVectorTy(), + "fpmath requires a floating point result!", &I); + Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I); + Value *Op0 = MD->getOperand(0); + if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) { + APFloat Accuracy = CFP0->getValueAPF(); + Assert1(Accuracy.isNormal() && !Accuracy.isNegative(), + "fpmath accuracy not a positive number!", &I); + } else { + Assert1(false, "invalid fpmath accuracy!", &I); + } + } + + MDNode *MD = I.getMetadata(LLVMContext::MD_range); + Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I); + InstsInThisBlock.insert(&I); } |