[llvm] 87f2e94 - Verifier: Add checks for associated metadata

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 25 18:39:00 PST 2023


Author: Matt Arsenault
Date: 2023-01-25T22:38:53-04:00
New Revision: 87f2e9448e82bbed4ac59bb61bea03256aa5f4de

URL: https://github.com/llvm/llvm-project/commit/87f2e9448e82bbed4ac59bb61bea03256aa5f4de
DIFF: https://github.com/llvm/llvm-project/commit/87f2e9448e82bbed4ac59bb61bea03256aa5f4de.diff

LOG: Verifier: Add checks for associated metadata

Also add missing assembler test for the valid cases.

Added: 
    llvm/test/Assembler/associated-metadata.ll
    llvm/test/Linker/Inputs/associated-global.ll
    llvm/test/Linker/associated-global.ll
    llvm/test/Verifier/associated-metadata.ll

Modified: 
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/IR/Verifier.cpp
    llvm/test/CodeGen/X86/elf-associated.ll
    llvm/test/Linker/metadata-global.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index e760564779c28..39f7ee73ec203 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -591,14 +591,7 @@ static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO,
   if (!MD)
     return nullptr;
 
-  const MDOperand &Op = MD->getOperand(0);
-  if (!Op.get())
-    return nullptr;
-
-  auto *VM = dyn_cast<ValueAsMetadata>(Op);
-  if (!VM)
-    report_fatal_error("MD_associated operand is not ValueAsMetadata");
-
+  auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get());
   auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue());
   return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr;
 }

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 83e42bc184ff2..5d86723c50346 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -653,6 +653,28 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
       Check(A->value() <= Value::MaximumAlignment,
             "huge alignment values are unsupported", GO);
     }
+
+    if (const MDNode *Associated =
+            GO->getMetadata(LLVMContext::MD_associated)) {
+      Check(Associated->getNumOperands() == 1,
+            "associated metadata must have one operand", &GV, Associated);
+      const Metadata *Op = Associated->getOperand(0).get();
+      Check(Op, "associated metadata must have a global value", GO, Associated);
+
+      const auto *VM = dyn_cast_or_null<ValueAsMetadata>(Op);
+      Check(VM, "associated metadata must be ValueAsMetadata", GO, Associated);
+      if (VM) {
+        Check(isa<PointerType>(VM->getValue()->getType()),
+              "associated value must be pointer typed", GV, Associated);
+
+        const Value *Stripped = VM->getValue()->stripPointerCastsAndAliases();
+        Check(isa<GlobalObject>(Stripped) || isa<Constant>(Stripped),
+              "associated metadata must point to a GlobalObject", GO, Stripped);
+        Check(Stripped != GO,
+              "global values should not associate to themselves", GO,
+              Associated);
+      }
+    }
   }
   Check(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
         "Only global variables can have appending linkage!", &GV);

