diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index f9ad41b2c42..47441032af9 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1375,6 +1375,20 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { } } +/// Produce a string to identify an intrinsic parameter or return value. +/// The ArgNo value numbers the return values from 0 to NumRets-1 and the +/// parameters beginning with NumRets. +/// +static std::string IntrinsicParam(unsigned ArgNo, unsigned NumRets) { + if (ArgNo < NumRets) { + if (NumRets == 1) + return "Intrinsic result type"; + else + return "Intrinsic result type #" + utostr(ArgNo); + } else + return "Intrinsic parameter #" + utostr(ArgNo - NumRets); +} + bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, int VT, unsigned ArgNo, std::string &Suffix) { const FunctionType *FTy = F->getFunctionType(); @@ -1387,6 +1401,12 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, NumElts = VTy->getNumElements(); } + const Type *RetTy = FTy->getReturnType(); + const StructType *ST = dyn_cast(RetTy); + unsigned NumRets = 1; + if (ST) + NumRets = ST->getNumElements(); + if (VT < 0) { int Match = ~VT; @@ -1397,7 +1417,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, TruncatedElementVectorType)) != 0) { const IntegerType *IEltTy = dyn_cast(EltTy); if (!VTy || !IEltTy) { - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " is not " + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not " "an integral vector type.", F); return false; } @@ -1405,7 +1425,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, // the type being matched against. if ((Match & ExtendedElementVectorType) != 0) { if ((IEltTy->getBitWidth() & 1) != 0) { - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " vector " + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " vector " "element bit-width is odd.", F); return false; } @@ -1415,37 +1435,26 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType); } - const Type *RetTy = FTy->getReturnType(); - const StructType *ST = dyn_cast(RetTy); - unsigned NumRets = 1; - - if (ST) - NumRets = ST->getNumElements(); - if (Match <= static_cast(NumRets - 1)) { if (ST) RetTy = ST->getElementType(Match); if (Ty != RetTy) { - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " does not " + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not " "match return type.", F); return false; } } else { if (Ty != FTy->getParamType(Match - 1)) { - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " does not " + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not " "match parameter %" + utostr(Match - 1) + ".", F); return false; } } } else if (VT == MVT::iAny) { if (!EltTy->isInteger()) { - if (ArgNo == 0) - CheckFailed("Intrinsic result type is not an integer type.", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " is not " - "an integer type.", F); - + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not " + "an integer type.", F); return false; } @@ -1461,17 +1470,16 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, switch (ID) { default: break; // Not everything needs to be checked. case Intrinsic::bswap: - if (GotBits < 16 || GotBits % 16 != 0) + if (GotBits < 16 || GotBits % 16 != 0) { CheckFailed("Intrinsic requires even byte width argument", F); + return false; + } break; } } else if (VT == MVT::fAny) { if (!EltTy->isFloatingPoint()) { - if (ArgNo == 0) - CheckFailed("Intrinsic result type is not a floating-point type.", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " is not " - "a floating-point type.", F); + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not " + "a floating-point type.", F); return false; } @@ -1483,12 +1491,9 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, Suffix += MVT::getMVT(EltTy).getMVTString(); } else if (VT == MVT::iPTR) { if (!isa(Ty)) { - if (ArgNo == 0) - CheckFailed("Intrinsic result type is not a " - "pointer and a pointer is required.", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " is not a " - "pointer and a pointer is required.", F); + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a " + "pointer and a pointer is required.", F); + return false; } } else if (VT == MVT::iPTRAny) { // Outside of TableGen, we don't distinguish iPTRAny (to any address space) @@ -1498,12 +1503,8 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, Suffix += ".p" + utostr(PTyp->getAddressSpace()) + MVT::getMVT(PTyp->getElementType()).getMVTString(); } else { - if (ArgNo == 0) - CheckFailed("Intrinsic result type is not a " - "pointer and a pointer is required.", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not a " - "pointer and a pointer is required.", F); + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a " + "pointer and a pointer is required.", F); return false; } } else if (MVT((MVT::SimpleValueType)VT).isVector()) { @@ -1521,19 +1522,12 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, return false; } } else if (MVT((MVT::SimpleValueType)VT).getTypeForMVT() != EltTy) { - if (ArgNo == 0) - CheckFailed("Intrinsic prototype has incorrect result type!", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is wrong!",F); - + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is wrong!", F); return false; } else if (EltTy != Ty) { - if (ArgNo == 0) - CheckFailed("Intrinsic result type is vector " - "and a scalar is required.", F); - else - CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is vector " - "and a scalar is required.", F); + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is a vector " + "and a scalar is required.", F); + return false; } return true; @@ -1587,7 +1581,8 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, break; } - if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo, Suffix)) + if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo + RetNum, + Suffix)) break; }