PreVerifier() : FunctionPass(&ID) { }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
// Check that the prerequisites for successful DominatorTree construction
// are satisfied.
bool runOnFunction(Function &F) {
GV.hasExternalWeakLinkage() ||
GV.hasGhostLinkage() ||
(isa<GlobalAlias>(GV) &&
- (GV.hasInternalLinkage() || GV.hasWeakLinkage())),
+ (GV.hasLocalLinkage() || GV.hasWeakLinkage())),
"Global is external, but doesn't have external or dllimport or weak linkage!",
&GV);
void Verifier::visitGlobalAlias(GlobalAlias &GA) {
Assert1(!GA.getName().empty(),
"Alias name cannot be empty!", &GA);
- Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
+ Assert1(GA.hasExternalLinkage() || GA.hasLocalLinkage() ||
GA.hasWeakLinkage(),
"Alias should have external or external weak linkage!", &GA);
Assert1(GA.getAliasee(),
}
void Verifier::visitSelectInst(SelectInst &SI) {
- if (const VectorType* vt
- = dyn_cast<VectorType>(SI.getCondition()->getType())) {
- Assert1( vt->getElementType() == Type::Int1Ty,
- "Select condition type must be vector of bool!", &SI);
- if (const VectorType* val_vt
- = dyn_cast<VectorType>(SI.getTrueValue()->getType())) {
- Assert1( vt->getNumElements() == val_vt->getNumElements(),
- "Select vector size != value vector size", &SI);
- } else {
- Assert1(0, "Vector select values must have vector types", &SI);
- }
- } else {
- Assert1(SI.getCondition()->getType() == Type::Int1Ty,
- "Select condition type must be bool!", &SI);
- }
- Assert1(SI.getTrueValue()->getType() == SI.getFalseValue()->getType(),
- "Select values must have identical types!", &SI);
+ Assert1(!SelectInst::areInvalidOperands(SI.getOperand(0), SI.getOperand(1),
+ SI.getOperand(2)),
+ "Invalid operands for select instruction!", &SI);
+
Assert1(SI.getTrueValue()->getType() == SI.getType(),
"Select values must have same type as select instruction!", &SI);
visitInstruction(SI);
Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I);
Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "trunc source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I);
visitInstruction(I);
// Get the size of the types in bits, we'll need this later
Assert1(SrcTy->isIntOrIntVector(), "ZExt only operates on integer", &I);
Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "zext source and destination must both be a vector or neither", &I);
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I);
Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "sext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I);
visitInstruction(I);
Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I);
Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "fptrunc source and destination must both be a vector or neither",&I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I);
visitInstruction(I);
Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I);
Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "fpext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I);
visitInstruction(I);
void Verifier::visitCallInst(CallInst &CI) {
VerifyCallSite(&CI);
- if (Function *F = CI.getCalledFunction()) {
+ if (Function *F = CI.getCalledFunction())
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicFunctionCall(ID, CI);
- }
}
void Verifier::visitInvokeInst(InvokeInst &II) {
InstsInThisBlock.insert(&I);
}
+// Flags used by TableGen to mark intrinsic parameters with the
+// LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes.
+static const unsigned ExtendedElementVectorType = 0x40000000;
+static const unsigned TruncatedElementVectorType = 0x20000000;
+
/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
///
void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
switch (ID) {
default:
break;
- case Intrinsic::memcpy_i32:
- case Intrinsic::memcpy_i64:
- case Intrinsic::memmove_i32:
- case Intrinsic::memmove_i64:
- case Intrinsic::memset_i32:
- case Intrinsic::memset_i64:
+ case Intrinsic::dbg_declare: // llvm.dbg.declare
+ if (Constant *C = dyn_cast<Constant>(CI.getOperand(1)))
+ Assert1(C && !isa<ConstantPointerNull>(C),
+ "invalid llvm.dbg.declare intrinsic call", &CI);
+ break;
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset:
Assert1(isa<ConstantInt>(CI.getOperand(4)),
"alignment argument of memory intrinsics must be a constant int",
&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();
unsigned NumElts = 0;
const Type *EltTy = Ty;
- if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ const VectorType *VTy = dyn_cast<VectorType>(Ty);
+ if (VTy) {
EltTy = VTy->getElementType();
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;
- const Type *RetTy = FTy->getReturnType();
- const StructType *ST = dyn_cast<StructType>(RetTy);
- unsigned NumRets = 1;
- if (ST)
- NumRets = ST->getNumElements();
+ // Check flags that indicate a type that is an integral vector type with
+ // elements that are larger or smaller than the elements of the matched
+ // type.
+ if ((Match & (ExtendedElementVectorType |
+ TruncatedElementVectorType)) != 0) {
+ const IntegerType *IEltTy = dyn_cast<IntegerType>(EltTy);
+ if (!VTy || !IEltTy) {
+ CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
+ "an integral vector type.", F);
+ return false;
+ }
+ // Adjust the current Ty (in the opposite direction) rather than
+ // the type being matched against.
+ if ((Match & ExtendedElementVectorType) != 0) {
+ if ((IEltTy->getBitWidth() & 1) != 0) {
+ CheckFailed(IntrinsicParam(ArgNo, NumRets) + " vector "
+ "element bit-width is odd.", F);
+ return false;
+ }
+ Ty = VectorType::getTruncatedElementVectorType(VTy);
+ } else
+ Ty = VectorType::getExtendedElementVectorType(VTy);
+ Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
+ }
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;
}