Skip to content

Commit 53acada

Browse files
committed
Verifier: Verify absolute_symbol metadata
This is the same as !range except for one edge case.
1 parent a2ce822 commit 53acada

File tree

4 files changed

+138
-6
lines changed

4 files changed

+138
-6
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
474474
void visitModuleFlagCGProfileEntry(const MDOperand &MDO);
475475
void visitFunction(const Function &F);
476476
void visitBasicBlock(BasicBlock &BB);
477+
void verifyRangeMetadata(const Value &V, const MDNode *Range, Type *Ty,
478+
bool IsAbsoluteSymbol);
477479
void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
478480
void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
479481
void visitProfMetadata(Instruction &I, MDNode *MD);
@@ -682,7 +684,15 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
682684
Associated);
683685
}
684686
}
687+
688+
// FIXME: Why is getMetadata on GlobalValue protected?
689+
if (const MDNode *AbsoluteSymbol =
690+
GO->getMetadata(LLVMContext::MD_absolute_symbol)) {
691+
verifyRangeMetadata(*GO, AbsoluteSymbol, DL.getIntPtrType(GO->getType()),
692+
true);
693+
}
685694
}
695+
686696
Check(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
687697
"Only global variables can have appending linkage!", &GV);
688698

@@ -3904,10 +3914,10 @@ static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
39043914
return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
39053915
}
39063916

3907-
void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
3908-
assert(Range && Range == I.getMetadata(LLVMContext::MD_range) &&
3909-
"precondition violation");
3910-
3917+
/// Verify !range and !absolute_symbol metadata. These have the same
3918+
/// restrictions, except !absolute_symbol allows the full set.
3919+
void Verifier::verifyRangeMetadata(const Value &I, const MDNode *Range,
3920+
Type *Ty, bool IsAbsoluteSymbol) {
39113921
unsigned NumOperands = Range->getNumOperands();
39123922
Check(NumOperands % 2 == 0, "Unfinished range!", Range);
39133923
unsigned NumRanges = NumOperands / 2;
@@ -3934,7 +3944,7 @@ void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
39343944
"The upper and lower limits cannot be the same value", &I);
39353945

