Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -5406,9 +5406,10 @@ Unlike instructions, global objects (functions and global variables) may have multiple metadata attachments with the same identifier. -A transformation is required to drop any metadata attachment that it does not -know or know it can't preserve. Currently there is an exception for metadata -attachment to globals for ``!func_sanitize``, ``!type`` and ``!absolute_symbol`` which can't be +A transformation is required to drop any metadata attachment that it +does not know or know it can't preserve. Currently there is an +exception for metadata attachment to globals for ``!func_sanitize``, +``!type``, ``!absolute_symbol`` and ``!associated`` which can't be unconditionally dropped unless the global is itself deleted. Metadata attached to a module using named metadata may not be dropped, with Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -658,7 +658,7 @@ Check(Associated->getNumOperands() == 1, "associated metadata must have one operand", &GV, Associated); const Metadata *Op = Associated->getOperand(0).get(); - Check(Op, "missing associated global", GO, Associated); + Check(Op, "associated metadata must have a global value", GO, Associated); const auto *VM = dyn_cast_or_null(Op); Check(VM, "associated metadata must be ValueAsMetadata", GO, @@ -671,6 +671,9 @@ Check(isa(Stripped) || isa(Stripped), "associated metadata must point to a GlobalObject", GO, Stripped); + Check(Stripped != VM->getValue(), + "global values should not associate to themselves", GO, + Associated); } } } Index: llvm/test/Verifier/associated-metadata.ll =================================================================== --- llvm/test/Verifier/associated-metadata.ll +++ llvm/test/Verifier/associated-metadata.ll @@ -20,6 +20,16 @@ ; CHECK-NEXT: !3 = !{} @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} +@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} +@associated.self = external constant [8 x i8], !associated !5 + @gv.decl0 = external constant [8 x i8] @gv.decl1 = external constant [8 x i8] @@ -27,3 +37,5 @@ !1 = !{float 1.000000e+00} !2 = !{ptr @gv.decl0, ptr @gv.decl1} !3 = !{} +!4 = !{null} +!5 = !{ptr @associated.self}