aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp53
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);