https://github.com/Men-cotton updated 
https://github.com/llvm/llvm-project/pull/203018

>From 0ece785abb3a460352adc6d0e99249ca16527fa3 Mon Sep 17 00:00:00 2001
From: mencotton <[email protected]>
Date: Mon, 8 Jun 2026 20:51:57 +0900
Subject: [PATCH] [MLIR][LLVM] Add function metadata to LLVMFuncOp

Add a generic LLVM dialect carrier for LLVM IR function metadata on LLVMFuncOp.
Represent attachments as an ordered list so repeated metadata kinds, such as
multiple type metadata attachments, can be preserved while keeping metadata 
names
language-agnostic.
---
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td       | 22 +++++++++++++++++++
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td   |  1 +
 mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp      | 18 +++++++++++++++
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp  |  3 +++
 mlir/test/Dialect/LLVMIR/invalid.mlir         | 20 +++++++++++++++++
 mlir/test/Dialect/LLVMIR/roundtrip.mlir       | 22 +++++++++++++++++++
 6 files changed, 86 insertions(+)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 51211d30ab2a6..0950a4e20cbed 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1788,6 +1788,28 @@ def LLVM_MDNodeArrayAttr
     : TypedArrayAttrBase<LLVM_MDNodeAttr,
                          "array of #llvm.md_node attributes">;
 
+def LLVM_FunctionMetadataAttr
+    : LLVM_Attr<"FunctionMetadata", "func_metadata"> {
+  let summary = "LLVM function metadata attachment";
+  let description = [{
+    Models one LLVM IR function metadata attachment. LLVM IR allows several
+    attachments with the same metadata kind, so function metadata is 
represented
+    as an ordered list of these entries instead of a dictionary.
+
+    Example:
+    ```mlir
+    #llvm.func_metadata<"type", <#llvm.md_string<"id">>>
+    ```
+  }];
+  let parameters = (ins "StringAttr":$metadataName, "MDNodeAttr":$node);
+  let assemblyFormat = "`<` $metadataName `,` $node `>`";
+  let genVerifyDecl = 1;
+}
+
+def LLVM_FunctionMetadataArrayAttr
+    : TypedArrayAttrBase<LLVM_FunctionMetadataAttr,
+                         "array of #llvm.func_metadata attributes">;
+
 def LLVM_AnyMDAttr : AnyAttrOf<[
     LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDGlobalValueAttr,
     LLVM_MDNodeAttr],
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index a06d51ef03c13..d6c3f7ecb1ca6 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2071,6 +2071,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
     OptionalAttr<DenseI32ArrayAttr>:$work_group_size_hint,
     OptionalAttr<DenseI32ArrayAttr>:$reqd_work_group_size,
     OptionalAttr<I32Attr>:$intel_reqd_sub_group_size,
+    OptionalAttr<LLVM_FunctionMetadataArrayAttr>:$function_metadata,
     OptionalAttr<UWTableKindAttr>:$uwtable_kind,
     OptionalAttr<BoolAttr>:$use_sample_profile
   );
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp 
b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 2bd5b42720ee2..0e46d6665e149 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -135,6 +135,24 @@ bool AddressSpaceAttr::isValidPtrIntCast(
   return false;
 }
 
+//===----------------------------------------------------------------------===//
+// FunctionMetadataAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+FunctionMetadataAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                             StringAttr metadataName, MDNodeAttr node) {
+  (void)node;
+  StringRef name = metadataName.getValue();
+  if (name.empty())
+    return emitError() << "function_metadata entry name must not be empty";
+  if (name == "dbg" || name == "prof") {
+    return emitError() << "reserved function_metadata entry '" << name
+                       << "' must use a dedicated LLVM dialect representation";
+  }
+  return success();
+}
+
 
//===----------------------------------------------------------------------===//
 // AliasScopeAttr
 
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp 
b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 7dc35faf12e06..9d9303785a713 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2048,6 +2048,9 @@ LogicalResult 
ModuleTranslation::convertFunctionSignatures() {
     llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
     llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
     mapFunction(function.getName(), llvmFunc);
+    if (function.getFunctionMetadataAttr())
+      return function.emitError()
+             << "not yet implemented: translating function_metadata to LLVM 
IR";
     addRuntimePreemptionSpecifier(function.getDsoLocal(), llvmFunc);
 
     // Convert function attributes.
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir 
b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 98180849223a3..f3f917454f15e 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1847,6 +1847,26 @@ llvm.mlir.alias external @y5 : i32 {
 
 // -----
 
+// expected-error@+1{{attribute 'function_metadata' failed to satisfy 
constraint: array of #llvm.func_metadata attributes}}
+llvm.func @function_metadata_value() attributes {function_metadata = 
[#llvm.md_string<"int">]}
+
+// -----
+
+// expected-error@+1{{function_metadata entry name must not be empty}}
+llvm.func @empty_function_metadata_name() attributes {function_metadata = 
[#llvm.func_metadata<"", #llvm.md_node<#llvm.md_string<"x">>>]}
+
+// -----
+
+// expected-error@+1{{reserved function_metadata entry 'dbg' must use a 
dedicated LLVM dialect representation}}
+llvm.func @reserved_dbg_function_metadata() attributes {function_metadata = 
[#llvm.func_metadata<"dbg", #llvm.md_node<#llvm.md_string<"x">>>]}
+
+// -----
+
+// expected-error@+1{{reserved function_metadata entry 'prof' must use a 
dedicated LLVM dialect representation}}
+llvm.func @reserved_prof_function_metadata() attributes {function_metadata = 
[#llvm.func_metadata<"prof", 
#llvm.md_node<#llvm.md_string<"function_entry_count">, #llvm.md_const<1 : 
i64>>>]}
+
+// -----
+
 // expected-error@+1{{attribute 'nodes' failed to satisfy constraint: array of 
#llvm.md_node attributes}}
 llvm.named_metadata "not_node" [#llvm.md_string<"int">]
 
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir 
b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 608385b541d77..fb9736bb4fb03 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -1230,3 +1230,25 @@ llvm.named_metadata "foo.kernel" [
     >
   >
 ]
+
+// CHECK-LABEL: llvm.func @generic_function_metadata
+// CHECK-SAME: function_metadata
+// CHECK-SAME: #llvm.func_metadata<"annotation", <#llvm.md_string<"function 
annotation">>>
+// CHECK-SAME: #llvm.func_metadata<"type", <#llvm.md_const<0 : i64>, 
#llvm.md_string<"typeid">>>
+llvm.func @generic_function_metadata() attributes {
+  function_metadata = [
+    #llvm.func_metadata<"annotation", #llvm.md_node<#llvm.md_string<"function 
annotation">>>,
+    #llvm.func_metadata<"type", #llvm.md_node<#llvm.md_const<0 : i64>, 
#llvm.md_string<"typeid">>>
+  ]
+}
+
+// CHECK-LABEL: llvm.func @repeated_function_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">>>
+llvm.func @repeated_function_metadata() attributes {
+  function_metadata = [
+    #llvm.func_metadata<"type", #llvm.md_node<#llvm.md_const<0 : i64>, 
#llvm.md_string<"typeid0">>>,
+    #llvm.func_metadata<"type", #llvm.md_node<#llvm.md_const<0 : i64>, 
#llvm.md_string<"typeid1">>>
+  ]
+}

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to