summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/IR/Verifier.cpp105
-rw-r--r--llvm/test/Verifier/range-1.ll15
2 files changed, 68 insertions, 52 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 5519cacbd10..154d54870ef 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -269,6 +269,8 @@ private:
SmallVectorImpl<const MDNode *> &Requirements);
void visitFunction(const Function &F);
void visitBasicBlock(BasicBlock &BB);
+ void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
+
// InstVisitor overrides...
using InstVisitor<Verifier>::visit;
@@ -1885,6 +1887,55 @@ static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
}
+void Verifier::visitRangeMetadata(Instruction& I,
+ MDNode* Range, Type* Ty) {
+ assert(Range &&
+ Range == I.getMetadata(LLVMContext::MD_range) &&
+ "precondition violation");
+
+ unsigned NumOperands = Range->getNumOperands();
+ 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);
+ ConstantInt *High = dyn_cast<ConstantInt>(Range->getOperand(2*i + 1));
+ Assert1(High, "The upper limit must be an integer!", High);
+ Assert1(High->getType() == Low->getType() &&
+ High->getType() == Ty, "Range types must match instruction type!",
+ &I);
+
+ 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);
+ }
+}
+
void Verifier::visitLoadInst(LoadInst &LI) {
PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType());
Assert1(PTy, "Load operand must be a pointer.", &LI);
@@ -1912,52 +1963,6 @@ void Verifier::visitLoadInst(LoadInst &LI) {
"Non-atomic load cannot have SynchronizationScope specified", &LI);
}
- if (MDNode *Range = LI.getMetadata(LLVMContext::MD_range)) {
- unsigned NumOperands = Range->getNumOperands();
- 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);
- ConstantInt *High = dyn_cast<ConstantInt>(Range->getOperand(2*i + 1));
- Assert1(High, "The upper limit must be an integer!", High);
- Assert1(High->getType() == Low->getType() &&
- High->getType() == ElTy, "Range types must match load type!",
- &LI);
-
- 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);
}
@@ -2276,9 +2281,11 @@ void Verifier::visitInstruction(Instruction &I) {
}
}
- MDNode *MD = I.getMetadata(LLVMContext::MD_range);
- Assert1(!MD || isa<LoadInst>(I) || isa<CallInst>(I) || isa<InvokeInst>(I),
- "Ranges are only for loads, calls and invokes!", &I);
+ if (MDNode *Range = I.getMetadata(LLVMContext::MD_range)) {
+ Assert1(isa<LoadInst>(I) || isa<CallInst>(I) || isa<InvokeInst>(I),
+ "Ranges are only for loads, calls and invokes!", &I);
+ visitRangeMetadata(I, Range, I.getType());
+ }
InstsInThisBlock.insert(&I);
}
diff --git a/llvm/test/Verifier/range-1.ll b/llvm/test/Verifier/range-1.ll
index f15ca3f7406..0b20ca25dfb 100644
--- a/llvm/test/Verifier/range-1.ll
+++ b/llvm/test/Verifier/range-1.ll
@@ -48,7 +48,7 @@ entry:
ret i8 %y
}
!5 = metadata !{i32 0, i8 0}
-; CHECK: Range types must match load type!
+; CHECK: Range types must match instruction type!
; CHECK: %y = load
define i8 @f7(i8* %x) {
@@ -57,7 +57,7 @@ entry:
ret i8 %y
}
!6 = metadata !{i8 0, i32 0}
-; CHECK: Range types must match load type!
+; CHECK: Range types must match instruction type!
; CHECK: %y = load
define i8 @f8(i8* %x) {
@@ -66,7 +66,7 @@ entry:
ret i8 %y
}
!7 = metadata !{i32 0, i32 0}
-; CHECK: Range types must match load type!
+; CHECK: Range types must match instruction type!
; CHECK: %y = load
define i8 @f9(i8* %x) {
@@ -140,3 +140,12 @@ entry:
}
!17 = metadata !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
; CHECK: Intervals are contiguous
+
+define i8 @f18() {
+entry:
+ %y = call i8 undef(), !range !18
+ ret i8 %y
+}
+!18 = metadata !{}
+; CHECK: It should have at least one range!
+; CHECK-NEXT: metadata
OpenPOWER on IntegriCloud