diff  --git a/llvm/test/Assembler/associated-metadata.ll b/llvm/test/Assembler/associated-metadata.ll
new file mode 100644
index 0000000000000..71f31bc4e2864
--- /dev/null
+++ b/llvm/test/Assembler/associated-metadata.ll
@@ -0,0 +1,93 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+ at gv.decl = external constant [8 x i8]
+ at gv.def = constant [8 x i8] zeroinitializer
+
+ at gv.associated.func.decl = external addrspace(1) constant [8 x i8], !associated !0
+ at gv.associated.func.def = external addrspace(1) constant [8 x i8], !associated !1
+
+ at gv.associated.gv.decl = external addrspace(1) constant [8 x i8], !associated !2
+ at gv.associated.gv.def = external addrspace(1) constant [8 x i8], !associated !3
+
+ at alias = alias i32, ptr @gv.def
+
+ at gv.associated.alias.gv.def = external addrspace(1) constant [8 x i8], !associated !4
+
+ at gv.associated.alias.addrspacecast = external addrspace(1) constant [8 x i8], !associated !5
+ at alias.addrspacecast = alias i32, ptr addrspace(1) addrspacecast (ptr @gv.def to ptr addrspace(1))
+
+
+ at gv.def.associated.addrspacecast = external addrspace(1) constant [8 x i8], !associated !6
+
+ at ifunc = dso_local ifunc i32 (i32), ptr @ifunc_resolver
+ at gv.associated.ifunc = external constant [8 x i8], !associated !7
+
+ at gv.associated.null = external constant [8 x i8], !associated !8
+ at gv.associated.inttoptr = external constant [8 x i8], !associated !9
+ at gv.associated.poison = external constant [8 x i8], !associated !10
+ at gv.associated.undef = external constant [8 x i8], !associated !11
+ at associated.addrspacecast.null = external addrspace(1) constant [8 x i8], !associated !12
+
+
+;.
+; CHECK: @[[GV_DECL:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8]
+; CHECK: @[[GV_DEF:[a-zA-Z0-9_$"\\.-]+]] = constant [8 x i8] zeroinitializer
+; CHECK: @[[GV_ASSOCIATED_FUNC_DECL:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !0
+; CHECK: @[[GV_ASSOCIATED_FUNC_DEF:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !1
+; CHECK: @[[GV_ASSOCIATED_GV_DECL:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !2
+; CHECK: @[[GV_ASSOCIATED_GV_DEF:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !3
+; CHECK: @[[GV_ASSOCIATED_ALIAS_GV_DEF:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !4
+; CHECK: @[[GV_ASSOCIATED_ALIAS_ADDRSPACECAST:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !5
+; CHECK: @[[GV_DEF_ASSOCIATED_ADDRSPACECAST:[a-zA-Z0-9_$"\\.-]+]] = external addrspace(1) constant [8 x i8], !associated !6
+; CHECK: @[[GV_ASSOCIATED_IFUNC:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8], !associated !7
+; CHECK: @[[GV_ASSOCIATED_NULL:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8], !associated !8
+; CHECK: @[[GV_ASSOCIATED_INTTOPTR:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8], !associated !9
+; CHECK: @[[GV_ASSOCIATED_POISON:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8], !associated !10
+; CHECK: @[[GV_ASSOCIATED_UNDEF:[a-zA-Z0-9_$"\\.-]+]] = external constant [8 x i8], !associated !11
+; CHECK: @[[ALIAS:[a-zA-Z0-9_$"\\.-]+]] = alias i32, ptr @gv.def
+; CHECK: @[[ALIAS_ADDRSPACECAST:[a-zA-Z0-9_$"\\.-]+]] = alias i32, addrspacecast (ptr @gv.def to ptr addrspace(1))
+; CHECK: @[[IFUNC:[a-zA-Z0-9_$"\\.-]+]] = dso_local ifunc i32 (i32), ptr @ifunc_resolver
+;.
+define ptr @ifunc_resolver() {
+; CHECK-LABEL: @ifunc_resolver(
+; CHECK-NEXT:    ret ptr null
+;
+  ret ptr null
+}
+
+
+declare void @func.decl()
+define void @func.def() {
+; CHECK-LABEL: @func.def(
+; CHECK-NEXT:    ret void
+;
+  ret void
+}
+
+!0 = !{ ptr @func.decl }
+!1 = !{ ptr @func.def }
+!2 = !{ ptr @gv.decl }
+!3 = !{ ptr @gv.def }
+!4 = !{ ptr @alias }
+!5 = !{ ptr addrspace(1) @alias.addrspacecast }
+!6 = !{ ptr addrspace(1) addrspacecast (ptr @gv.def to ptr addrspace(1)) }
+!7 = !{ ptr @ifunc }
+!8 = !{ ptr null }
+!9 = !{ ptr inttoptr (i64 12345 to ptr) }
+!10 = !{ ptr poison }
+!11 = !{ ptr undef }
+!12 = !{ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1))}
+;.
+; CHECK: [[META0:![0-9]+]] = !{ptr @func.decl}
+; CHECK: [[META1:![0-9]+]] = !{ptr @func.def}
+; CHECK: [[META2:![0-9]+]] = !{ptr @gv.decl}
+; CHECK: [[META3:![0-9]+]] = !{ptr @gv.def}
+; CHECK: [[META4:![0-9]+]] = !{ptr @alias}
+; CHECK: [[META5:![0-9]+]] = !{ptr addrspace(1) @alias.addrspacecast}
+; CHECK: [[META6:![0-9]+]] = !{ptr addrspace(1) addrspacecast (ptr @gv.def to ptr addrspace(1))}
+; CHECK: [[META7:![0-9]+]] = !{ptr @ifunc}
+; CHECK: [[META8:![0-9]+]] = !{ptr null}
+; CHECK: [[META9:![0-9]+]] = !{ptr inttoptr (i64 12345 to ptr)}
+; CHECK: [[META10:![0-9]+]] = !{ptr poison}
+; CHECK: [[META11:![0-9]+]] = !{ptr undef}
+;.

diff  --git a/llvm/test/CodeGen/X86/elf-associated.ll b/llvm/test/CodeGen/X86/elf-associated.ll
index 20b8618807e3d..33e9e43bf8998 100644
--- a/llvm/test/CodeGen/X86/elf-associated.ll
+++ b/llvm/test/CodeGen/X86/elf-associated.ll
@@ -38,13 +38,8 @@
 !5 = !{ptr null}
 ; CHECK-DAG: .section	ccc,"awo", at progbits,0,unique,3
 
-; Null metadata.
- at m = global i32 1, section "ddd", !associated !6
-!6 = distinct !{null}
-; CHECK-DAG: .section	ddd,"awo", at progbits,0,unique,4
-
 ; Aliases are OK.
 @n = alias i32, ptr inttoptr (i64 add (i64 ptrtoint (ptr @a to i64), i64 1297036692682702848) to ptr)
 @o = global i32 1, section "eee", !associated !7
 !7 = !{ptr @n}
-; CHECK-DAG: .section	eee,"awo", at progbits,n,unique,5
+; CHECK-DAG: .section	eee,"awo", at progbits,n,unique,4

diff  --git a/llvm/test/Linker/Inputs/associated-global.ll b/llvm/test/Linker/Inputs/associated-global.ll
new file mode 100644
index 0000000000000..9df9962ea76f6
--- /dev/null
+++ b/llvm/test/Linker/Inputs/associated-global.ll
@@ -0,0 +1,9 @@
+ at a = global i32 0, !associated !0
+ at b = external global i32, !associated !1
+ at c = internal global i32 1, !associated !2
+ at e = global i32 0, !associated !3
+
+!0 = !{ptr @b}
+!1 = !{ptr @a}
+!2 = !{ptr @e}
+!3 = !{ptr @c}

diff  --git a/llvm/test/Linker/associated-global.ll b/llvm/test/Linker/associated-global.ll
new file mode 100644
index 0000000000000..403a626dd483d
--- /dev/null
+++ b/llvm/test/Linker/associated-global.ll
@@ -0,0 +1,26 @@
+; RUN: llvm-link -S %s %S/Inputs/associated-global.ll | FileCheck %s
+
+; CHECK: @c = internal global i32 1, !associated !0
+; CHECK: @d = global i32 0, !associated !1
+; CHECK: @a = global i32 0, !associated !2
+; CHECK: @b = global i32 0, !associated !3
+; CHECK: @c.3 = internal global i32 1, !associated !4
+; CHECK: @e = global i32 0, !associated !5
+
+; CHECK: !0 = !{ptr @d}
+; CHECK: !1 = !{ptr @c}
+; CHECK: !2 = !{ptr @b}
+; CHECK: !3 = !{ptr @a}
+; CHECK: !4 = !{ptr @e}
+; CHECK: !5 = !{ptr @c.3}
+
+
+ at a = external global i32, !associated !0
+ at b = global i32 0, !associated !1
+ at c = internal global i32 1, !associated !2
+ at d = global i32 0, !associated !3
+
+!0 = !{ptr @b}
+!1 = !{ptr @a}
+!2 = !{ptr @d}
+!3 = !{ptr @c}

diff  --git a/llvm/test/Linker/metadata-global.ll b/llvm/test/Linker/metadata-global.ll
index 219ed944e3aa7..cd0b487447acf 100644
--- a/llvm/test/Linker/metadata-global.ll
+++ b/llvm/test/Linker/metadata-global.ll
@@ -3,9 +3,9 @@
 ; CHECK-DAG: @a = global i32 0
 ; CHECK-DAG: @b = global i32 0, !associated !0
 
-; CHECK-DAG: !0 = !{ptr @b}
+; CHECK-DAG: !0 = !{ptr @a}
 
 @a = global i32 0
 @b = global i32 0, !associated !0
 
-!0 = !{ptr @b}
+!0 = !{ptr @a}

diff  --git a/llvm/test/Verifier/associated-metadata.ll b/llvm/test/Verifier/associated-metadata.ll
new file mode 100644
index 0000000000000..00f30e6b82878
--- /dev/null
+++ b/llvm/test/Verifier/associated-metadata.ll
@@ -0,0 +1,47 @@
+; RUN: not llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s
+
+; CHECK: associated value must be pointer typed
+; CHECK-NEXT: ptr addrspace(1) @associated.int
+; CHECK-NEXT: !0 = !{i32 1}
+ at associated.int = external addrspace(1) constant [8 x i8], !associated !0
+
+; CHECK: associated value must be pointer typed
+; CHECK-NEXT: ptr addrspace(1) @associated.float
+; CHECK-NEXT: !1 = !{float 1.000000e+00}
+ at associated.float = external addrspace(1) constant [8 x i8], !associated !1
+
+; CHECK: associated metadata must have one operand
+; CHECK-NEXT: ptr addrspace(1) @associated.too.many.ops
+; CHECK-NEXT: !2 = !{ptr @gv.decl0, ptr @gv.decl1}
+ at associated.too.many.ops = external addrspace(1) constant [8 x i8], !associated !2
+
+; CHECK: associated metadata must have one operand
+; CHECK-NEXT: ptr addrspace(1) @associated.empty
+; CHECK-NEXT: !3 = !{}
+ at associated.empty = external addrspace(1) constant [8 x i8], !associated !3
+
+; CHECK: associated metadata must have a global value
+; CHECK-NEXT: ptr addrspace(1) @associated.null.metadata
+; CHECK-NEXT: !4 = !{null}
+ at associated.null.metadata = external addrspace(1) constant [8 x i8], !associated !4
+
+; CHECK: global values should not associate to themselves
+; CHECK-NEXT: ptr @associated.self
+; CHECK-NEXT: !5 = !{ptr @associated.self}
+ at associated.self = external constant [8 x i8], !associated !5
+
+; CHECK: associated metadata must be ValueAsMetadata
+; CHECK-NEXT: ptr @associated.string
+; CHECK-NEXT: !6 = !{!"string"}
+ at associated.string = external constant [8 x i8], !associated !6
+
+ at gv.decl0 = external constant [8 x i8]
+ at gv.decl1 = external constant [8 x i8]
+
+!0 = !{i32 1}
+!1 = !{float 1.000000e+00}
+!2 = !{ptr @gv.decl0, ptr @gv.decl1}
+!3 = !{}
+!4 = !{null}
+!5 = !{ptr @associated.self}
+!6 = !{!"string"}


        


More information about the llvm-commits mailing list