X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FVerifier.cpp;h=0ce7d4c27ce921395c97491ae6f23f28ad33a560;hb=719de53742167ca3f0e6b2efafb6eac18bd90452;hp=575bb82df756cd411a67061d0440292fc814bc0b;hpb=ab3b77834c9232e4c13acb29afe1920b97c5a20b;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 575bb82df75..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/ParamAttrsList.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 ) {} @@ -264,7 +266,7 @@ namespace { // Anonymous namespace for class unsigned Count, ...); void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, bool isReturnValue, const Value *V); - void VerifyFunctionAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, + void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs, const Value *V); void WriteValue(const Value *V) { @@ -306,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) \ @@ -368,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 && @@ -378,7 +381,11 @@ 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); } @@ -394,11 +401,11 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, if (isReturnValue) { ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly; - Assert1(!RetI, "Attribute " + ParamAttrsList::getParamAttrsText(RetI) + + Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) + "does not apply to return values!", V); } else { ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly; - Assert1(!ParmI, "Attribute " + ParamAttrsList::getParamAttrsText(ParmI) + + Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) + "only applies to return values!", V); } @@ -406,37 +413,44 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i]; Assert1(!(MutI & (MutI - 1)), "Attributes " + - ParamAttrsList::getParamAttrsText(MutI) + "are incompatible!", V); + ParamAttr::getAsString(MutI) + "are incompatible!", V); } ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty); Assert1(!TypeI, "Wrong type for attribute " + - ParamAttrsList::getParamAttrsText(TypeI), V); + ParamAttr::getAsString(TypeI), V); } // VerifyFunctionAttrs - Check parameter attributes against a function type. // The value V is printed in error messages. void Verifier::VerifyFunctionAttrs(const FunctionType *FT, - const ParamAttrsList *Attrs, + const PAListPtr &Attrs, const Value *V) { - if (!Attrs) + if (Attrs.isEmpty()) return; bool SawNest = false; - for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { + const ParamAttrsWithIndex &Attr = Attrs.getSlot(i); - VerifyAttrs(Attr, FT->getParamType(Idx-1), !Idx, 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); } } @@ -455,14 +469,13 @@ void Verifier::visitFunction(Function &F) { 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. @@ -577,22 +590,35 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); unsigned N = RI.getNumOperands(); - if (N == 0) - Assert2(F->getReturnType() == Type::VoidTy, + 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 if (N == 1) - Assert2(F->getReturnType() == RI.getOperand(0)->getType(), - "Function return type does not match operand " - "type of return inst!", &RI, F->getReturnType()); - else if (const StructType *STy = dyn_cast(F->getReturnType())) { - for (unsigned i = 0; i < N; i++) + 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 - Assert1(0, "Invalid return type!", &RI); - + } 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); @@ -711,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); @@ -733,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); @@ -749,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); @@ -768,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); @@ -870,25 +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. 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) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + ParameterAttributes Attr = Attrs.getParamAttrs(Idx); VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I); ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible; - Assert1(!VArgI, "Attribute " + ParamAttrsList::getParamAttrsText(VArgI) + + Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) + "cannot be used for vararg call arguments!", I); } @@ -1016,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, @@ -1051,8 +1091,14 @@ void Verifier::visitAllocationInst(AllocationInst &AI) { } void Verifier::visitGetResultInst(GetResultInst &GRI) { - Assert1(GRI.isValidOperands(GRI.getAggregateValue(), GRI.getIndex()), + 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); } @@ -1193,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 { @@ -1240,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); @@ -1267,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; @@ -1297,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()) @@ -1317,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()) { @@ -1369,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) @@ -1380,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 @@ -1422,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); }