[llvm] 53acada - Verifier: Verify absolute_symbol metadata

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 30 09:31:41 PDT 2023


Author: Matt Arsenault
Date: 2023-06-30T12:31:32-04:00
New Revision: 53acadafdd388e5ecdf060b47766c2b73f185317

URL: https://github.com/llvm/llvm-project/commit/53acadafdd388e5ecdf060b47766c2b73f185317
DIFF: https://github.com/llvm/llvm-project/commit/53acadafdd388e5ecdf060b47766c2b73f185317.diff

LOG: Verifier: Verify absolute_symbol metadata

This is the same as !range except for one edge case.

Added: 
    llvm/test/Assembler/absolute_symbol.ll
    llvm/test/Verifier/absolute_symbol.ll

Modified: 
    llvm/lib/IR/Verifier.cpp
    llvm/test/CodeGen/X86/absolute-constant.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 251865abab32f9..5cf230d574aac4 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -474,6 +474,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
   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 visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
   void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
   void visitProfMetadata(Instruction &I, MDNode *MD);
@@ -682,7 +684,15 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
               Associated);
       }
     }
+
+    // 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);
+    }
   }
+
   Check(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
         "Only global variables can have appending linkage!", &GV);
 
@@ -3904,10 +3914,10 @@ 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");
-
+/// 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) {
   unsigned NumOperands = Range->getNumOperands();
   Check(NumOperands % 2 == 0, "Unfinished range!", Range);
   unsigned NumRanges = NumOperands / 2;
@@ -3934,7 +3944,7 @@ void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
           "The upper and lower limits cannot be the same value", &I);
 
     ConstantRange CurRange(LowV, HighV);
