diff options
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 1cd5eb3..b89c9ce 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -492,6 +492,14 @@ private: /// Whether a metadata node is allowed to be, or contain, a DILocation. enum class AreDebugLocsAllowed { No, Yes }; + /// Metadata that should be treated as a range, with slightly different + /// requirements. + enum class RangeLikeMetadataKind { + Range, // MD_range + AbsoluteSymbol, // MD_absolute_symbol + NoaliasAddrspace // MD_noalias_addrspace + }; + // Verification methods... void visitGlobalValue(const GlobalValue &GV); void visitGlobalVariable(const GlobalVariable &GV); @@ -515,9 +523,10 @@ private: void visitModuleFlagCGProfileEntry(const MDOperand &MDO); void visitFunction(const Function &F); void visitBasicBlock(BasicBlock &BB); - void verifyRangeMetadata(const Value &V, const MDNode *Range, Type *Ty, - bool IsAbsoluteSymbol); + void verifyRangeLikeMetadata(const Value &V, const MDNode *Range, Type *Ty, + RangeLikeMetadataKind Kind); void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); + void visitNoaliasAddrspaceMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); void visitProfMetadata(Instruction &I, MDNode *MD); void visitCallStackMetadata(MDNode *MD); @@ -760,8 +769,9 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { // FIXME: Why is getMetadata on GlobalValue protected? if (const MDNode *AbsoluteSymbol = GO->getMetadata(LLVMContext::MD_absolute_symbol)) { - verifyRangeMetadata(*GO, AbsoluteSymbol, DL.getIntPtrType(GO->getType()), - true); + verifyRangeLikeMetadata(*GO, AbsoluteSymbol, + DL.getIntPtrType(GO->getType()), + RangeLikeMetadataKind::AbsoluteSymbol); } } @@ -4136,8 +4146,8 @@ static bool isContiguous(const ConstantRange &A, const ConstantRange &B) { /// Verify !range and !absolute_symbol metadata. These have the same /// restrictions, except !absolute_symbol allows the full set. -void Verifier::verifyRangeMetadata(const Value &I, const MDNode *Range, - Type *Ty, bool IsAbsoluteSymbol) { +void Verifier::verifyRangeLikeMetadata(const Value &I, const MDNode *Range, + Type *Ty, RangeLikeMetadataKind Kind) { unsigned NumOperands = Range->getNumOperands(); Check(NumOperands % 2 == 0, "Unfinished range!", Range); unsigned NumRanges = NumOperands / 2; @@ -4154,8 +4164,14 @@ void Verifier::verifyRangeMetadata(const Value &I, const MDNode *Range, Check(High->getType() == Low->getType(), "Range pair types must match!", &I); - Check(High->getType() == Ty->getScalarType(), - "Range types must match instruction type!", &I); + + if (Kind == RangeLikeMetadataKind::NoaliasAddrspace) { + Check(High->getType()->isIntegerTy(32), + "noalias.addrspace type must be i32!", &I); + } else { + Check(High->getType() == Ty->getScalarType(), + "Range types must match instruction type!", &I); + } APInt HighV = High->getValue(); APInt LowV = Low->getValue(); @@ -4166,7 +4182,9 @@ void Verifier::verifyRangeMetadata(const Value &I, const MDNode *Range, "The upper and lower limits cannot be the same value", &I); ConstantRange CurRange(LowV, HighV); - Check(!CurRange.isEmptySet() && (IsAbsoluteSymbol || !CurRange.isFullSet()), + Check(!CurRange.isEmptySet() && + (Kind == RangeLikeMetadataKind::AbsoluteSymbol || + !CurRange.isFullSet()), "Range must not be empty!", Range); if (i != 0) { Check(CurRange.intersectWith(LastRange).isEmptySet(), @@ -4194,7 +4212,15 @@ void Verifier::verifyRangeMetadata(const Value &I, const MDNode *Range, void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) { assert(Range && Range == I.getMetadata(LLVMContext::MD_range) && "precondition violation"); - verifyRangeMetadata(I, Range, Ty, false); + verifyRangeLikeMetadata(I, Range, Ty, RangeLikeMetadataKind::Range); +} + +void Verifier::visitNoaliasAddrspaceMetadata(Instruction &I, MDNode *Range, + Type *Ty) { + assert(Range && Range == I.getMetadata(LLVMContext::MD_noalias_addrspace) && + "precondition violation"); + verifyRangeLikeMetadata(I, Range, Ty, + RangeLikeMetadataKind::NoaliasAddrspace); } void Verifier::checkAtomicMemAccessSize(Type *Ty, const Instruction *I) { @@ -5187,6 +5213,13 @@ void Verifier::visitInstruction(Instruction &I) { visitRangeMetadata(I, Range, I.getType()); } + if (MDNode *Range = I.getMetadata(LLVMContext::MD_noalias_addrspace)) { + Check(isa<LoadInst>(I) || isa<StoreInst>(I) || isa<AtomicRMWInst>(I) || + isa<AtomicCmpXchgInst>(I) || isa<CallInst>(I), + "noalias.addrspace are only for memory operations!", &I); + visitNoaliasAddrspaceMetadata(I, Range, I.getType()); + } + if (I.hasMetadata(LLVMContext::MD_invariant_group)) { Check(isa<LoadInst>(I) || isa<StoreInst>(I), "invariant.group metadata is only for loads and stores", &I); |