/// 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
+ if (ArgNo >= NumRets)
return "Intrinsic parameter #" + utostr(ArgNo - NumRets);
+ if (NumRets == 1)
+ return "Intrinsic result type";
+ return "Intrinsic result type #" + utostr(ArgNo);
}
bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
const Type *RetTy = FTy->getReturnType();
const StructType *ST = dyn_cast<StructType>(RetTy);
- unsigned NumRets = 1;
- if (ST)
- NumRets = ST->getNumElements();
+ unsigned NumRetVals;
+ if (RetTy->isVoidTy())
+ NumRetVals = 0;
+ else if (ST)
+ NumRetVals = ST->getNumElements();
+ else
+ NumRetVals = 1;
if (VT < 0) {
int Match = ~VT;
TruncatedElementVectorType)) != 0) {
const IntegerType *IEltTy = dyn_cast<IntegerType>(EltTy);
if (!VTy || !IEltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"an integral vector type.", F);
return false;
}
// the type being matched against.
if ((Match & ExtendedElementVectorType) != 0) {
if ((IEltTy->getBitWidth() & 1) != 0) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " vector "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " vector "
"element bit-width is odd.", F);
return false;
}
Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
}
- if (Match <= static_cast<int>(NumRets - 1)) {
+ if (Match <= static_cast<int>(NumRetVals - 1)) {
if (ST)
RetTy = ST->getElementType(Match);
if (Ty != RetTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " does not "
"match return type.", F);
return false;
}
} else {
- if (Ty != FTy->getParamType(Match - NumRets)) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not "
- "match parameter %" + utostr(Match - NumRets) + ".", F);
+ if (Ty != FTy->getParamType(Match - NumRetVals)) {
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " does not "
+ "match parameter %" + utostr(Match - NumRetVals) + ".", F);
return false;
}
}
} else if (VT == MVT::iAny) {
if (!EltTy->isIntegerTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"an integer type.", F);
return false;
}
}
} else if (VT == MVT::fAny) {
if (!EltTy->isFloatingPointTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not "
"a floating-point type.", F);
return false;
}
Suffix += EVT::getEVT(EltTy).getEVTString();
} else if (VT == MVT::vAny) {
if (!VTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a vector type.", F);
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a vector type.",
+ F);
return false;
}
Suffix += ".v" + utostr(NumElts) + EVT::getEVT(EltTy).getEVTString();
} else if (VT == MVT::iPTR) {
if (!Ty->isPointerTy()) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a "
"pointer and a pointer is required.", F);
return false;
}
Suffix += ".p" + utostr(PTyp->getAddressSpace()) +
EVT::getEVT(PTyp->getElementType()).getEVTString();
} else {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is not a "
"pointer and a pointer is required.", F);
return false;
}
}
} else if (EVT((MVT::SimpleValueType)VT).getTypeForEVT(Ty->getContext()) !=
EltTy) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is wrong!", F);
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is wrong!", F);
return false;
} else if (EltTy != Ty) {
- CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is a vector "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " is a vector "
"and a scalar is required.", F);
return false;
}
/// Intrinsics.gen. This implements a little state machine that verifies the
/// prototype of intrinsics.
void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
- unsigned RetNum,
- unsigned ParamNum, ...) {
+ unsigned NumRetVals,
+ unsigned NumParams, ...) {
va_list VA;
- va_start(VA, ParamNum);
+ va_start(VA, NumParams);
const FunctionType *FTy = F->getFunctionType();
// For overloaded intrinsics, the Suffix of the function name must match the
// suffix, to be checked at the end.
std::string Suffix;
- if (FTy->getNumParams() + FTy->isVarArg() != ParamNum) {
+ if (FTy->getNumParams() + FTy->isVarArg() != NumParams) {
CheckFailed("Intrinsic prototype has incorrect number of arguments!", F);
return;
}
const Type *Ty = FTy->getReturnType();
const StructType *ST = dyn_cast<StructType>(Ty);
+ if (NumRetVals == 0 && !Ty->isVoidTy()) {
+ CheckFailed("Intrinsic should return void", F);
+ return;
+ }
+
// Verify the return types.
- if (ST && ST->getNumElements() != RetNum) {
+ if (ST && ST->getNumElements() != NumRetVals) {
CheckFailed("Intrinsic prototype has incorrect number of return types!", F);
return;
}
-
- for (unsigned ArgNo = 0; ArgNo < RetNum; ++ArgNo) {
+
+ for (unsigned ArgNo = 0; ArgNo != NumRetVals; ++ArgNo) {
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
if (ST) Ty = ST->getElementType(ArgNo);
-
if (!PerformTypeCheck(ID, F, Ty, VT, ArgNo, Suffix))
break;
}
// Verify the parameter types.
- for (unsigned ArgNo = 0; ArgNo < ParamNum; ++ArgNo) {
+ for (unsigned ArgNo = 0; ArgNo != NumParams; ++ArgNo) {
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
if (VT == MVT::isVoid && ArgNo > 0) {
break;
}
- if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo + RetNum,
- Suffix))
+ if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT,
+ ArgNo + NumRetVals, Suffix))
break;
}