aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-03-22 20:56:36 +0000
committerChris Lattner <sabre@nondot.org>2010-03-22 20:56:36 +0000
commit93dc92e412fd06250e46951bffb6040eca9baebd (patch)
tree8cfd6d2eb0dc5903f09f8a3fdc7223480d43759a /lib
parentb751418a3992c9da6f48c988f549c8e4c65e26f1 (diff)
Change intrinsic result type for void to store it as an empty list
instead of as a single element list with VoidTy. Now with a fix for the verifier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99206 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/VMCore/Verifier.cpp75
1 files changed, 41 insertions, 34 deletions
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index f141382569..552cc6e93c 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1683,13 +1683,11 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
/// 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,
@@ -1706,9 +1704,13 @@ 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;
@@ -1720,7 +1722,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
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;
}
@@ -1728,7 +1730,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(IntrinsicParam(ArgNo, NumRets) + " vector "
+ CheckFailed(IntrinsicParam(ArgNo, NumRetVals) + " vector "
"element bit-width is odd.", F);
return false;
}
@@ -1738,25 +1740,25 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
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;
}
@@ -1781,7 +1783,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
} 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;
}
@@ -1794,13 +1796,14 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
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;
}
@@ -1812,7 +1815,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
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;
}
@@ -1832,10 +1835,10 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
} 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;
}
@@ -1847,10 +1850,10 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
/// 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
@@ -1858,7 +1861,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
// 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;
}
@@ -1866,23 +1869,27 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
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) {
@@ -1891,8 +1898,8 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
break;
}
- if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo + RetNum,
- Suffix))
+ if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT,
+ ArgNo + NumRetVals, Suffix))
break;
}