X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FVerifier.cpp;h=0ce7d4c27ce921395c97491ae6f23f28ad33a560;hb=719de53742167ca3f0e6b2efafb6eac18bd90452;hp=e42109e0f30abf82e708d8fff33aa3d3cc9ad7f6;hpb=623a389f623dfef44f07211bd12fbd2a93db09e3;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e42109e0f30..0ce7d4c27ce 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -21,7 +21,7 @@ // * The code is in valid SSA form // * It should be illegal to put a label into any other type (like a structure) // or to return one. [except constant arrays!] -// * Only phi nodes can be self referential: 'add int %0, %0 ; :0' is bad +// * Only phi nodes can be self referential: 'add i32 %0, %0 ; :0' is bad // * PHI nodes must have an entry for each predecessor, with no extras. // * PHI nodes must be the first thing in a basic block, all grouped together // * PHI nodes must have at least one entry @@ -40,18 +40,17 @@ //===----------------------------------------------------------------------===// #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" -#include "llvm/ModuleProvider.h" -#include "llvm/ParameterAttributes.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Module.h" +#include "llvm/ModuleProvider.h" +#include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" @@ -93,11 +92,14 @@ namespace { // Anonymous namespace for class return false; } }; +} - char PreVerifier::ID = 0; - RegisterPass PreVer("preverify", "Preliminary module verification"); - const PassInfo *PreVerifyID = PreVer.getPassInfo(); +char PreVerifier::ID = 0; +static RegisterPass +PreVer("preverify", "Preliminary module verification"); +static const PassInfo *const PreVerifyID = &PreVer; +namespace { struct VISIBILITY_HIDDEN Verifier : public FunctionPass, InstVisitor { static char ID; // Pass ID, replacement for typeid @@ -119,16 +121,16 @@ namespace { // Anonymous namespace for class : FunctionPass((intptr_t)&ID), Broken(false), RealPass(true), action(AbortProcessAction), DT(0), msgs( std::ios::app | std::ios::out ) {} - Verifier( VerifierFailureAction ctn ) + explicit Verifier(VerifierFailureAction ctn) : FunctionPass((intptr_t)&ID), Broken(false), RealPass(true), action(ctn), DT(0), msgs( std::ios::app | std::ios::out ) {} - Verifier(bool AB ) + explicit Verifier(bool AB) : FunctionPass((intptr_t)&ID), Broken(false), RealPass(true), action( AB ? AbortProcessAction : PrintMessageAction), DT(0), msgs( std::ios::app | std::ios::out ) {} - Verifier(DominatorTree &dt) + explicit Verifier(DominatorTree &dt) : FunctionPass((intptr_t)&ID), Broken(false), RealPass(false), action(PrintMessageAction), DT(&dt), msgs( std::ios::app | std::ios::out ) {} @@ -257,12 +259,15 @@ namespace { // Anonymous namespace for class void visitUserOp2(Instruction &I) { visitUserOp1(I); } void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); void visitAllocationInst(AllocationInst &AI); + void visitGetResultInst(GetResultInst &GRI); void VerifyCallSite(CallSite CS); void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, unsigned Count, ...); - void VerifyParamAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, - const Value *V); + void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, + bool isReturnValue, const Value *V); + void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs, + const Value *V); void WriteValue(const Value *V) { if (!V) return; @@ -303,11 +308,10 @@ namespace { // Anonymous namespace for class Broken = true; } }; - - char Verifier::ID = 0; - RegisterPass X("verify", "Module Verifier"); } // End anonymous namespace +char Verifier::ID = 0; +static RegisterPass X("verify", "Module Verifier"); // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ @@ -365,9 +369,11 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() || GA.hasWeakLinkage(), "Alias should have external or external weak linkage!", &GA); + Assert1(GA.getAliasee(), + "Aliasee cannot be NULL!", &GA); Assert1(GA.getType() == GA.getAliasee()->getType(), "Alias and aliasee types should match!", &GA); - + if (!isa(GA.getAliasee())) { const ConstantExpr *CE = dyn_cast(GA.getAliasee()); Assert1(CE && CE->getOpcode() == Instruction::BitCast && @@ -375,56 +381,76 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { "Aliasee should be either GlobalValue or bitcast of GlobalValue", &GA); } - + + const GlobalValue* Aliasee = GA.resolveAliasedGlobal(); + Assert1(Aliasee, + "Aliasing chain should end with function or global variable", &GA); + visitGlobalValue(GA); } void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) { } -// VerifyParamAttrs - Check parameter attributes against a function type. +// VerifyAttrs - Check the given parameter attributes for an argument or return +// value of the specified type. The value V is printed in error messages. +void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, + bool isReturnValue, const Value *V) { + if (Attrs == ParamAttr::None) + return; + + if (isReturnValue) { + ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly; + Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) + + "does not apply to return values!", V); + } else { + ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly; + Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) + + "only applies to return values!", V); + } + + for (unsigned i = 0; + i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { + ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i]; + Assert1(!(MutI & (MutI - 1)), "Attributes " + + ParamAttr::getAsString(MutI) + "are incompatible!", V); + } + + ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty); + Assert1(!TypeI, "Wrong type for attribute " + + ParamAttr::getAsString(TypeI), V); +} + +// VerifyFunctionAttrs - Check parameter attributes against a function type. // The value V is printed in error messages. -void Verifier::VerifyParamAttrs(const FunctionType *FT, - const ParamAttrsList *Attrs, - const Value *V) { - if (!Attrs) +void Verifier::VerifyFunctionAttrs(const FunctionType *FT, + const PAListPtr &Attrs, + const Value *V) { + if (Attrs.isEmpty()) return; bool SawNest = false; - for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { - uint16_t Attr = Attrs->getParamAttrs(Idx); - - if (!Idx) { - uint16_t RetI = Attr & ParamAttr::ParameterOnly; - Assert1(!RetI, "Attribute " + Attrs->getParamAttrsText(RetI) + - "does not apply to return values!", V); - } else { - uint16_t ParmI = Attr & ParamAttr::ReturnOnly; - Assert1(!ParmI, "Attribute " + Attrs->getParamAttrsText(ParmI) + - "only applies to return values!", V); - } - - for (unsigned i = 0; - i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { - uint16_t MutI = Attr & ParamAttr::MutuallyIncompatible[i]; - Assert1(!(MutI & (MutI - 1)), "Attributes " + - Attrs->getParamAttrsText(MutI) + "are incompatible!", V); - } + for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { + const ParamAttrsWithIndex &Attr = Attrs.getSlot(i); - uint16_t TypeI = - Attr & ParamAttr::typeIncompatible(FT->getParamType(Idx-1)); - Assert1(!TypeI, "Wrong type for attribute " + - Attrs->getParamAttrsText(TypeI), V); + const Type *Ty; + if (Attr.Index == 0) + Ty = FT->getReturnType(); + else if (Attr.Index-1 < FT->getNumParams()) + Ty = FT->getParamType(Attr.Index-1); + else + break; // VarArgs attributes, don't verify. + + VerifyAttrs(Attr.Attrs, Ty, Attr.Index == 0, V); - if (Attr & ParamAttr::Nest) { + if (Attr.Attrs & ParamAttr::Nest) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); SawNest = true; } - if (Attr & ParamAttr::StructRet) { - Assert1(Idx == 1, "Attribute sret not on first parameter!", V); - } + if (Attr.Attrs & ParamAttr::StructRet) + Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V); } } @@ -439,21 +465,21 @@ void Verifier::visitFunction(Function &F) { "# formal arguments must match # of arguments for function type!", &F, FT); Assert1(F.getReturnType()->isFirstClassType() || - F.getReturnType() == Type::VoidTy, + F.getReturnType() == Type::VoidTy || + isa(F.getReturnType()), "Functions cannot return aggregate values!", &F); - Assert1(!F.isStructReturn() || FT->getReturnType() == Type::VoidTy, - "Invalid struct-return function!", &F); + Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy, + "Invalid struct return type!", &F); - const ParamAttrsList *Attrs = F.getParamAttrs(); + const PAListPtr &Attrs = F.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(), "Attributes after last parameter!", &F); // Check function attributes. - VerifyParamAttrs(FT, Attrs, &F); + VerifyFunctionAttrs(FT, Attrs, &F); // Check that this function meets the restrictions on this calling convention. switch (F.getCallingConv()) { @@ -563,15 +589,36 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); - if (RI.getNumOperands() == 0) - Assert2(F->getReturnType() == Type::VoidTy, + unsigned N = RI.getNumOperands(); + if (F->getReturnType() == Type::VoidTy) + Assert2(N == 0, "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 " - "type of return inst!", &RI, F->getReturnType()); - + else if (N == 1 && F->getReturnType() == RI.getOperand(0)->getType()) { + // Exactly one return value and it matches the return type. Good. + } else if (const StructType *STy = dyn_cast(F->getReturnType())) { + // The return type is a struct; check for multiple return values. + Assert2(STy->getNumElements() == N, + "Incorrect number of return values in ret instruction!", + &RI, F->getReturnType()); + for (unsigned i = 0; i != N; ++i) + Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(), + "Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } else if (const ArrayType *ATy = dyn_cast(F->getReturnType())) { + // The return type is an array; check for multiple return values. + Assert2(ATy->getNumElements() == N, + "Incorrect number of return values in ret instruction!", + &RI, F->getReturnType()); + for (unsigned i = 0; i != N; ++i) + Assert2(ATy->getElementType() == RI.getOperand(i)->getType(), + "Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } else { + CheckFailed("Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } + // Check to make sure that the return value has necessary properties for // terminators... visitTerminatorInst(RI); @@ -690,15 +737,19 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa(SrcTy); + bool DstVec = isa(DestTy); - Assert1(SrcVec == DstVec,"UIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"UIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"UIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "UIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "UIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "UIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast(SrcTy)->getNumElements() == cast(DestTy)->getNumElements(), + Assert1(cast(SrcTy)->getNumElements() == + cast(DestTy)->getNumElements(), "UIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -712,12 +763,16 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) { bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; bool DstVec = DestTy->getTypeID() == Type::VectorTyID; - Assert1(SrcVec == DstVec,"SIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"SIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"SIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "SIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "SIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "SIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast(SrcTy)->getNumElements() == cast(DestTy)->getNumElements(), + Assert1(cast(SrcTy)->getNumElements() == + cast(DestTy)->getNumElements(), "SIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -728,15 +783,18 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa(SrcTy); + bool DstVec = isa(DestTy); - Assert1(SrcVec == DstVec,"FPToUI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToUI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToUI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToUI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToUI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast(SrcTy)->getNumElements() == cast(DestTy)->getNumElements(), + Assert1(cast(SrcTy)->getNumElements() == + cast(DestTy)->getNumElements(), "FPToUI source and dest vector length mismatch", &I); visitInstruction(I); @@ -747,15 +805,19 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa(SrcTy); + bool DstVec = isa(DestTy); - Assert1(SrcVec == DstVec,"FPToSI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToSI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToSI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToSI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), + "FPToSI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToSI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast(SrcTy)->getNumElements() == cast(DestTy)->getNumElements(), + Assert1(cast(SrcTy)->getNumElements() == + cast(DestTy)->getNumElements(), "FPToSI source and dest vector length mismatch", &I); visitInstruction(I); @@ -849,22 +911,24 @@ void Verifier::VerifyCallSite(CallSite CS) { "Call parameter type does not match function signature!", CS.getArgument(i), FTy->getParamType(i), I); - const ParamAttrsList *Attrs = CS.getParamAttrs(); + const PAListPtr &Attrs = CS.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= CS.arg_size()), - "Attributes after last argument!", I); + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(), + "Attributes after last parameter!", I); // Verify call attributes. - VerifyParamAttrs(FTy, Attrs, I); + VerifyFunctionAttrs(FTy, Attrs, I); - if (Attrs && FTy->isVarArg()) + if (FTy->isVarArg()) // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { - uint16_t Attr = Attrs->getParamAttrs(Idx); - uint16_t VArgI = Attr & ~ParamAttr::VarArgsCompatible; - Assert1(!VArgI, "Attribute " + Attrs->getParamAttrsText(VArgI) + + ParameterAttributes Attr = Attrs.getParamAttrs(Idx); + + VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I); + + ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible; + Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) + "cannot be used for vararg call arguments!", I); } @@ -992,7 +1056,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { SmallVector Idxs(GEP.idx_begin(), GEP.idx_end()); const Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), - Idxs.begin(), Idxs.end(), true); + Idxs.begin(), Idxs.end()); Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP); Assert2(isa(GEP.getType()) && cast(GEP.getType())->getElementType() == ElTy, @@ -1017,12 +1081,27 @@ void Verifier::visitStoreInst(StoreInst &SI) { } void Verifier::visitAllocationInst(AllocationInst &AI) { - const PointerType *Ptr = AI.getType(); - Assert(Ptr->getAddressSpace() == 0, - "Allocation instruction pointer not in the generic address space!"); + const 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", + &AI); visitInstruction(AI); } +void Verifier::visitGetResultInst(GetResultInst &GRI) { + Assert1(GetResultInst::isValidOperands(GRI.getAggregateValue(), + GRI.getIndex()), + "Invalid GetResultInst operands!", &GRI); + Assert1(isa(GRI.getAggregateValue()) || + isa(GRI.getAggregateValue()) || + isa(GRI.getAggregateValue()), + "GetResultInst operand must be a call/invoke/undef!", &GRI); + + visitInstruction(GRI); +} + /// verifyInstruction - Verify that an instruction is well formed. /// @@ -1037,6 +1116,11 @@ void Verifier::visitInstruction(Instruction &I) { !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Only PHI nodes may reference their own value!", &I); } + + // Verify that if this is a terminator that it is at the end of the block. + if (isa(I)) + Assert1(BB->getTerminator() == &I, "Terminator not at end of block!", &I); + // Check that void typed values don't have names Assert1(I.getType() != Type::VoidTy || !I.hasName(), @@ -1044,7 +1128,9 @@ void Verifier::visitInstruction(Instruction &I) { // Check that the return value of the instruction is either void or a legal // value type. - Assert1(I.getType() == Type::VoidTy || I.getType()->isFirstClassType(), + Assert1(I.getType() == Type::VoidTy || I.getType()->isFirstClassType() + || ((isa(I) || isa(I)) + && isa(I.getType())), "Instruction returns a non-scalar type!", &I); // Check that all uses of the instruction, if they are instructions @@ -1064,9 +1150,23 @@ void Verifier::visitInstruction(Instruction &I) { // Check to make sure that only first-class-values are operands to // instructions. - Assert1(I.getOperand(i)->getType()->isFirstClassType(), - "Instruction operands must be first-class values!", &I); - + if (!I.getOperand(i)->getType()->isFirstClassType()) { + if (isa(I) || isa(I)) + Assert1(isa(I.getOperand(i)->getType()), + "Invalid ReturnInst operands!", &I); + else if (isa(I) || isa(I)) { + if (const PointerType *PT = dyn_cast + (I.getOperand(i)->getType())) { + const Type *ETy = PT->getElementType(); + Assert1(isa(ETy), "Invalid CallInst operands!", &I); + } + else + Assert1(0, "Invalid CallInst operands!", &I); + } + else + Assert1(0, "Instruction operands must be first-class values!", &I); + } + if (Function *F = dyn_cast(I.getOperand(i))) { // Check to make sure that the "address of" an intrinsic function is never // taken. @@ -1139,7 +1239,7 @@ void Verifier::visitInstruction(Instruction &I) { } // Definition must dominate use unless use is unreachable! - Assert2(DT->dominates(OpBlock, BB) || + Assert2(DT->dominates(Op, &I) || !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } else { @@ -1186,8 +1286,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "Intrinsic parameter #1 is not i8**.", &CI); Assert1(CI.getOperand(2)->getType() == PtrTy, "Intrinsic parameter #2 is not i8*.", &CI); - Assert1(isa( - IntrinsicInst::StripPointerCasts(CI.getOperand(1))), + Assert1(isa(CI.getOperand(1)->stripPointerCasts()), "llvm.gcroot parameter #1 must be an alloca.", &CI); Assert1(isa(CI.getOperand(2)), "llvm.gcroot parameter #2 must be a constant.", &CI); @@ -1213,7 +1312,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { &CI); } break; case Intrinsic::init_trampoline: - Assert1(isa(IntrinsicInst::StripPointerCasts(CI.getOperand(2))), + Assert1(isa(CI.getOperand(2)->stripPointerCasts()), "llvm.init_trampoline parameter #2 must resolve to a function.", &CI); break; @@ -1243,7 +1342,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, // Note that "arg#0" is the return type. for (unsigned ArgNo = 0; ArgNo < Count; ++ArgNo) { - MVT::ValueType VT = va_arg(VA, MVT::ValueType); + int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative. if (VT == MVT::isVoid && ArgNo > 0) { if (!FTy->isVarArg()) @@ -1263,8 +1362,8 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, EltTy = VTy->getElementType(); NumElts = VTy->getNumElements(); } - - if ((int)VT < 0) { + + if (VT < 0) { int Match = ~VT; if (Match == 0) { if (Ty != FTy->getReturnType()) { @@ -1315,7 +1414,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Suffix += "."; if (EltTy != Ty) Suffix += "v" + utostr(NumElts); - Suffix += MVT::getValueTypeString(MVT::getValueType(EltTy)); + Suffix += MVT::getMVT(EltTy).getMVTString(); } else if (VT == MVT::iPTR) { if (!isa(Ty)) { if (ArgNo == 0) @@ -1326,19 +1425,20 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, "pointer and a pointer is required.", F); break; } - } else if (MVT::isVector(VT)) { + } else if (MVT((MVT::SimpleValueType)VT).isVector()) { + MVT VVT = MVT((MVT::SimpleValueType)VT); // If this is a vector argument, verify the number and type of elements. - if (MVT::getVectorElementType(VT) != MVT::getValueType(EltTy)) { + if (VVT.getVectorElementType() != MVT::getMVT(EltTy)) { CheckFailed("Intrinsic prototype has incorrect vector element type!", F); break; } - if (MVT::getVectorNumElements(VT) != NumElts) { + if (VVT.getVectorNumElements() != NumElts) { CheckFailed("Intrinsic prototype has incorrect number of " "vector elements!",F); break; } - } else if (MVT::getTypeForValueType(VT) != EltTy) { + } else if (MVT((MVT::SimpleValueType)VT).getTypeForMVT() != EltTy) { if (ArgNo == 0) CheckFailed("Intrinsic prototype has incorrect result type!", F); else @@ -1368,6 +1468,10 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, F->getName().substr(Name.length()) + "'. It should be '" + Suffix + "'", F); } + + // Check parameter attributes. + Assert1(F->getParamAttrs() == Intrinsic::getParamAttrs(ID), + "Intrinsic has wrong parameter attributes!", F); }