[Mlir-commits] [mlir] c315c9d - [MLIR][LLVM] Preserve unknown function metadata on import (#203022)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Aug 21 02:14:59 PDT 2026


Author: Akimasa Watanuki
Date: 2026-08-21T18:14:53+09:00
New Revision: c315c9dc5d8daa54e681cf59297679647c17355d

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

LOG: [MLIR][LLVM] Preserve unknown function metadata on import (#203022)

Import representable non-debug function metadata without a kind-specific
dialect conversion into `LLVMFuncOp` `function_metadata`. Preserve
repeated metadata kinds through the generic carrier so LLVM IR import
and export can round-trip the supported generic metadata subset.

Warn and drop attachments outside that subset while continuing to import
the function.

Added: 
    mlir/test/Target/LLVMIR/Import/function-metadata.ll

Modified: 
    mlir/lib/Target/LLVMIR/ModuleImport.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 2ab4529ddef53..08b23c0bbdfa4 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -3291,18 +3291,45 @@ LogicalResult ModuleImport::processFunction(llvm::Function *func) {
   // Handle Function attributes.
   processFunctionAttributes(func, funcOp);
 
-  // Convert non-debug metadata by using the dialect interface.
+  // Convert non-debug metadata by using the dialect interface. Metadata without
+  // a kind-specific conversion is preserved in the generic function metadata
+  // carrier.
   SmallVector<std::pair<unsigned, llvm::MDNode *>> allMetadata;
   func->getAllMetadata(allMetadata);
+  SmallVector<StringRef> metadataNames;
+  llvmModule->getMDKindNames(metadataNames);
+  SmallVector<Attribute> functionMetadata;
   for (auto &[kind, node] : allMetadata) {
-    if (!iface.isConvertibleMetadata(kind))
+    if (kind == llvm::LLVMContext::MD_dbg)
       continue;
-    if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *this))) {
+
+    llvm::MDNode *metadataNode = node;
+    auto emitUnhandledFunctionMetadataWarning = [&]() {
       emitWarning(funcOp.getLoc())
-          << "unhandled function metadata: " << diagMD(node, llvmModule.get())
-          << " on " << diag(*func);
+          << "unhandled function metadata: "
+          << diagMD(metadataNode, llvmModule.get()) << " on " << diag(*func);
+    };
+
+    if (iface.isConvertibleMetadata(kind)) {
+      if (succeeded(iface.setMetadataAttrs(builder, kind, metadataNode, funcOp,
+                                           *this)))
+        continue;
+      emitUnhandledFunctionMetadataWarning();
+      continue;
     }
+
+    Attribute nodeAttr = convertMetadataToAttr(metadataNode);
+    auto mdNodeAttr = dyn_cast_if_present<LLVM::MDNodeAttr>(nodeAttr);
+    if (!mdNodeAttr || kind >= metadataNames.size()) {
+      emitUnhandledFunctionMetadataWarning();
+      continue;
+    }
+
+    functionMetadata.push_back(LLVM::FunctionMetadataAttr::get(
+        context, builder.getStringAttr(metadataNames[kind]), mdNodeAttr));
   }
+  if (!functionMetadata.empty())
+    funcOp.setFunctionMetadataAttr(builder.getArrayAttr(functionMetadata));
 
   if (func->isDeclaration())
     return success();

diff  --git a/mlir/test/Target/LLVMIR/Import/function-metadata.ll b/mlir/test/Target/LLVMIR/Import/function-metadata.ll
new file mode 100644
index 0000000000000..f74f1bb1216c7
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/function-metadata.ll
@@ -0,0 +1,124 @@
+; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
+; RUN: mlir-translate -import-llvm -split-input-file %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+
+; CHECK-LABEL: llvm.func @repeated_type_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"type", <#llvm.md_const<0 : i64>, #llvm.md_string<"typeid0">>>
+; CHECK-SAME: #llvm.func_metadata<"type", <#llvm.md_const<0 : i64>, #llvm.md_string<"typeid1">>>
+define void @repeated_type_metadata() !type !0 !type !1 {
+  ret void
+}
+
+!0 = !{i64 0, !"typeid0"}
+!1 = !{i64 0, !"typeid1"}
+
+; // -----
+
+; CHECK-LABEL: llvm.func @declaration_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"annotation", <#llvm.md_string<"declaration annotation">>>
+declare !annotation !0 void @declaration_metadata()
+
+!0 = !{!"declaration annotation"}
+
+; // -----
+
+declare void @callee()
+
+; CHECK-LABEL: llvm.func @function_ref_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"callees", <#llvm.md_global_value<@callee>>>
+define void @function_ref_metadata() !callees !0 {
+  ret void
+}
+
+!0 = !{ptr @callee}
+
+; // -----
+
+define void @alias_target() {
+  ret void
+}
+ at alias = alias void (), ptr @alias_target
+
+; CHECK-LABEL: llvm.func @alias_ref_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"callees", <#llvm.md_global_value<@alias>>>
+define void @alias_ref_metadata() !callees !0 {
+  ret void
+}
+
+!0 = !{ptr @alias}
+
+; // -----
+
+ at global = global i32 0
+
+; CHECK-LABEL: llvm.func @global_ref_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"callees", <#llvm.md_global_value<@global>>>
+define void @global_ref_metadata() !callees !0 {
+  ret void
+}
+
+!0 = !{ptr @global}
+
+; // -----
+
+ at 0 = global i32 0
+
+; CHECK-LABEL: llvm.func @nameless_global_ref_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"callees", <#llvm.md_global_value<@{{mlir\.llvm\.nameless_global_[0-9]+}}>>>
+define void @nameless_global_ref_metadata() !callees !0 {
+  ret void
+}
+
+!0 = !{ptr @0}
+
+; // -----
+
+ at ifunc = ifunc void (), ptr @ifunc_resolver
+define ptr @ifunc_resolver() {
+  ret ptr @ifunc_target
+}
+define void @ifunc_target() {
+  ret void
+}
+
+; CHECK-LABEL: llvm.func @ifunc_ref_metadata
+; CHECK-SAME: function_metadata
+; CHECK-SAME: #llvm.func_metadata<"callees", <#llvm.md_global_value<@ifunc>>>
+define void @ifunc_ref_metadata() !callees !0 {
+  ret void
+}
+
+!0 = !{ptr @ifunc}
+
+; // -----
+
+; WARN: warning: unhandled function metadata:
+; WARN-SAME: !{{[0-9]+}} = !{!"unknown", !"sample-pass"}
+; WARN-SAME: on define void @unknown_profile_metadata()
+; CHECK-LABEL: llvm.func @unknown_profile_metadata()
+; CHECK-NOT: function_metadata
+; CHECK: llvm.return
+define void @unknown_profile_metadata() !prof !0 {
+  ret void
+}
+
+!0 = !{!"unknown", !"sample-pass"}
+
+; // -----
+
+; WARN: warning: unhandled function metadata:
+; WARN-SAME: !{{[0-9]+}} = distinct !{!"identity"}
+; WARN-SAME: on define void @distinct_metadata()
+; CHECK-LABEL: llvm.func @distinct_metadata()
+; CHECK-NOT: function_metadata
+; CHECK: llvm.return
+define void @distinct_metadata() !annotation !0 {
+  ret void
+}
+
+!0 = distinct !{!"identity"}


        


More information about the Mlir-commits mailing list