39363946
ConstantRange CurRange(LowV, HighV);
3937-
Check(!CurRange.isEmptySet() && !CurRange.isFullSet(),
3947+
Check(!CurRange.isEmptySet() && (IsAbsoluteSymbol || !CurRange.isFullSet()),
39383948
"Range must not be empty!", Range);
39393949
if (i != 0) {
39403950
Check(CurRange.intersectWith(LastRange).isEmptySet(),
@@ -3959,6 +3969,12 @@ void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
39593969
}
39603970
}
39613971

3972+
void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
3973+
assert(Range && Range == I.getMetadata(LLVMContext::MD_range) &&
3974+
"precondition violation");
3975+
verifyRangeMetadata(I, Range, Ty, false);
3976+
}
3977+
39623978
void Verifier::checkAtomicMemAccessSize(Type *Ty, const Instruction *I) {
39633979
unsigned Size = DL.getTypeSizeInBits(Ty);
39643980
Check(Size >= 8, "atomic memory access' size must be byte-sized", Ty, I);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
2+
3+
; CHECK: @simple_range = external global i32, !absolute_symbol [[META0:![0-9]+]]
4+
@simple_range = external global i32, !absolute_symbol !0
5+
6+
; Unlike !range, this accepts -1, -1
7+
; CHECK: @full_range = external global i32, !absolute_symbol [[META1:![0-9]+]]
8+
@full_range = external global i32, !absolute_symbol !1
9+
10+
; CHECK: @multiple_ranges = external global i32, !absolute_symbol [[META2:![0-9]+]]
11+
@multiple_ranges = external global i32, !absolute_symbol !2
12+
13+
!0 = !{i64 4096, i64 8192}
14+
!1 = !{i64 -1, i64 -1}
15+
!2 = !{i64 256, i64 512, i64 1024, i64 4096}
16+
;.
17+
; CHECK: [[META0]] = !{i64 4096, i64 8192}
18+
; CHECK: [[META1]] = !{i64 -1, i64 -1}
19+
; CHECK: [[META2]] = !{i64 256, i64 512, i64 1024, i64 4096}
20+
;.

llvm/test/CodeGen/X86/absolute-constant.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ if.end: ; preds = %entry, %if.then
4444

4545
declare void @xf(...)
4646

47-
!0 = !{i32 0, i32 256}
47+
!0 = !{i64 0, i64 256}

llvm/test/Verifier/absolute_symbol.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
target datalayout = "p0:64:64-p1:32:32"
4+
5+
6+
@absolute_empty_arguments = external global i32, !absolute_symbol !0
7+
8+
@absolute_one_argument = external global i32, !absolute_symbol !1
9+
10+
@absolute_three_arguments = external global i32, !absolute_symbol !2
11+
12+
13+
14+
@absolute_one_argument_wrong_width = external global i32, !absolute_symbol !3
15+
@absolute_two_arguments_wrong_width = external global i32, !absolute_symbol !4
16+
17+
@absolute_two_arguments_one_wrong_width0 = external global i32, !absolute_symbol !5
18+
@absolute_two_arguments_one_wrong_width1 = external global i32, !absolute_symbol !6
19+
20+
@absolute_zero_zero = external global i32, !absolute_symbol !7
21+
22+
@absolute_equal_other = external global i32, !absolute_symbol !8
23+
24+
@absolute_wrong_width_non0_as = external addrspace(1) global i32, !absolute_symbol !9
25+
26+
; Test other kinds of symbols besides GlobalVariable
27+
define void @absolute_func_empty_arguments() !absolute_symbol !0 {
28+
ret void
29+
}
30+
31+
@absolute_is_fp = external global i32, !absolute_symbol !10
32+
@absolute_is_vector = external global i32, !absolute_symbol !11
33+
@absolute_is_ptr = external global i32, !absolute_symbol !12
34+
@absolute_is_ptr0 = external global i32, !absolute_symbol !13
35+
@absolute_is_ptr1 = external global i32, !absolute_symbol !14
36+
37+
@absolute_wrong_order = external global i32, !absolute_symbol !15
38+
39+
; CHECK: It should have at least one range!
40+
; CHECK-NEXT: !0 = !{}
41+
; CHECK: It should have at least one range!
42+
; CHECK-NEXT: !0 = !{}
43+
!0 = !{}
44+
45+
; CHECK-NEXT: Unfinished range!
46+
; CHECK-NEXT: !1 = !{i64 128}
47+
!1 = !{i64 128}
48+
49+
; CHECK-NEXT: Unfinished range!
50+
; CHECK-NEXT: !2 = !{i64 128, i64 256, i64 512}
51+
!2 = !{i64 128, i64 256, i64 512}
52+
53+
; CHECK-NEXT: Unfinished range!
54+
; CHECK-NEXT: !3 = !{i32 256}
55+
!3 = !{i32 256}
56+
57+
; CHECK-NEXT: Range types must match instruction type!
58+
; CHECK-NEXT: ptr @absolute_two_arguments_wrong_width
59+
!4 = !{i32 256, i32 512}
60+
61+
; CHECK-NEXT: Range types must match instruction type!
62+
; CHECK-NEXT: ptr @absolute_two_arguments_one_wrong_width0
63+
!5 = !{i32 256, i64 512}
64+
65+
; CHECK-NEXT: Range types must match instruction type!
66+
; CHECK-NEXT: ptr @absolute_two_arguments_one_wrong_width1
67+
!6 = !{i64 256, i32 512}
68+
69+
; CHECK-NEXT: Range must not be empty!
70+
; CHECK-NEXT: !7 = !{i64 0, i64 0}
71+
!7 = !{i64 0, i64 0}
72+
73+
; CHECK-NEXT: The upper and lower limits cannot be the same value
74+
; CHECK-NEXT: ptr @absolute_equal_other
75+
!8 = !{i64 123, i64 123}
76+
77+
; CHECK-NEXT: Range types must match instruction type!
78+
; CHECK-NEXT: ptr addrspace(1) @absolute_wrong_width_non0_as
79+
!9 = !{i64 512, i64 256}
80+
81+
; CHECK-NEXT: The lower limit must be an integer!
82+
!10 = !{float 0.0, float 256.0}
83+
84+
; CHECK-NEXT: The lower limit must be an integer!
85+
!11 = !{<2 x i64> zeroinitializer, <2 x i64> <i64 256, i64 256>}
86+
87+
; CHECK-NEXT: The lower limit must be an integer!
88+
!12 = !{ptr null, ptr inttoptr (i64 256 to ptr)}
89+
90+
; CHECK-NEXT: The lower limit must be an integer!
91+
!13 = !{ptr null, i64 456}
92+
93+
; CHECK-NEXT: The upper limit must be an integer!
94+
!14 = !{i64 456, ptr inttoptr (i64 512 to ptr)}
95+
!15 = !{i64 1024, i64 128}
96+

0 commit comments

Comments
 (0)