X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FVerifier.cpp;h=36462388b380be68b6bdc32284378758b6735bfa;hb=18365506ebe3e28593cb36951f17f08e75712a29;hp=2005dbf584522e83b55487290c5e98b1d9667e02;hpb=9545a1797b99cad119d2dfaa975f6e95c745b62a;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 2005dbf5845..36462388b38 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1,10 +1,10 @@ //===-- Verifier.cpp - Implement the Module Verifier -------------*- C++ -*-==// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file defines the function verifier interface, that can be used for some @@ -41,6 +41,7 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/Writer.h" +#include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Pass.h" #include "llvm/Module.h" @@ -53,7 +54,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Support/CFG.h" #include "llvm/Support/InstVisitor.h" -#include "Support/STLExtras.h" +#include "llvm/ADT/STLExtras.h" #include #include #include @@ -67,22 +68,28 @@ namespace { // Anonymous namespace for class VerifierFailureAction action; // What to do if verification fails. Module *Mod; // Module we are verifying right now - DominatorSet *DS; // Dominator set, caution can be null! + ETForest *EF; // ET-Forest, caution can be null! std::stringstream msgs; // A stringstream to collect messages - Verifier() + /// 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. + std::set InstsInThisBlock; + + Verifier() : Broken(false), RealPass(true), action(AbortProcessAction), - DS(0), msgs( std::ios_base::app | std::ios_base::out ) {} + EF(0), msgs( std::ios::app | std::ios::out ) {} Verifier( VerifierFailureAction ctn ) - : Broken(false), RealPass(true), action(ctn), DS(0), - msgs( std::ios_base::app | std::ios_base::out ) {} - Verifier(bool AB ) - : Broken(false), RealPass(true), - action( AB ? AbortProcessAction : PrintMessageAction), DS(0), - msgs( std::ios_base::app | std::ios_base::out ) {} - Verifier(DominatorSet &ds) + : Broken(false), RealPass(true), action(ctn), EF(0), + msgs( std::ios::app | std::ios::out ) {} + Verifier(bool AB ) + : Broken(false), RealPass(true), + action( AB ? AbortProcessAction : PrintMessageAction), EF(0), + msgs( std::ios::app | std::ios::out ) {} + Verifier(ETForest &ef) : Broken(false), RealPass(false), action(PrintMessageAction), - DS(&ds), msgs( std::ios_base::app | std::ios_base::out ) {} + EF(&ef), msgs( std::ios::app | std::ios::out ) {} bool doInitialization(Module &M) { @@ -99,8 +106,9 @@ namespace { // Anonymous namespace for class bool runOnFunction(Function &F) { // Get dominator information if we are being run by PassManager - if (RealPass) DS = &getAnalysis(); + if (RealPass) EF = &getAnalysis(); visit(F); + InstsInThisBlock.clear(); // 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 @@ -120,8 +128,9 @@ namespace { // Anonymous namespace for class if (I->isExternal()) visitFunction(*I); } - for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - visitGlobalValue(*I); + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + visitGlobalVariable(*I); // If the module is broken, abort at this time. abortIfBroken(); @@ -131,7 +140,7 @@ namespace { // Anonymous namespace for class virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); if (RealPass) - AU.addRequired(); + AU.addRequired(); } /// abortIfBroken - If the module is broken and we are supposed to abort on @@ -164,12 +173,14 @@ namespace { // Anonymous namespace for class // Verification methods... void verifySymbolTable(SymbolTable &ST); void visitGlobalValue(GlobalValue &GV); + void visitGlobalVariable(GlobalVariable &GV); void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitShiftInst(ShiftInst &SI); - void visitVANextInst(VANextInst &VAN) { visitInstruction(VAN); } + void visitExtractElementInst(ExtractElementInst &EI); + void visitInsertElementInst(InsertElementInst &EI); void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } void visitCallInst(CallInst &CI); void visitGetElementPtrInst(GetElementPtrInst &GEP); @@ -215,7 +226,7 @@ namespace { // Anonymous namespace for class Broken = true; } - void CheckFailed( const std::string& Message, const Value* V1, + void CheckFailed( const std::string& Message, const Value* V1, const Type* T2, const Value* V3 = 0 ) { msgs << Message << "\n"; WriteValue(V1); @@ -255,12 +266,22 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { } } +void Verifier::visitGlobalVariable(GlobalVariable &GV) { + if (GV.hasInitializer()) + Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(), + "Global variable initializer type does not match global " + "variable type!", &GV); + + visitGlobalValue(GV); +} + + // verifySymbolTable - Verify that a function or module symbol table is ok // void Verifier::verifySymbolTable(SymbolTable &ST) { // Loop over all of the values in all type planes in the symbol table. - for (SymbolTable::plane_const_iterator PI = ST.plane_begin(), + for (SymbolTable::plane_const_iterator PI = ST.plane_begin(), PE = ST.plane_end(); PI != PE; ++PI) for (SymbolTable::value_const_iterator VI = PI->second.begin(), VE = PI->second.end(); VI != VE; ++VI) { @@ -276,7 +297,10 @@ void Verifier::verifySymbolTable(SymbolTable &ST) { // visitFunction - Verify that a function is ok. // void Verifier::visitFunction(Function &F) { - // Check function arguments... + Assert1(!F.isVarArg() || F.getCallingConv() == CallingConv::C, + "Varargs functions must have C calling conventions!", &F); + + // Check function arguments. const FunctionType *FT = F.getFunctionType(); unsigned NumArgs = F.getArgumentList().size(); @@ -289,12 +313,12 @@ void Verifier::visitFunction(Function &F) { // Check that the argument values match the function type for this function... unsigned i = 0; - for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++i) { + for (Function::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)); // Make sure no aggregates are passed by value. - Assert1(I->getType()->isFirstClassType(), + Assert1(I->getType()->isFirstClassType(), "Functions cannot take aggregates as arguments by value!", I); } @@ -312,12 +336,17 @@ void Verifier::visitFunction(Function &F) { // verifyBasicBlock - Verify that a basic block is well formed... // void Verifier::visitBasicBlock(BasicBlock &BB) { + InstsInThisBlock.clear(); + + // Ensure that basic blocks have terminators! + Assert1(BB.getTerminator(), "Basic Block does not have terminator!", &BB); + // Check constraints that this basic block imposes on all of the PHI nodes in // it. if (isa(BB.front())) { std::vector Preds(pred_begin(&BB), pred_end(&BB)); std::sort(Preds.begin(), Preds.end()); - PHINode *PN; + PHINode *PN; for (BasicBlock::iterator I = BB.begin(); (PN = dyn_cast(I));++I) { // Ensure that PHI nodes have at least one entry! @@ -327,7 +356,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { Assert1(PN->getNumIncomingValues() == Preds.size(), "PHINode should have one entry for each predecessor of its " "parent basic block!", PN); - + // Get and sort all incoming values in the PHI node... std::vector > Values; Values.reserve(PN->getNumIncomingValues()); @@ -335,7 +364,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { Values.push_back(std::make_pair(PN->getIncomingBlock(i), PN->getIncomingValue(i))); std::sort(Values.begin(), Values.end()); - + for (unsigned i = 0, e = Values.size(); i != e; ++i) { // Check to make sure that if there is more than one entry for a // particular basic block in this PHI node, that the incoming values are @@ -346,18 +375,15 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { "PHI node has multiple entries for the same basic block with " "different incoming values!", PN, Values[i].first, Values[i].second, Values[i-1].second); - + // Check to make sure that the predecessors and PHI node entries are // matched up. Assert3(Values[i].first == Preds[i], "PHI node entries do not match predecessors!", PN, - Values[i].first, Preds[i]); + Values[i].first, Preds[i]); } } } - - // Ensure that basic blocks have terminators! - Assert1(BB.getTerminator(), "Basic Block does not have terminator!", &BB); } void Verifier::visitTerminatorInst(TerminatorInst &I) { @@ -370,9 +396,9 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); if (RI.getNumOperands() == 0) - Assert1(F->getReturnType() == Type::VoidTy, - "Function returns no value, but ret instruction found that does!", - &RI); + Assert2(F->getReturnType() == Type::VoidTy, + "Found return instr that returns void in Function of non-void " + "return type!", &RI, F->getReturnType()); else Assert2(F->getReturnType() == RI.getOperand(0)->getType(), "Function return type does not match operand " @@ -401,6 +427,7 @@ void Verifier::visitSelectInst(SelectInst &SI) { "Select values must have identical types!", &SI); Assert1(SI.getTrueValue()->getType() == SI.getType(), "Select values must have same type as select instruction!", &SI); + visitInstruction(SI); } @@ -474,7 +501,9 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { // Check that logical operators are only used with integral operands. if (B.getOpcode() == Instruction::And || B.getOpcode() == Instruction::Or || B.getOpcode() == Instruction::Xor) { - Assert1(B.getType()->isIntegral(), + Assert1(B.getType()->isIntegral() || + (isa(B.getType()) && + cast(B.getType())->getElementType()->isIntegral()), "Logical operators only work with integral types!", &B); Assert1(B.getType() == B.getOperand(0)->getType(), "Logical operators must have same type for operands and result!", @@ -488,10 +517,11 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { Assert1(B.getType() == B.getOperand(0)->getType(), "Arithmetic operators must have same type for operands and result!", &B); - Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint(), - "Arithmetic operators must have integer or fp type!", &B); + Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() || + isa(B.getType()), + "Arithmetic operators must have integer, fp, or packed type!", &B); } - + visitInstruction(B); } @@ -505,6 +535,30 @@ void Verifier::visitShiftInst(ShiftInst &SI) { visitInstruction(SI); } +void Verifier::visitExtractElementInst(ExtractElementInst &EI) { + Assert1(isa(EI.getOperand(0)->getType()), + "First operand to extractelement must be packed type!", &EI); + Assert1(EI.getOperand(1)->getType() == Type::UIntTy, + "Second operand to extractelement must be uint type!", &EI); + Assert1(EI.getType() == + cast(EI.getOperand(0)->getType())->getElementType(), + "Extractelement return type must match " + "first operand element type!", &EI); + visitInstruction(EI); +} + +void Verifier::visitInsertElementInst(InsertElementInst &IE) { + Assert1(isa(IE.getOperand(0)->getType()), + "First operand to insertelement must be packed type!", &IE); + Assert1(IE.getOperand(1)->getType() == + cast(IE.getOperand(0)->getType())->getElementType(), + "Second operand to insertelement must match " + "first operand element type!", &IE); + Assert1(IE.getOperand(2)->getType() == Type::UIntTy, + "Third operand to insertelement must be uint type!", &IE); + visitInstruction(IE); +} + void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { const Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), @@ -535,14 +589,14 @@ void Verifier::visitStoreInst(StoreInst &SI) { /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { - BasicBlock *BB = I.getParent(); + BasicBlock *BB = I.getParent(); Assert1(BB, "Instruction not embedded in basic block!", &I); if (!isa(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 || - !DS->dominates(&BB->getParent()->getEntryBlock(), BB), + !EF->dominates(&BB->getParent()->getEntryBlock(), BB), "Only PHI nodes may reference their own value!", &I); } @@ -570,6 +624,7 @@ void Verifier::visitInstruction(Instruction &I) { for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { // Check to make sure that the "address of" an intrinsic function is never // taken. + Assert1(I.getOperand(i) != 0, "Instruction has null operand!", &I); if (Function *F = dyn_cast(I.getOperand(i))) { Assert1(!F->isIntrinsic() || (i == 0 && isa(I)), "Cannot take the address of an intrinsic!", &I); @@ -591,25 +646,26 @@ void Verifier::visitInstruction(Instruction &I) { else if (OpBlock == BB) { // If they are in the same basic block, make sure that the definition // comes before the use. - Assert2(DS->dominates(Op, &I) || - !DS->dominates(&BB->getParent()->getEntryBlock(), BB), + Assert2(InstsInThisBlock.count(Op) || + !EF->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } // Definition must dominate use unless use is unreachable! - Assert2(DS->dominates(OpBlock, BB) || - !DS->dominates(&BB->getParent()->getEntryBlock(), BB), + Assert2(EF->dominates(OpBlock, BB) || + !EF->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } else { // PHI nodes are more difficult than other nodes because they actually // "use" the value in the predecessor basic blocks they correspond to. BasicBlock *PredBB = cast(I.getOperand(i+1)); - Assert2(DS->dominates(OpBlock, PredBB) || - !DS->dominates(&BB->getParent()->getEntryBlock(), PredBB), + Assert2(EF->dominates(OpBlock, PredBB) || + !EF->dominates(&BB->getParent()->getEntryBlock(), PredBB), "Instruction does not dominate all uses!", Op, &I); } } } + InstsInThisBlock.insert(&I); } /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. @@ -627,10 +683,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(), "llvm.va_start intrinsic may only occur in function with variable" " args!", &CI); - NumArgs = 0; + NumArgs = 1; break; case Intrinsic::vaend: NumArgs = 1; break; - case Intrinsic::vacopy: NumArgs = 1; break; + case Intrinsic::vacopy: NumArgs = 2; break; case Intrinsic::returnaddress: case Intrinsic::frameaddress: @@ -687,18 +743,194 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { break; } - case Intrinsic::isunordered: + case Intrinsic::isunordered_f32: + Assert1(FT->getNumParams() == 2, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == Type::BoolTy, + "Return type is not bool!", IF); + Assert1(FT->getParamType(0) == FT->getParamType(1), + "Arguments must be of the same type!", IF); + Assert1(FT->getParamType(0) == Type::FloatTy, + "Arguments must be a 32-bit floating point type!", IF); + NumArgs = 2; + break; + + case Intrinsic::isunordered_f64: Assert1(FT->getNumParams() == 2, "Illegal # arguments for intrinsic function!", IF); Assert1(FT->getReturnType() == Type::BoolTy, "Return type is not bool!", IF); Assert1(FT->getParamType(0) == FT->getParamType(1), "Arguments must be of the same type!", IF); - Assert1(FT->getParamType(0)->isFloatingPoint(), - "Argument is not a floating point type!", IF); + Assert1(FT->getParamType(0) == Type::DoubleTy, + "Argument is not a 64-bit floating point type!", IF); NumArgs = 2; break; + case Intrinsic::readcyclecounter: + Assert1(FT->getNumParams() == 0, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == Type::ULongTy, + "Return type is not ulong!", IF); + NumArgs = 0; + break; + + case Intrinsic::bswap_i16: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getReturnType() == Type::UShortTy, + "Return type is not ushort!", IF); + NumArgs = 1; + break; + + case Intrinsic::bswap_i32: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getReturnType() == Type::UIntTy, + "Return type is not uint!", IF); + NumArgs = 1; + break; + + case Intrinsic::bswap_i64: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getReturnType() == Type::ULongTy, + "Return type is not ulong!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctpop_i8: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UByteTy, + "Argument is not ubyte!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctpop_i16: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UShortTy, + "Argument is not ushort!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctpop_i32: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctpop_i64: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctlz_i8: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF); + NumArgs = 1; + break; + + case Intrinsic::ctlz_i16: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UShortTy, + "Argument is not ushort!", IF); + NumArgs = 1; + break; + case Intrinsic::ctlz_i32: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); + NumArgs = 1; + break; + case Intrinsic::ctlz_i64: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF); + NumArgs = 1; + break; + case Intrinsic::cttz_i8: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF); + NumArgs = 1; + break; + case Intrinsic::cttz_i16: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UShortTy, + "Argument is not ushort!", IF); + NumArgs = 1; + break; + case Intrinsic::cttz_i32: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); + NumArgs = 1; + break; + case Intrinsic::cttz_i64: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type does not match source type", IF); + Assert1(FT->getParamType(0) == Type::ULongTy, "Argument Is not ulong!", IF); + NumArgs = 1; + break; + + case Intrinsic::sqrt_f32: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getParamType(0) == Type::FloatTy, + "Argument is not a 32-bit floating point type!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type is not the same as argument type!", IF); + NumArgs = 1; + break; + + case Intrinsic::sqrt_f64: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getParamType(0) == Type::DoubleTy, + "Argument is not a 64-bit floating point type!", IF); + Assert1(FT->getReturnType() == FT->getParamType(0), + "Return type is not the same as argument type!", IF); + NumArgs = 1; + break; + case Intrinsic::setjmp: NumArgs = 1; break; case Intrinsic::longjmp: NumArgs = 2; break; case Intrinsic::sigsetjmp: NumArgs = 2; break; @@ -723,24 +955,27 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::memcpy: NumArgs = 4; break; case Intrinsic::memmove: NumArgs = 4; break; case Intrinsic::memset: NumArgs = 4; break; - - case Intrinsic::alpha_ctlz: NumArgs = 1; break; - case Intrinsic::alpha_cttz: NumArgs = 1; break; - case Intrinsic::alpha_ctpop: NumArgs = 1; break; - case Intrinsic::alpha_umulh: NumArgs = 2; break; - case Intrinsic::alpha_vecop: NumArgs = 4; break; - case Intrinsic::alpha_pup: NumArgs = 3; break; - case Intrinsic::alpha_bytezap: NumArgs = 2; break; - case Intrinsic::alpha_bytemanip: NumArgs = 3; break; - case Intrinsic::alpha_dfpbop: NumArgs = 3; break; - case Intrinsic::alpha_dfpuop: NumArgs = 2; break; - case Intrinsic::alpha_unordered: NumArgs = 2; break; - case Intrinsic::alpha_uqtodfp: NumArgs = 2; break; - case Intrinsic::alpha_uqtosfp: NumArgs = 2; break; - case Intrinsic::alpha_dfptosq: NumArgs = 2; break; - case Intrinsic::alpha_sfptosq: NumArgs = 2; break; - - case Intrinsic::not_intrinsic: + + case Intrinsic::stacksave: + NumArgs = 0; + Assert1(CI.getType() == PointerType::get(Type::SByteTy), + "llvm.stacksave must return an sbyte*", &CI); + break; + case Intrinsic::stackrestore: + NumArgs = 1; + Assert1(CI.getOperand(1)->getType() == PointerType::get(Type::SByteTy), + "llvm.stackrestore must take an sbyte*", &CI); + Assert1(CI.getType() == Type::VoidTy, + "llvm.stackrestore return void", &CI); + break; + case Intrinsic::prefetch: NumArgs = 3; break; + case Intrinsic::pcmarker: + NumArgs = 1; + Assert1(isa(CI.getOperand(1)), + "First argument to llvm.pcmarker must be a constant!", &CI); + break; + + case Intrinsic::not_intrinsic: assert(0 && "Invalid intrinsic!"); NumArgs = 0; break; } @@ -759,11 +994,11 @@ FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) { } -// verifyFunction - Create +// verifyFunction - Create bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) { Function &F = const_cast(f); assert(!F.isExternal() && "Cannot verify external functions"); - + FunctionPassManager FPM(new ExistingModuleProvider(F.getParent())); Verifier *V = new Verifier(action); FPM.add(V);