-    Check(!CurRange.isEmptySet() && !CurRange.isFullSet(),
+    Check(!CurRange.isEmptySet() && (IsAbsoluteSymbol || !CurRange.isFullSet()),
           "Range must not be empty!", Range);
     if (i != 0) {
       Check(CurRange.intersectWith(LastRange).isEmptySet(),
@@ -3959,6 +3969,12 @@ void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
   }
 }
 
+void Verifier::visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty) {
+  assert(Range && Range == I.getMetadata(LLVMContext::MD_range) &&
+         "precondition violation");
+  verifyRangeMetadata(I, Range, Ty, false);
+}
+
 void Verifier::checkAtomicMemAccessSize(Type *Ty, const Instruction *I) {
   unsigned Size = DL.getTypeSizeInBits(Ty);
   Check(Size >= 8, "atomic memory access' size must be byte-sized", Ty, I);

diff  --git a/llvm/test/Assembler/absolute_symbol.ll b/llvm/test/Assembler/absolute_symbol.ll
new file mode 100644
index 00000000000000..6c52727144ad6f
--- /dev/null
+++ b/llvm/test/Assembler/absolute_symbol.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+; CHECK: @simple_range = external global i32, !absolute_symbol [[META0:![0-9]+]]
+ at simple_range = external global i32, !absolute_symbol !0
+
+; Unlike !range, this accepts -1, -1
+; CHECK: @full_range = external global i32, !absolute_symbol [[META1:![0-9]+]]
+ at full_range = external global i32, !absolute_symbol !1
+
+; CHECK: @multiple_ranges = external global i32, !absolute_symbol [[META2:![0-9]+]]
+ at multiple_ranges = external global i32, !absolute_symbol !2
+
+!0 = !{i64 4096, i64 8192}
+!1 = !{i64 -1, i64 -1}
+!2 = !{i64 256, i64 512, i64 1024, i64 4096}
+;.
+; CHECK: [[META0]] = !{i64 4096, i64 8192}
+; CHECK: [[META1]] = !{i64 -1, i64 -1}
+; CHECK: [[META2]] = !{i64 256, i64 512, i64 1024, i64 4096}
+;.

diff  --git a/llvm/test/CodeGen/X86/absolute-constant.ll b/llvm/test/CodeGen/X86/absolute-constant.ll
index 6344e0bc2d5cd3..209e9f872612d0 100644
--- a/llvm/test/CodeGen/X86/absolute-constant.ll
+++ b/llvm/test/CodeGen/X86/absolute-constant.ll
@@ -44,4 +44,4 @@ if.end:                                           ; preds = %entry, %if.then
 
 declare void @xf(...)
 
-!0 = !{i32 0, i32 256}
+!0 = !{i64 0, i64 256}

diff  --git a/llvm/test/Verifier/absolute_symbol.ll b/llvm/test/Verifier/absolute_symbol.ll
new file mode 100644
index 00000000000000..631f35585f288b
--- /dev/null
+++ b/llvm/test/Verifier/absolute_symbol.ll
@@ -0,0 +1,96 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+target datalayout = "p0:64:64-p1:32:32"
+
+
+ at absolute_empty_arguments = external global i32, !absolute_symbol !0
+
+ at absolute_one_argument = external global i32, !absolute_symbol !1
+
+ at absolute_three_arguments = external global i32, !absolute_symbol !2
+
+
+
+ at absolute_one_argument_wrong_width = external global i32, !absolute_symbol !3
+ at absolute_two_arguments_wrong_width = external global i32, !absolute_symbol !4
+
+ at absolute_two_arguments_one_wrong_width0 = external global i32, !absolute_symbol !5
+ at absolute_two_arguments_one_wrong_width1 = external global i32, !absolute_symbol !6
+
+ at absolute_zero_zero = external global i32, !absolute_symbol !7
+
+ at absolute_equal_other = external global i32, !absolute_symbol !8
+
+ at absolute_wrong_width_non0_as = external addrspace(1) global i32, !absolute_symbol !9
+
+; Test other kinds of symbols besides GlobalVariable
+define void @absolute_func_empty_arguments() !absolute_symbol !0 {
+  ret void
+}
+
+ at absolute_is_fp = external global i32, !absolute_symbol !10
+ at absolute_is_vector = external global i32, !absolute_symbol !11
+ at absolute_is_ptr = external global i32, !absolute_symbol !12
+ at absolute_is_ptr0 = external global i32, !absolute_symbol !13
+ at absolute_is_ptr1 = external global i32, !absolute_symbol !14
+
+ at absolute_wrong_order = external global i32, !absolute_symbol !15
+
+; CHECK: It should have at least one range!
+; CHECK-NEXT: !0 = !{}
+; CHECK: It should have at least one range!
+; CHECK-NEXT: !0 = !{}
+!0 = !{}
+
+; CHECK-NEXT: Unfinished range!
+; CHECK-NEXT: !1 = !{i64 128}
+!1 = !{i64 128}
+
+; CHECK-NEXT: Unfinished range!
+; CHECK-NEXT: !2 = !{i64 128, i64 256, i64 512}
+!2 = !{i64 128, i64 256, i64 512}
+
+; CHECK-NEXT: Unfinished range!
+; CHECK-NEXT: !3 = !{i32 256}
+!3 = !{i32 256}
+
+; CHECK-NEXT: Range types must match instruction type!
+; CHECK-NEXT: ptr @absolute_two_arguments_wrong_width
+!4 = !{i32 256, i32 512}
+
+; CHECK-NEXT: Range types must match instruction type!
+; CHECK-NEXT: ptr @absolute_two_arguments_one_wrong_width0
+!5 = !{i32 256, i64 512}
+
+; CHECK-NEXT: Range types must match instruction type!
+; CHECK-NEXT: ptr @absolute_two_arguments_one_wrong_width1
+!6 = !{i64 256, i32 512}
+
+; CHECK-NEXT: Range must not be empty!
+; CHECK-NEXT: !7 = !{i64 0, i64 0}
+!7 = !{i64 0, i64 0}
+
+; CHECK-NEXT: The upper and lower limits cannot be the same value
+; CHECK-NEXT: ptr @absolute_equal_other
+!8 = !{i64 123, i64 123}
+
+; CHECK-NEXT: Range types must match instruction type!
+; CHECK-NEXT: ptr addrspace(1) @absolute_wrong_width_non0_as
+!9 = !{i64 512, i64 256}
+
+; CHECK-NEXT: The lower limit must be an integer!
+!10 = !{float 0.0, float 256.0}
+
+; CHECK-NEXT: The lower limit must be an integer!
+!11 = !{<2 x i64> zeroinitializer, <2 x i64> <i64 256, i64 256>}
+
+; CHECK-NEXT: The lower limit must be an integer!
+!12 = !{ptr null, ptr inttoptr (i64 256 to ptr)}
+
+; CHECK-NEXT: The lower limit must be an integer!
+!13 = !{ptr null, i64 456}
+
+; CHECK-NEXT: The upper limit must be an integer!
+!14 = !{i64 456, ptr inttoptr (i64 512 to ptr)}
+!15 = !{i64 1024, i64 128}
+


        


More information about the llvm-commits mailing list