//===----------------------------------------------------------------------===//
#include "llvm/Analysis/Verifier.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Assembly/Writer.h"
#include "llvm/CallingConv.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
+#include "llvm/InstVisitor.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
SmallVectorImpl<Type*> &ArgTys);
void VerifyParameterAttrs(Attributes Attrs, Type *Ty,
bool isReturnValue, const Value *V);
- void VerifyFunctionAttrs(FunctionType *FT, const AttrListPtr &Attrs,
+ void VerifyFunctionAttrs(FunctionType *FT, const AttributeSet &Attrs,
const Value *V);
void WriteValue(const Value *V) {
"Only global arrays can have appending linkage!", GVar);
}
- Assert1(!GV.hasLinkerPrivateWeakDefAutoLinkage() || GV.hasDefaultVisibility(),
- "linker_private_weak_def_auto can only have default visibility!",
+ Assert1(!GV.hasLinkOnceODRAutoHideLinkage() || GV.hasDefaultVisibility(),
+ "linkonce_odr_auto_hide can only have default visibility!",
&GV);
}
// value of the specified type. The value V is printed in error messages.
void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
bool isReturnValue, const Value *V) {
- if (Attrs == Attribute::None)
+ if (!Attrs.hasAttributes())
return;
- Attributes FnCheckAttr = Attrs & Attribute::FunctionOnly;
- Assert1(!FnCheckAttr, "Attribute " + Attribute::getAsString(FnCheckAttr) +
- " only applies to the function!", V);
-
- if (isReturnValue) {
- Attributes RetI = Attrs & Attribute::ParameterOnly;
- Assert1(!RetI, "Attribute " + Attribute::getAsString(RetI) +
- " does not apply to return values!", V);
- }
-
- for (unsigned i = 0;
- i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
- Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
- Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
- Attribute::getAsString(MutI) + " are incompatible!", V);
- }
-
- Attributes TypeI = Attrs & Attribute::typeIncompatible(Ty);
- Assert1(!TypeI, "Wrong type for attribute " +
- Attribute::getAsString(TypeI), V);
-
- Attributes ByValI = Attrs & Attribute::ByVal;
- if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
- Assert1(!ByValI || PTy->getElementType()->isSized(),
- "Attribute " + Attribute::getAsString(ByValI) +
- " does not support unsized types!", V);
- } else {
- Assert1(!ByValI,
- "Attribute " + Attribute::getAsString(ByValI) +
- " only applies to parameters with pointer type!", V);
- }
+ Assert1(!Attrs.hasFunctionOnlyAttrs(),
+ "Some attributes in '" + Attrs.getAsString() +
+ "' only apply to functions!", V);
+
+ if (isReturnValue)
+ Assert1(!Attrs.hasParameterOnlyAttrs(),
+ "Attributes 'byval', 'nest', 'sret', and 'nocapture' "
+ "do not apply to return values!", V);
+
+ // Check for mutually incompatible attributes.
+ Assert1(!((Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::Nest)) ||
+ (Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::StructRet)) ||
+ (Attrs.hasAttribute(Attributes::Nest) &&
+ Attrs.hasAttribute(Attributes::StructRet))), "Attributes "
+ "'byval, nest, and sret' are incompatible!", V);
+
+ Assert1(!((Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::Nest)) ||
+ (Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::InReg)) ||
+ (Attrs.hasAttribute(Attributes::Nest) &&
+ Attrs.hasAttribute(Attributes::InReg))), "Attributes "
+ "'byval, nest, and inreg' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::ZExt) &&
+ Attrs.hasAttribute(Attributes::SExt)), "Attributes "
+ "'zeroext and signext' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::ReadNone) &&
+ Attrs.hasAttribute(Attributes::ReadOnly)), "Attributes "
+ "'readnone and readonly' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::NoInline) &&
+ Attrs.hasAttribute(Attributes::AlwaysInline)), "Attributes "
+ "'noinline and alwaysinline' are incompatible!", V);
+
+ Assert1(!AttrBuilder(Attrs).
+ hasAttributes(Attributes::typeIncompatible(Ty)),
+ "Wrong types for attribute: " +
+ Attributes::typeIncompatible(Ty).getAsString(), V);
+
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ Assert1(!Attrs.hasAttribute(Attributes::ByVal) ||
+ PTy->getElementType()->isSized(),
+ "Attribute 'byval' does not support unsized types!", V);
+ else
+ Assert1(!Attrs.hasAttribute(Attributes::ByVal),
+ "Attribute 'byval' only applies to parameters with pointer type!",
+ V);
}
// VerifyFunctionAttrs - Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::VerifyFunctionAttrs(FunctionType *FT,
- const AttrListPtr &Attrs,
+ const AttributeSet &Attrs,
const Value *V) {
if (Attrs.isEmpty())
return;
VerifyParameterAttrs(Attr.Attrs, Ty, Attr.Index == 0, V);
- if (Attr.Attrs & Attribute::Nest) {
+ if (Attr.Attrs.hasAttribute(Attributes::Nest)) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
- if (Attr.Attrs & Attribute::StructRet)
+ if (Attr.Attrs.hasAttribute(Attributes::StructRet))
Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V);
}
Attributes FAttrs = Attrs.getFnAttributes();
- Attributes NotFn = FAttrs & (~Attribute::FunctionOnly);
- Assert1(!NotFn, "Attribute " + Attribute::getAsString(NotFn) +
- " does not apply to the function!", V);
-
- for (unsigned i = 0;
- i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
- Attributes MutI = FAttrs & Attribute::MutuallyIncompatible[i];
- Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
- Attribute::getAsString(MutI) + " are incompatible!", V);
- }
+ AttrBuilder NotFn(FAttrs);
+ NotFn.removeFunctionOnlyAttrs();
+ Assert1(!NotFn.hasAttributes(), "Attributes '" +
+ Attributes::get(V->getContext(), NotFn).getAsString() +
+ "' do not apply to the function!", V);
+
+ // Check for mutually incompatible attributes.
+ Assert1(!((FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::Nest)) ||
+ (FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::StructRet)) ||
+ (FAttrs.hasAttribute(Attributes::Nest) &&
+ FAttrs.hasAttribute(Attributes::StructRet))), "Attributes "
+ "'byval, nest, and sret' are incompatible!", V);
+
+ Assert1(!((FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::Nest)) ||
+ (FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::InReg)) ||
+ (FAttrs.hasAttribute(Attributes::Nest) &&
+ FAttrs.hasAttribute(Attributes::InReg))), "Attributes "
+ "'byval, nest, and inreg' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::ZExt) &&
+ FAttrs.hasAttribute(Attributes::SExt)), "Attributes "
+ "'zeroext and signext' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::ReadNone) &&
+ FAttrs.hasAttribute(Attributes::ReadOnly)), "Attributes "
+ "'readnone and readonly' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::NoInline) &&
+ FAttrs.hasAttribute(Attributes::AlwaysInline)), "Attributes "
+ "'noinline and alwaysinline' are incompatible!", V);
}
-static bool VerifyAttributeCount(const AttrListPtr &Attrs, unsigned Params) {
+static bool VerifyAttributeCount(const AttributeSet &Attrs, unsigned Params) {
if (Attrs.isEmpty())
return true;
Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(),
"Invalid struct return type!", &F);
- const AttrListPtr &Attrs = F.getAttributes();
+ const AttributeSet &Attrs = F.getAttributes();
Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()),
"Attributes after last parameter!", &F);
case CallingConv::Cold:
case CallingConv::X86_FastCall:
case CallingConv::X86_ThisCall:
+ case CallingConv::Intel_OCL_BI:
case CallingConv::PTX_Kernel:
case CallingConv::PTX_Device:
Assert1(!F.isVarArg(),
// have the same type as the switched-on value.
Type *SwitchTy = SI.getCondition()->getType();
IntegerType *IntTy = cast<IntegerType>(SwitchTy);
- CRSBuilder Builder;
- std::map<ConstantRangesSet::Range, unsigned> RangeSetMap;
+ IntegersSubsetToBB Mapping;
+ std::map<IntegersSubset::Range, unsigned> RangeSetMap;
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
- ConstantRangesSet RS = i.getCaseValueEx();
- for (unsigned ri = 0, rie = RS.getNumItems(); ri < rie; ++ri) {
- ConstantRangesSet::Range r = RS.getItem(ri);
- Assert1(r.Low->getBitWidth() == IntTy->getBitWidth(),
+ IntegersSubset CaseRanges = i.getCaseValueEx();
+ for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
+ IntegersSubset::Range r = CaseRanges.getItem(ri);
+ Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
"Switch constants must all be same type as switch value!", &SI);
- Assert1(r.High->getBitWidth() == IntTy->getBitWidth(),
+ Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
"Switch constants must all be same type as switch value!", &SI);
- Builder.add(r);
+ Mapping.add(r);
RangeSetMap[r] = i.getCaseIndex();
}
}
- CRSBuilder::RangeIterator errItem;
- if (!Builder.verify(errItem)) {
+ IntegersSubsetToBB::RangeIterator errItem;
+ if (!Mapping.verify(errItem)) {
unsigned CaseIndex = RangeSetMap[errItem->first];
SwitchInst::CaseIt i(&SI, CaseIndex);
Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx());
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
- Assert1(DestTy->isPointerTy() == DestTy->isPointerTy(),
+ Assert1(SrcTy->isPointerTy() == DestTy->isPointerTy(),
"Bitcast requires both operands to be pointer or neither", &I);
Assert1(SrcBitSize == DestBitSize, "Bitcast requires types of same width",&I);
"Call parameter type does not match function signature!",
CS.getArgument(i), FTy->getParamType(i), I);
- const AttrListPtr &Attrs = CS.getAttributes();
+ const AttributeSet &Attrs = CS.getAttributes();
Assert1(VerifyAttributeCount(Attrs, CS.arg_size()),
"Attributes after last parameter!", I);
VerifyParameterAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I);
- Attributes VArgI = Attr & Attribute::VarArgsIncompatible;
- Assert1(!VArgI, "Attribute " + Attribute::getAsString(VArgI) +
- " cannot be used for vararg call arguments!", I);
+ Assert1(!Attr.hasIncompatibleWithVarArgsAttrs(),
+ "Attribute 'sret' cannot be used for vararg call arguments!", I);
}
// Verify that there's no metadata unless it's a direct call to an intrinsic.
"GEP base pointer is not a vector or a vector of pointers", &GEP);
Assert1(cast<PointerType>(TargetTy)->getElementType()->isSized(),
"GEP into unsized type!", &GEP);
+ Assert1(GEP.getPointerOperandType()->isVectorTy() ==
+ GEP.getType()->isVectorTy(), "Vector GEP must return a vector value",
+ &GEP);
SmallVector<Value*, 16> Idxs(GEP.idx_begin(), GEP.idx_end());
Type *ElTy =
GetElementPtrInst::getIndexedType(GEP.getPointerOperandType(), Idxs);
Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP);
- if (GEP.getPointerOperandType()->isPointerTy()) {
- // Validate GEPs with scalar indices.
- Assert2(GEP.getType()->isPointerTy() &&
- cast<PointerType>(GEP.getType())->getElementType() == ElTy,
- "GEP is not of right type for indices!", &GEP, ElTy);
- } else {
- // Validate GEPs with a vector index.
- Assert1(Idxs.size() == 1, "Invalid number of indices!", &GEP);
- Value *Index = Idxs[0];
- Type *IndexTy = Index->getType();
- Assert1(IndexTy->isVectorTy(),
- "Vector GEP must have vector indices!", &GEP);
- Assert1(GEP.getType()->isVectorTy(),
- "Vector GEP must return a vector value", &GEP);
- Type *ElemPtr = cast<VectorType>(GEP.getType())->getElementType();
- Assert1(ElemPtr->isPointerTy(),
- "Vector GEP pointer operand is not a pointer!", &GEP);
- unsigned IndexWidth = cast<VectorType>(IndexTy)->getNumElements();
- unsigned GepWidth = cast<VectorType>(GEP.getType())->getNumElements();
- Assert1(IndexWidth == GepWidth, "Invalid GEP index vector width", &GEP);
- Assert1(ElTy == cast<PointerType>(ElemPtr)->getElementType(),
- "Vector GEP type does not match pointer type!", &GEP);
+ Assert2(GEP.getType()->getScalarType()->isPointerTy() &&
+ cast<PointerType>(GEP.getType()->getScalarType())->getElementType()
+ == ElTy, "GEP is not of right type for indices!", &GEP, ElTy);
+
+ if (GEP.getPointerOperandType()->isVectorTy()) {
+ // Additional checks for vector GEPs.
+ unsigned GepWidth = GEP.getPointerOperandType()->getVectorNumElements();
+ Assert1(GepWidth == GEP.getType()->getVectorNumElements(),
+ "Vector GEP result width doesn't match operand's", &GEP);
+ for (unsigned i = 0, e = Idxs.size(); i != e; ++i) {
+ Type *IndexTy = Idxs[i]->getType();
+ Assert1(IndexTy->isVectorTy(),
+ "Vector GEP must have vector indices!", &GEP);
+ unsigned IndexWidth = IndexTy->getVectorNumElements();
+ Assert1(IndexWidth == GepWidth, "Invalid GEP index vector width", &GEP);
+ }
}
visitInstruction(GEP);
}
+static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
+ return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
+}
+
void Verifier::visitLoadInst(LoadInst &LI) {
PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType());
Assert1(PTy, "Load operand must be a pointer.", &LI);
"Load cannot have Release ordering", &LI);
Assert1(LI.getAlignment() != 0,
"Atomic load must specify explicit alignment", &LI);
+ if (!ElTy->isPointerTy()) {
+ Assert2(ElTy->isIntegerTy(),
+ "atomic store operand must have integer type!",
+ &LI, ElTy);
+ unsigned Size = ElTy->getPrimitiveSizeInBits();
+ Assert2(Size >= 8 && !(Size & (Size - 1)),
+ "atomic store operand must be power-of-two byte-sized integer",
+ &LI, ElTy);
+ }
} else {
Assert1(LI.getSynchScope() == CrossThread,
"Non-atomic load cannot have SynchronizationScope specified", &LI);
Assert1(NumOperands % 2 == 0, "Unfinished range!", Range);
unsigned NumRanges = NumOperands / 2;
Assert1(NumRanges >= 1, "It should have at least one range!", Range);
+
+ ConstantRange LastRange(1); // Dummy initial value
for (unsigned i = 0; i < NumRanges; ++i) {
ConstantInt *Low = dyn_cast<ConstantInt>(Range->getOperand(2*i));
Assert1(Low, "The lower limit must be an integer!", Low);
Assert1(High->getType() == Low->getType() &&
High->getType() == ElTy, "Range types must match load type!",
&LI);
- Assert1(High->getValue() != Low->getValue(), "Range must not be empty!",
+
+ APInt HighV = High->getValue();
+ APInt LowV = Low->getValue();
+ ConstantRange CurRange(LowV, HighV);
+ Assert1(!CurRange.isEmptySet() && !CurRange.isFullSet(),
+ "Range must not be empty!", Range);
+ if (i != 0) {
+ Assert1(CurRange.intersectWith(LastRange).isEmptySet(),
+ "Intervals are overlapping", Range);
+ Assert1(LowV.sgt(LastRange.getLower()), "Intervals are not in order",
+ Range);
+ Assert1(!isContiguous(CurRange, LastRange), "Intervals are contiguous",
+ Range);
+ }
+ LastRange = ConstantRange(LowV, HighV);
+ }
+ if (NumRanges > 2) {
+ APInt FirstLow =
+ dyn_cast<ConstantInt>(Range->getOperand(0))->getValue();
+ APInt FirstHigh =
+ dyn_cast<ConstantInt>(Range->getOperand(1))->getValue();
+ ConstantRange FirstRange(FirstLow, FirstHigh);
+ Assert1(FirstRange.intersectWith(LastRange).isEmptySet(),
+ "Intervals are overlapping", Range);
+ Assert1(!isContiguous(FirstRange, LastRange), "Intervals are contiguous",
Range);
}
+
+
}
visitInstruction(LI);
"Store cannot have Acquire ordering", &SI);
Assert1(SI.getAlignment() != 0,
"Atomic store must specify explicit alignment", &SI);
+ if (!ElTy->isPointerTy()) {
+ Assert2(ElTy->isIntegerTy(),
+ "atomic store operand must have integer type!",
+ &SI, ElTy);
+ unsigned Size = ElTy->getPrimitiveSizeInBits();
+ Assert2(Size >= 8 && !(Size & (Size - 1)),
+ "atomic store operand must be power-of-two byte-sized integer",
+ &SI, ElTy);
+ }
} else {
Assert1(SI.getSynchScope() == CrossThread,
"Non-atomic store cannot have SynchronizationScope specified", &SI);
PointerType *PTy = dyn_cast<PointerType>(CXI.getOperand(0)->getType());
Assert1(PTy, "First cmpxchg operand must be a pointer.", &CXI);
Type *ElTy = PTy->getElementType();
+ Assert2(ElTy->isIntegerTy(),
+ "cmpxchg operand must have integer type!",
+ &CXI, ElTy);
+ unsigned Size = ElTy->getPrimitiveSizeInBits();
+ Assert2(Size >= 8 && !(Size & (Size - 1)),
+ "cmpxchg operand must be power-of-two byte-sized integer",
+ &CXI, ElTy);
Assert2(ElTy == CXI.getOperand(1)->getType(),
"Expected value type does not match pointer operand type!",
&CXI, ElTy);
PointerType *PTy = dyn_cast<PointerType>(RMWI.getOperand(0)->getType());
Assert1(PTy, "First atomicrmw operand must be a pointer.", &RMWI);
Type *ElTy = PTy->getElementType();
+ Assert2(ElTy->isIntegerTy(),
+ "atomicrmw operand must have integer type!",
+ &RMWI, ElTy);
+ unsigned Size = ElTy->getPrimitiveSizeInBits();
+ Assert2(Size >= 8 && !(Size & (Size - 1)),
+ "atomicrmw operand must be power-of-two byte-sized integer",
+ &RMWI, ElTy);
Assert2(ElTy == RMWI.getOperand(1)->getType(),
"Argument value type does not match pointer operand type!",
&RMWI, ElTy);
// landing pad block may be branched to only by the unwind edge of an invoke.
for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator());
- Assert1(II && II->getUnwindDest() == BB,
+ Assert1(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
"Block containing LandingPadInst must be jumped to "
"only by the unwind edge of an invoke.", &LPI);
}
void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
Instruction *Op = cast<Instruction>(I.getOperand(i));
- BasicBlock *BB = I.getParent();
- BasicBlock *OpBlock = Op->getParent();
- PHINode *PN = dyn_cast<PHINode>(&I);
-
- // DT can handle non phi instructions for us.
- if (!PN) {
- // Definition must dominate use unless use is unreachable!
- Assert2(InstsInThisBlock.count(Op) || !DT->isReachableFromEntry(BB) ||
- DT->dominates(Op, &I),
- "Instruction does not dominate all uses!", Op, &I);
- return;
- }
-
- // Check that a definition dominates all of its uses.
+ // If the we have an invalid invoke, don't try to compute the dominance.
+ // We already reject it in the invoke specific checks and the dominance
+ // computation doesn't handle multiple edges.
if (InvokeInst *II = dyn_cast<InvokeInst>(Op)) {
- // Invoke results are only usable in the normal destination, not in the
- // exceptional destination.
- BasicBlock *NormalDest = II->getNormalDest();
-
-
- // PHI nodes differ from other nodes because they actually "use" the
- // value in the predecessor basic blocks they correspond to.
- BasicBlock *UseBlock = BB;
- unsigned j = PHINode::getIncomingValueNumForOperand(i);
- UseBlock = PN->getIncomingBlock(j);
- Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB",
- Op, &I);
-
- if (UseBlock == OpBlock) {
- // Special case of a phi node in the normal destination or the unwind
- // destination.
- Assert2(BB == NormalDest || !DT->isReachableFromEntry(UseBlock),
- "Invoke result not available in the unwind destination!",
- Op, &I);
- } else {
- Assert2(DT->dominates(II, UseBlock) ||
- !DT->isReachableFromEntry(UseBlock),
- "Invoke result does not dominate all uses!", Op, &I);
- }
+ if (II->getNormalDest() == II->getUnwindDest())
+ return;
}
- // PHI nodes are more difficult than other nodes because they actually
- // "use" the value in the predecessor basic blocks they correspond to.
- unsigned j = PHINode::getIncomingValueNumForOperand(i);
- BasicBlock *PredBB = PN->getIncomingBlock(j);
- Assert2(PredBB && (DT->dominates(OpBlock, PredBB) ||
- !DT->isReachableFromEntry(PredBB)),
+ const Use &U = I.getOperandUse(i);
+ Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, U),
"Instruction does not dominate all uses!", Op, &I);
}
if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
// Check to make sure that the "address of" an intrinsic function is never
// taken.
- Assert1(!F->isIntrinsic() || (i + 1 == e && isa<CallInst>(I)),
+ Assert1(!F->isIntrinsic() || i == (isa<CallInst>(I) ? e-1 : 0),
"Cannot take the address of an intrinsic!", &I);
+ Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
+ F->getIntrinsicID() == Intrinsic::donothing,
+ "Cannot invoke an intrinsinc other than donothing", &I);
Assert1(F->getParent() == Mod, "Referencing function in another module!",
&I);
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
}
case IITDescriptor::Argument:
- // Two cases here - If this is the second occurrance of an argument, verify
+ // Two cases here - If this is the second occurrence of an argument, verify
// that the later instance matches the previous instance.
if (D.getArgumentNumber() < ArgTys.size())
return Ty != ArgTys[D.getArgumentNumber()];