}
}
+/// 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();
NumElts = VTy->getNumElements();
}
+ const Type *RetTy = FTy->getReturnType();
+ const StructType *ST = dyn_cast<StructType>(RetTy);
+ unsigned NumRets = 1;
+ if (ST)
+ NumRets = ST->getNumElements();
+
if (VT < 0) {
int Match = ~VT;
TruncatedElementVectorType)) != 0) {
const IntegerType *IEltTy = dyn_cast<IntegerType>(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;
}
// 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;
}
Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
}
- const Type *RetTy = FTy->getReturnType();
- const StructType *ST = dyn_cast<StructType>(RetTy);
- unsigned NumRets = 1;
-
- if (ST)
- NumRets = ST->getNumElements();
-
if (Match <= static_cast<int>(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;
}
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;
}
Suffix += MVT::getMVT(EltTy).getMVTString();
} else if (VT == MVT::iPTR) {
if (!isa<PointerType>(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)
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()) {
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;
break;
}
- if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo, Suffix))
+ if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo + RetNum,
+ Suffix))
break;
}