[llvm] 74bea4c - [IR] enable attaching metadata on ifuncs (#158732)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 19 08:42:02 PDT 2025
Author: Wael Yehia
Date: 2025-09-19T11:41:57-04:00
New Revision: 74bea4c1ad34c9044b9e02f7f9688a408676df75
URL: https://github.com/llvm/llvm-project/commit/74bea4c1ad34c9044b9e02f7f9688a408676df75
DIFF: https://github.com/llvm/llvm-project/commit/74bea4c1ad34c9044b9e02f7f9688a408676df75.diff
LOG: [IR] enable attaching metadata on ifuncs (#158732)
Teach the IR parser and writer to support metadata on ifuncs, and update
documentation.
In PR #153049, we have a use case of attaching the `!associated`
metadata to an ifunc.
Since an ifunc is similar to a function declaration, it seems natural to
allow metadata on ifuncs.
Currently, the metadata API allows adding Metadata to
llvm::GlobalObject, so the in-memory IR allows for metadata on ifuncs,
but the IR reader/writer is not aware of that.
---------
Co-authored-by: Wael Yehia <wyehia at ca.ibm.com>
Added:
Modified:
llvm/docs/LangRef.rst
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/Verifier.cpp
llvm/test/Assembler/metadata.ll
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5fd0f6573bb97..e6713c827d6ab 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1022,13 +1022,14 @@ On ELF platforms, IFuncs are resolved by the dynamic linker at load time. On
Mach-O platforms, they are lowered in terms of ``.symbol_resolver`` functions,
which lazily resolve the callee the first time they are called.
-IFunc may have an optional :ref:`linkage type <linkage>` and an optional
-:ref:`visibility style <visibility>`.
+IFunc may have an optional :ref:`linkage type <linkage>`, an optional
+:ref:`visibility style <visibility>`, an option partition, and an optional
+list of attached :ref:`metadata <metadata>`.
Syntax::
@<Name> = [Linkage] [PreemptionSpecifier] [Visibility] ifunc <IFuncTy>, <ResolverTy>* @<Resolver>
- [, partition "name"]
+ [, partition "name"] (, !name !N)*
.. _langref_comdats:
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 1bc2906f63b07..8739b24d4b74b 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1258,6 +1258,9 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID,
GV->setPartition(Lex.getStrVal());
if (parseToken(lltok::StringConstant, "expected partition string"))
return true;
+ } else if (!IsAlias && Lex.getKind() == lltok::MetadataVar) {
+ if (parseGlobalObjectMetadataAttachment(*GI.get()))
+ return true;
} else {
return tokError("unknown alias or ifunc property!");
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a1d5b36bde64d..c4070e1f44688 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -2626,6 +2626,9 @@ void ModuleBitcodeWriter::writeModuleMetadata() {
for (const Function &F : M)
if (F.isDeclaration() && F.hasMetadata())
AddDeclAttachedMetadata(F);
+ for (const GlobalIFunc &GI : M.ifuncs())
+ if (GI.hasMetadata())
+ AddDeclAttachedMetadata(GI);
// FIXME: Only store metadata for declarations here, and move data for global
// variable definitions to a separate block (PR28134).
for (const GlobalVariable &GV : M.globals())
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index e133abe577c22..f497c574ee75d 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -495,6 +495,12 @@ ValueEnumerator::ValueEnumerator(const Module &M,
EnumerateMetadata(&F, Op);
}
}
+ for (const GlobalIFunc &GIF : M.ifuncs()) {
+ MDs.clear();
+ GIF.getAllMetadata(MDs);
+ for (const auto &I : MDs)
+ EnumerateMetadata(nullptr, I.second);
+ }
// Optimize constant ordering.
OptimizeConstants(FirstConstant, Values.size());
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 094678f32af2b..60e86d4d2b5a5 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1080,6 +1080,7 @@ void SlotTracker::processModule() {
for (const GlobalIFunc &I : TheModule->ifuncs()) {
if (!I.hasName())
CreateModuleSlot(&I);
+ processGlobalObjectMetadata(I);
}
// Add metadata used by named metadata.
@@ -4079,6 +4080,11 @@ void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
printEscapedString(GI->getPartition(), Out);
Out << '"';
}
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ GI->getAllMetadata(MDs);
+ if (!MDs.empty()) {
+ printMetadataAttachments(MDs, ", ");
+ }
printInfoComment(*GI);
Out << '\n';
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e9ee130dd5e91..17cbfa2458375 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -999,6 +999,18 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
}
void Verifier::visitGlobalIFunc(const GlobalIFunc &GI) {
+ visitGlobalValue(GI);
+
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ GI.getAllMetadata(MDs);
+ for (const auto &I : MDs) {
+ CheckDI(I.first != LLVMContext::MD_dbg,
+ "an ifunc may not have a !dbg attachment", &GI);
+ Check(I.first != LLVMContext::MD_prof,
+ "an ifunc may not have a !prof attachment", &GI);
+ visitMDNode(*I.second, AreDebugLocsAllowed::No);
+ }
+
Check(GlobalIFunc::isValidLinkage(GI.getLinkage()),
"IFunc should have private, internal, linkonce, weak, linkonce_odr, "
"weak_odr, or external linkage!",
diff --git a/llvm/test/Assembler/metadata.ll b/llvm/test/Assembler/metadata.ll
index 5b62bfafa6d7d..b1fb720eb31f9 100644
--- a/llvm/test/Assembler/metadata.ll
+++ b/llvm/test/Assembler/metadata.ll
@@ -5,6 +5,14 @@
; CHECK-UNMAT: @global = global i32 0, !foo [[M2:![0-9]+]], !foo [[M3:![0-9]+]], !baz [[M3]]
@global = global i32 0, !foo !2, !foo !3, !baz !3
+; CHECK-UNMAT: @ifunc_func = ifunc void (...), ptr @resolver, !foo [[M2]]
+ at ifunc_func = ifunc void (...), ptr @resolver, !foo !2
+
+define internal ptr @resolver() {
+entry:
+ ret ptr @test
+}
+
; CHECK-LABEL: @test
; CHECK: ret void, !foo [[M0:![0-9]+]], !bar [[M1:![0-9]+]]
define void @test() !dbg !1 {
More information about the llvm-commits
mailing list