[Mlir-commits] [mlir] [MLIR][LLVM] Share LLVM metadata attribute translation (PR #203016)

Akimasa Watanuki llvmlistbot at llvm.org
Fri Jun 12 06:24:53 PDT 2026


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

>From caae8f80cbffae7206e38d20500cc2299feb8e4f Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Mon, 8 Jun 2026 20:51:28 +0900
Subject: [PATCH 1/3] [MLIR][LLVM] Share LLVM metadata attribute translation

Share LLVM dialect metadata materialization through ModuleTranslation so named
metadata and metadata-as-value lowering use one conversion path. Resolve metadata
symbol references to functions, globals, aliases, and ifuncs, and diagnose
malformed required metadata before lowering.
---
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td       |  4 ++
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td   | 21 ++++---
 .../mlir/Target/LLVMIR/ModuleTranslation.h    |  9 +++
 .../LLVMIR/LLVMToLLVMIRTranslation.cpp        | 61 ++++++-------------
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp  | 50 +++++++++++++++
 mlir/test/Dialect/LLVMIR/call-intrin.mlir     | 13 ++++
 mlir/test/Dialect/LLVMIR/invalid.mlir         |  5 ++
 mlir/test/Target/LLVMIR/llvmir-invalid.mlir   | 17 ++++++
 .../Target/LLVMIR/llvmir-named-metadata.mlir  | 31 ++++++++++
 9 files changed, 159 insertions(+), 52 deletions(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 56f3afba6a030..4cf4771664290 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1784,6 +1784,10 @@ def LLVM_MDNodeAttr : LLVM_Attr<"MDNode", "md_node"> {
   let assemblyFormat = "`<` (`>`) : ($operands^ `>`)?";
 }
 
+def LLVM_MDNodeArrayAttr
+    : TypedArrayAttrBase<LLVM_MDNodeAttr,
+                         "array of #llvm.md_node attributes">;
+
 def LLVM_AnyMDAttr : AnyAttrOf<[
     LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDFuncAttr, LLVM_MDNodeAttr],
     "LLVM metadata attribute (md_string, md_const, md_func, or md_node)">;
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 85b768f2f6755..c813d71fdc773 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2521,7 +2521,8 @@ def LLVM_MetadataAsValueOp
 
     * `#llvm.md_string<"...">` -> `llvm::MDString`.
     * `#llvm.md_const<...>` -> `llvm::ConstantAsMetadata`.
-    * `#llvm.md_func<@symbol>` -> `llvm::ValueAsMetadata` of a function.
+    * `#llvm.md_func<@symbol>` -> `llvm::ValueAsMetadata` of a function or
+      global value.
     * `#llvm.md_node<...>` -> `llvm::MDNode` over any of the above.
 
     These can be nested arbitrarily to form metadata trees. Lowering to LLVM
@@ -2555,12 +2556,14 @@ def LLVM_MetadataAsValueOp
   ];
 
   let llvmBuilder = [{
-    ::llvm::Metadata *md = convertMetadataAttr(
-        op.getMetadataAttr(), builder, moduleTranslation);
-    if (!md)
-      return ::mlir::emitError(op.getLoc(),
-          "llvm.mlir.metadata_as_value: cannot lower metadata attribute");
-    $res = ::llvm::MetadataAsValue::get(builder.getContext(), md);
+    ::mlir::FailureOr<::llvm::Metadata *> md =
+        moduleTranslation.convertMetadataAttr(op.getMetadataAttr(), [&]() {
+          return ::mlir::emitError(op.getLoc(),
+              "llvm.mlir.metadata_as_value: cannot lower metadata attribute: ");
+        });
+    if (::mlir::failed(md))
+      return ::mlir::failure();
+    $res = ::llvm::MetadataAsValue::get(builder.getContext(), *md);
   }];
 
   let hasFolder = 1;
@@ -2705,13 +2708,13 @@ def LLVM_NamedMetadataOp
     ]
     ```
   }];
-  let arguments = (ins StrAttr:$metadata_name, ArrayAttr:$nodes);
+  let arguments = (ins StrAttr:$metadata_name, LLVM_MDNodeArrayAttr:$nodes);
   let assemblyFormat = [{
     $metadata_name $nodes attr-dict
   }];
 
   let llvmBuilder = [{
-    convertNamedMetadataOp($metadata_name, $nodes, builder, moduleTranslation);
+    return convertNamedMetadataOp(op, moduleTranslation);
   }];
 }
 
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index c5c4b105ee152..b23f78ff0f98a 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -19,6 +19,7 @@
 #include "mlir/IR/Operation.h"
 #include "mlir/IR/SymbolTable.h"
 #include "mlir/IR/Value.h"
+#include "mlir/Support/LLVM.h"
 #include "mlir/Support/StateStack.h"
 #include "mlir/Target/LLVMIR/Export.h"
 #include "mlir/Target/LLVMIR/LLVMTranslationInterface.h"
@@ -34,6 +35,7 @@ class CallBase;
 class CanonicalLoopInfo;
 class Function;
 class IRBuilderBase;
+class Metadata;
 class OpenMPIRBuilder;
 class Value;
 namespace vfs {
@@ -345,6 +347,13 @@ class ModuleTranslation {
   /// it if it does not exist.
   llvm::NamedMDNode *getOrInsertNamedModuleMetadata(StringRef name);
 
+  /// Converts an LLVM dialect metadata attribute to LLVM IR metadata.
+  /// Returns failure and emits a diagnostic using `emitError` if the attribute
+  /// cannot be converted.
+  FailureOr<llvm::Metadata *>
+  convertMetadataAttr(Attribute attr,
+                      function_ref<InFlightDiagnostic()> emitError);
+
   /// Creates a stack frame of type `T` on ModuleTranslation stack. `T` must
   /// be derived from `StackFrameBase<T>` and constructible from the provided
   /// arguments. Doing this before entering the region of the op being
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 5474689c9b0b5..1e7a6072eadd5 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -210,52 +210,27 @@ convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
   return success();
 }
 
-/// Recursively converts an MLIR metadata attribute to an LLVM metadata node.
-static llvm::Metadata *
-convertMetadataAttr(Attribute attr, llvm::IRBuilderBase &builder,
-                    LLVM::ModuleTranslation &moduleTranslation) {
-  return llvm::TypeSwitch<Attribute, llvm::Metadata *>(attr)
-      .Case<LLVM::MDStringAttr>([&](auto a) -> llvm::Metadata * {
-        return llvm::MDString::get(builder.getContext(),
-                                   a.getValue().getValue());
-      })
-      .Case<LLVM::MDConstantAttr>([&](auto a) -> llvm::Metadata * {
-        IntegerAttr intAttr = llvm::dyn_cast<IntegerAttr>(a.getValue());
-        if (!intAttr)
-          return nullptr;
-        return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
-            llvm::Type::getIntNTy(builder.getContext(),
-                                  intAttr.getType().getIntOrFloatBitWidth()),
-            intAttr.getValue()));
-      })
-      .Case<LLVM::MDFuncAttr>([&](auto a) -> llvm::Metadata * {
-        if (llvm::Function *fn =
-                moduleTranslation.lookupFunction(a.getName().getValue()))
-          return llvm::ValueAsMetadata::get(fn);
-        return nullptr;
-      })
-      .Case<LLVM::MDNodeAttr>([&](auto a) -> llvm::Metadata * {
-        SmallVector<llvm::Metadata *> operands;
-        for (Attribute op : a.getOperands())
-          operands.push_back(
-              convertMetadataAttr(op, builder, moduleTranslation));
-        return llvm::MDNode::get(builder.getContext(), operands);
-      })
-      .Default([](auto) -> llvm::Metadata * { return nullptr; });
-}
-
-static void convertNamedMetadataOp(StringRef metadataName, ArrayAttr nodes,
-                                   llvm::IRBuilderBase &builder,
-                                   LLVM::ModuleTranslation &moduleTranslation) {
+static LogicalResult
+convertNamedMetadataOp(NamedMetadataOp op,
+                       LLVM::ModuleTranslation &moduleTranslation) {
   llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
   llvm::NamedMDNode *namedMD =
-      llvmModule->getOrInsertNamedMetadata(metadataName);
-  for (Attribute nodeAttr : nodes) {
-    llvm::Metadata *md =
-        convertMetadataAttr(nodeAttr, builder, moduleTranslation);
-    if (auto *mdNode = llvm::dyn_cast_or_null<llvm::MDNode>(md))
-      namedMD->addOperand(mdNode);
+      llvmModule->getOrInsertNamedMetadata(op.getMetadataName());
+  for (Attribute nodeAttr : op.getNodes()) {
+    FailureOr<llvm::Metadata *> md =
+        moduleTranslation.convertMetadataAttr(nodeAttr, [&]() {
+          return op.emitError() << "failed to convert named metadata '"
+                                << op.getMetadataName() << "': ";
+        });
+    if (failed(md))
+      return failure();
+    auto *mdNode = llvm::dyn_cast_if_present<llvm::MDNode>(*md);
+    if (!mdNode)
+      return op.emitError() << "failed to convert named metadata '"
+                            << op.getMetadataName() << "'";
+    namedMD->addOperand(mdNode);
   }
+  return success();
 }
 
 static void convertLinkerOptionsOp(ArrayAttr options,
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 01d3e9c4a62ce..7d3a4c6346b0a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1567,6 +1567,56 @@ static llvm::MDNode *convertIntegerArrayToMDNode(llvm::LLVMContext &context,
   return llvm::MDNode::get(context, mdValues);
 }
 
+FailureOr<llvm::Metadata *> ModuleTranslation::convertMetadataAttr(
+    Attribute attr, function_ref<InFlightDiagnostic()> emitError) {
+  llvm::LLVMContext &llvmContext = getLLVMContext();
+
+  return llvm::TypeSwitch<Attribute, FailureOr<llvm::Metadata *>>(attr)
+      .Case<MDStringAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
+        return llvm::MDString::get(llvmContext, a.getValue().getValue());
+      })
+      .Case<MDConstantAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
+        IntegerAttr intAttr = llvm::dyn_cast<IntegerAttr>(a.getValue());
+        if (!intAttr)
+          return emitError()
+                 << "expected integer attribute in metadata constant";
+        return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+            llvm::Type::getIntNTy(llvmContext,
+                                  intAttr.getType().getIntOrFloatBitWidth()),
+            intAttr.getValue()));
+      })
+      .Case<MDFuncAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
+        if (llvm::Function *fn = lookupFunction(a.getName().getValue()))
+          return llvm::ValueAsMetadata::get(fn);
+        if (llvm::GlobalValue *global = lookupGlobal(a.getName().getValue()))
+          return llvm::ValueAsMetadata::get(global);
+        Operation *symbol =
+            symbolTable().lookupSymbolIn(mlirModule, a.getName());
+        if (auto alias = dyn_cast_if_present<LLVM::AliasOp>(symbol))
+          if (llvm::GlobalValue *global = lookupAlias(alias))
+            return llvm::ValueAsMetadata::get(global);
+        if (auto ifunc = dyn_cast_if_present<LLVM::IFuncOp>(symbol))
+          if (llvm::GlobalValue *global = lookupIFunc(ifunc))
+            return llvm::ValueAsMetadata::get(global);
+        return emitError() << "could not resolve metadata reference '"
+                           << a.getName() << "'";
+      })
+      .Case<MDNodeAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
+        SmallVector<llvm::Metadata *> operands;
+        for (Attribute operand : a.getOperands()) {
+          FailureOr<llvm::Metadata *> md =
+              convertMetadataAttr(operand, emitError);
+          if (failed(md))
+            return failure();
+          operands.push_back(*md);
+        }
+        return llvm::MDNode::get(llvmContext, operands);
+      })
+      .Default([&](Attribute attr) -> FailureOr<llvm::Metadata *> {
+        return emitError() << "unsupported LLVM metadata attribute " << attr;
+      });
+}
+
 LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
   // Clear the block, branch value mappings, they are only relevant within one
   // function.
diff --git a/mlir/test/Dialect/LLVMIR/call-intrin.mlir b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
index 7a12e09eb6480..e0e1127e24aca 100644
--- a/mlir/test/Dialect/LLVMIR/call-intrin.mlir
+++ b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
@@ -146,3 +146,16 @@ llvm.func @read_named_register() -> i32 {
       : (!llvm.metadata) -> i32
   llvm.return %r : i32
 }
+
+// -----
+
+llvm.mlir.global internal @metadata_global(0 : i32) : i32
+
+// CHECK-LABEL: define i32 @read_global_ref_metadata()
+// CHECK: call i32 @llvm.read_register.i32(metadata ptr @metadata_global)
+llvm.func @read_global_ref_metadata() -> i32 {
+  %md = llvm.mlir.metadata_as_value #llvm.md_node<#llvm.md_func<@metadata_global>>
+  %r = llvm.call_intrinsic "llvm.read_register.i32"(%md)
+      : (!llvm.metadata) -> i32
+  llvm.return %r : i32
+}
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index e80094df1eed2..98180849223a3 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1847,6 +1847,11 @@ llvm.mlir.alias external @y5 : i32 {
 
 // -----
 
+// expected-error at +1{{attribute 'nodes' failed to satisfy constraint: array of #llvm.md_node attributes}}
+llvm.named_metadata "not_node" [#llvm.md_string<"int">]
+
+// -----
+
 module {
   llvm.func @foo()
 
diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
index c263afe553750..ef6681ca3821f 100644
--- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
@@ -305,6 +305,23 @@ module attributes {} {
 
 // -----
 
+// expected-error @below{{failed to convert named metadata 'bad': expected integer attribute in metadata constant}}
+// expected-error @below{{LLVM Translation failed for operation: llvm.named_metadata}}
+llvm.named_metadata "bad" [
+  #llvm.md_node<#llvm.md_const<"not an integer">>
+]
+
+// -----
+
+llvm.func @bad_metadata_as_value() {
+  // expected-error @below{{llvm.mlir.metadata_as_value: cannot lower metadata attribute: expected integer attribute in metadata constant}}
+  // expected-error @below{{LLVM Translation failed for operation: llvm.mlir.metadata_as_value}}
+  %0 = llvm.mlir.metadata_as_value #llvm.md_node<#llvm.md_const<"not an integer">>
+  llvm.return
+}
+
+// -----
+
 module @does_not_exist {
   // expected-error @below{{resource does not exist}}
   llvm.mlir.global internal constant @constant(dense_resource<test0> : tensor<4xf32>) : !llvm.array<4 x f32>
diff --git a/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir b/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
index 493616430c822..9f09062c2a44b 100644
--- a/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
@@ -5,11 +5,34 @@
 // CHECK: !foo.version = !{![[VERSION:[0-9]+]]}
 // CHECK: !foo.language_version = !{![[LANG:[0-9]+]]}
 // CHECK: !foo.kernel = !{![[KERNEL:[0-9]+]]}
+// CHECK: !foo.global_refs = !{![[GLOBAL_REFS:[0-9]+]]}
 
 llvm.func @my_kernel() {
   llvm.return
 }
 
+llvm.mlir.global internal @metadata_global(0 : i32) : i32
+
+llvm.func @metadata_alias_target() {
+  llvm.return
+}
+
+llvm.mlir.alias external @metadata_alias : !llvm.func<void ()> {
+  %0 = llvm.mlir.addressof @metadata_alias_target : !llvm.ptr
+  llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.ifunc external @metadata_ifunc : !llvm.func<void ()>, !llvm.ptr @metadata_ifunc_resolver
+
+llvm.func @metadata_ifunc_resolver() -> !llvm.ptr {
+  %0 = llvm.mlir.addressof @metadata_ifunc_target : !llvm.ptr
+  llvm.return %0 : !llvm.ptr
+}
+
+llvm.func @metadata_ifunc_target() {
+  llvm.return
+}
+
 llvm.named_metadata "foo.version" [
   #llvm.md_node<#llvm.md_const<1 : i32>,
                 #llvm.md_const<0 : i32>,
@@ -43,3 +66,11 @@ llvm.named_metadata "foo.kernel" [
 // CHECK-DAG: ![[KERNEL]] = !{ptr @my_kernel, ![[EMPTY:[0-9]+]], ![[ARGS:[0-9]+]]}
 // CHECK-DAG: ![[EMPTY]] = !{}
 // CHECK-DAG: ![[ARGS]] = !{![[A0]]}
+
+llvm.named_metadata "foo.global_refs" [
+  #llvm.md_node<
+    #llvm.md_func<@metadata_global>,
+    #llvm.md_func<@metadata_alias>,
+    #llvm.md_func<@metadata_ifunc>>
+]
+// CHECK-DAG: ![[GLOBAL_REFS]] = !{ptr @metadata_global, ptr @metadata_alias, ptr @metadata_ifunc}

>From 42a87bdc7e97eca6323c3009092c13c0928400d5 Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Fri, 12 Jun 2026 21:57:41 +0900
Subject: [PATCH 2/3] fix: delete invalid test (read_global_ref_metadata)

---
 mlir/test/Dialect/LLVMIR/call-intrin.mlir | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/mlir/test/Dialect/LLVMIR/call-intrin.mlir b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
index e0e1127e24aca..7a12e09eb6480 100644
--- a/mlir/test/Dialect/LLVMIR/call-intrin.mlir
+++ b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
@@ -146,16 +146,3 @@ llvm.func @read_named_register() -> i32 {
       : (!llvm.metadata) -> i32
   llvm.return %r : i32
 }
-
-// -----
-
-llvm.mlir.global internal @metadata_global(0 : i32) : i32
-
-// CHECK-LABEL: define i32 @read_global_ref_metadata()
-// CHECK: call i32 @llvm.read_register.i32(metadata ptr @metadata_global)
-llvm.func @read_global_ref_metadata() -> i32 {
-  %md = llvm.mlir.metadata_as_value #llvm.md_node<#llvm.md_func<@metadata_global>>
-  %r = llvm.call_intrinsic "llvm.read_register.i32"(%md)
-      : (!llvm.metadata) -> i32
-  llvm.return %r : i32
-}

>From 0eaca71c36553e84db7ba25acba36db0cdcb07a9 Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Fri, 12 Jun 2026 21:51:03 +0900
Subject: [PATCH 3/3] fix: rename `MDFunc` to `MDValue`

---
 mlir/include/mlir-c/Dialect/LLVM.h             | 18 +++++++++---------
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td        | 16 ++++++++--------
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td    |  6 +++---
 mlir/lib/Bindings/Python/DialectLLVM.cpp       | 18 +++++++++---------
 mlir/lib/CAPI/Dialect/LLVM.cpp                 | 16 ++++++++--------
 mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp     |  2 +-
 mlir/lib/Target/LLVMIR/ModuleImport.cpp        |  2 +-
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp   |  2 +-
 mlir/test/Dialect/LLVMIR/roundtrip.mlir        |  8 ++++----
 .../Target/LLVMIR/llvmir-named-metadata.mlir   |  8 ++++----
 mlir/test/python/dialects/llvm.py              | 14 +++++++-------
 11 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 09d3ad198a3b2..db48cf538ed51 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -510,18 +510,18 @@ MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDConstantAttrGetTypeID(void);
 MLIR_CAPI_EXPORTED MlirAttribute
 mlirLLVMMDConstantAttrGetValue(MlirAttribute attr);
 
-/// Creates an LLVM MDFuncAttr referencing a function symbol.
-MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDFuncAttrGet(MlirContext ctx,
-                                                       MlirAttribute name);
+/// Creates an LLVM MDValueAttr referencing a symbol-backed value.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDValueAttrGet(MlirContext ctx,
+                                                        MlirAttribute name);
 
-/// Returns `true` if the attribute is an LLVM MDFuncAttr.
-MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDFuncAttr(MlirAttribute attr);
+/// Returns `true` if the attribute is an LLVM MDValueAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDValueAttr(MlirAttribute attr);
 
-/// Returns the TypeID of MDFuncAttr.
-MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void);
+/// Returns the TypeID of MDValueAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDValueAttrGetTypeID(void);
 
-/// Returns the symbol name of an LLVM MDFuncAttr.
-MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr);
+/// Returns the symbol name of an LLVM MDValueAttr.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDValueAttrGetName(MlirAttribute attr);
 
 /// Creates an LLVM MDNodeAttr.
 MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDNodeAttrGet(
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 4cf4771664290..831dcecd0fc93 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1752,15 +1752,15 @@ def LLVM_MDConstantAttr : LLVM_Attr<"MDConstant", "md_const"> {
   let assemblyFormat = "`<` $value `>`";
 }
 
-def LLVM_MDFuncAttr : LLVM_Attr<"MDFunc", "md_func"> {
-  let summary = "LLVM function-as-metadata";
+def LLVM_MDValueAttr : LLVM_Attr<"MDValue", "md_value"> {
+  let summary = "LLVM value-as-metadata";
   let description = [{
-    References a function (or global) symbol as LLVM metadata, corresponding
-    to `llvm::ValueAsMetadata::get(function)` in LLVM IR.
+    References a symbol-backed value as LLVM metadata, corresponding to
+    `llvm::ValueAsMetadata::get(value)` in LLVM IR.
 
     Example:
     ```mlir
-    #llvm.md_func<@my_kernel>
+    #llvm.md_value<@my_kernel>
     ```
   }];
   let parameters = (ins "FlatSymbolRefAttr":$name);
@@ -1772,7 +1772,7 @@ def LLVM_MDNodeAttr : LLVM_Attr<"MDNode", "md_node"> {
   let description = [{
     Represents an LLVM metadata node. The operands
     can be any combination of metadata attributes: `#llvm.md_string`,
-    `#llvm.md_const`, `#llvm.md_func`, or nested `#llvm.md_node`.
+    `#llvm.md_const`, `#llvm.md_value`, or nested `#llvm.md_node`.
 
     Example:
     ```mlir
@@ -1789,7 +1789,7 @@ def LLVM_MDNodeArrayAttr
                          "array of #llvm.md_node attributes">;
 
 def LLVM_AnyMDAttr : AnyAttrOf<[
-    LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDFuncAttr, LLVM_MDNodeAttr],
-    "LLVM metadata attribute (md_string, md_const, md_func, or md_node)">;
+    LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDValueAttr, LLVM_MDNodeAttr],
+    "LLVM metadata attribute (md_string, md_const, md_value, or md_node)">;
 
 #endif // LLVMIR_ATTRDEFS
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index c813d71fdc773..6fda732baa77b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2521,8 +2521,8 @@ def LLVM_MetadataAsValueOp
 
     * `#llvm.md_string<"...">` -> `llvm::MDString`.
     * `#llvm.md_const<...>` -> `llvm::ConstantAsMetadata`.
-    * `#llvm.md_func<@symbol>` -> `llvm::ValueAsMetadata` of a function or
-      global value.
+    * `#llvm.md_value<@symbol>` -> `llvm::ValueAsMetadata` of a
+      symbol-backed value.
     * `#llvm.md_node<...>` -> `llvm::MDNode` over any of the above.
 
     These can be nested arbitrarily to form metadata trees. Lowering to LLVM
@@ -2697,7 +2697,7 @@ def LLVM_NamedMetadataOp
     ]
     llvm.named_metadata "foo.kernel" [
       #llvm.md_node<
-        #llvm.md_func<@my_kernel>,
+        #llvm.md_value<@my_kernel>,
         #llvm.md_node<>,
         #llvm.md_node<
           #llvm.md_node<#llvm.md_const<0 : i32>,
diff --git a/mlir/lib/Bindings/Python/DialectLLVM.cpp b/mlir/lib/Bindings/Python/DialectLLVM.cpp
index 7e4f24b556613..eb864194ff698 100644
--- a/mlir/lib/Bindings/Python/DialectLLVM.cpp
+++ b/mlir/lib/Bindings/Python/DialectLLVM.cpp
@@ -321,11 +321,11 @@ struct MDConstantAttr : PyConcreteAttribute<MDConstantAttr> {
   }
 };
 
-struct MDFuncAttr : PyConcreteAttribute<MDFuncAttr> {
-  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDFuncAttr;
+struct MDValueAttr : PyConcreteAttribute<MDValueAttr> {
+  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDValueAttr;
   static constexpr GetTypeIDFunctionTy getTypeIdFunction =
-      mlirLLVMMDFuncAttrGetTypeID;
-  static constexpr const char *pyClassName = "MDFuncAttr";
+      mlirLLVMMDValueAttrGetTypeID;
+  static constexpr const char *pyClassName = "MDValueAttr";
   using Base::Base;
 
   static void bindDerived(ClassTy &c) {
@@ -335,13 +335,13 @@ struct MDFuncAttr : PyConcreteAttribute<MDFuncAttr> {
           MlirAttribute symRef = mlirFlatSymbolRefAttrGet(
               context.get()->get(),
               mlirStringRefCreate(name.data(), name.size()));
-          return MDFuncAttr(
+          return MDValueAttr(
               context->getRef(),
-              mlirLLVMMDFuncAttrGet(context.get()->get(), symRef));
+              mlirLLVMMDValueAttrGet(context.get()->get(), symRef));
         },
         "name"_a, nb::kw_only(), "context"_a = nb::none());
-    c.def_prop_ro("name", [](const MDFuncAttr &self) {
-      MlirAttribute symRef = mlirLLVMMDFuncAttrGetName(self);
+    c.def_prop_ro("name", [](const MDValueAttr &self) {
+      MlirAttribute symRef = mlirLLVMMDValueAttrGetName(self);
       MlirStringRef ref = mlirFlatSymbolRefAttrGetValue(symRef);
       return nb::str(ref.data, ref.length);
     });
@@ -390,7 +390,7 @@ static void populateDialectLLVMSubmodule(nanobind::module_ &m) {
   FunctionType::bind(m);
   MDStringAttr::bind(m);
   MDConstantAttr::bind(m);
-  MDFuncAttr::bind(m);
+  MDValueAttr::bind(m);
   MDNodeAttr::bind(m);
 
   m.def(
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 6b8cac201d8bf..fdde4354990df 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -590,21 +590,21 @@ MlirAttribute mlirLLVMMDConstantAttrGetValue(MlirAttribute attr) {
   return wrap((Attribute)cast<MDConstantAttr>(unwrap(attr)).getValue());
 }
 
-MlirAttribute mlirLLVMMDFuncAttrGet(MlirContext ctx, MlirAttribute name) {
+MlirAttribute mlirLLVMMDValueAttrGet(MlirContext ctx, MlirAttribute name) {
   return wrap(
-      MDFuncAttr::get(unwrap(ctx), cast<FlatSymbolRefAttr>(unwrap(name))));
+      MDValueAttr::get(unwrap(ctx), cast<FlatSymbolRefAttr>(unwrap(name))));
 }
 
-bool mlirLLVMAttrIsAMDFuncAttr(MlirAttribute attr) {
-  return isa<MDFuncAttr>(unwrap(attr));
+bool mlirLLVMAttrIsAMDValueAttr(MlirAttribute attr) {
+  return isa<MDValueAttr>(unwrap(attr));
 }
 
-MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void) {
-  return wrap(MDFuncAttr::getTypeID());
+MlirTypeID mlirLLVMMDValueAttrGetTypeID(void) {
+  return wrap(MDValueAttr::getTypeID());
 }
 
-MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr) {
-  return wrap((Attribute)cast<MDFuncAttr>(unwrap(attr)).getName());
+MlirAttribute mlirLLVMMDValueAttrGetName(MlirAttribute attr) {
+  return wrap((Attribute)cast<MDValueAttr>(unwrap(attr)).getName());
 }
 
 MlirAttribute mlirLLVMMDNodeAttrGet(MlirContext ctx, intptr_t nOperands,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index ac6cf03e057dc..0427cf3f0fe90 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -4710,7 +4710,7 @@ Operation *LLVMDialect::materializeConstant(OpBuilder &builder, Attribute value,
     return LLVM::PoisonOp::create(builder, loc, type);
   if (isa<LLVM::ZeroAttr>(value))
     return LLVM::ZeroOp::create(builder, loc, type);
-  if (isa<LLVM::MDStringAttr, LLVM::MDConstantAttr, LLVM::MDFuncAttr,
+  if (isa<LLVM::MDStringAttr, LLVM::MDConstantAttr, LLVM::MDValueAttr,
           LLVM::MDNodeAttr>(value))
     if (isa<LLVM::LLVMMetadataType>(type))
       return LLVM::MetadataAsValueOp::create(builder, loc, type, value);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 3038a6a2ed986..f6b12c91fba4d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -178,7 +178,7 @@ static Attribute convertMetadataToAttrImpl(
     auto *fn = dyn_cast<llvm::Function>(vam->getValue());
     if (!fn)
       return {};
-    return MDFuncAttr::get(ctx, FlatSymbolRefAttr::get(ctx, fn->getName()));
+    return MDValueAttr::get(ctx, FlatSymbolRefAttr::get(ctx, fn->getName()));
   }
   if (auto *node = dyn_cast<llvm::MDNode>(md)) {
     if (Attribute cached = attrMap.lookup(node))
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 7d3a4c6346b0a..af9b1ee58d2da 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1585,7 +1585,7 @@ FailureOr<llvm::Metadata *> ModuleTranslation::convertMetadataAttr(
                                   intAttr.getType().getIntOrFloatBitWidth()),
             intAttr.getValue()));
       })
-      .Case<MDFuncAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
+      .Case<MDValueAttr>([&](auto a) -> FailureOr<llvm::Metadata *> {
         if (llvm::Function *fn = lookupFunction(a.getName().getValue()))
           return llvm::ValueAsMetadata::get(fn);
         if (llvm::GlobalValue *global = lookupGlobal(a.getName().getValue()))
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index d0acdfec6c8de..0300a70251113 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -1147,8 +1147,8 @@ llvm.func @metadata_as_value_shapes() {
   %0 = llvm.mlir.metadata_as_value #llvm.md_string<"sp">
   // CHECK: %{{.*}} = llvm.mlir.metadata_as_value #llvm.md_const<42 : i32>
   %1 = llvm.mlir.metadata_as_value #llvm.md_const<42 : i32>
-  // CHECK: %{{.*}} = llvm.mlir.metadata_as_value #llvm.md_func<@md_kernel>
-  %2 = llvm.mlir.metadata_as_value #llvm.md_func<@md_kernel>
+  // CHECK: %{{.*}} = llvm.mlir.metadata_as_value #llvm.md_value<@md_kernel>
+  %2 = llvm.mlir.metadata_as_value #llvm.md_value<@md_kernel>
   // CHECK: %{{.*}} = llvm.mlir.metadata_as_value #llvm.md_node<#llvm.md_string<"sp">>
   %3 = llvm.mlir.metadata_as_value #llvm.md_node<#llvm.md_string<"sp">>
   llvm.return
@@ -1219,10 +1219,10 @@ llvm.named_metadata "foo.language" [
   >
 ]
 
-// CHECK: llvm.named_metadata "foo.kernel" [#llvm.md_node<#llvm.md_func<@md_kernel>, #llvm.md_node<>, #llvm.md_node<#llvm.md_const<0 : i32>, #llvm.md_string<"foo.buffer">>>]
+// CHECK: llvm.named_metadata "foo.kernel" [#llvm.md_node<#llvm.md_value<@md_kernel>, #llvm.md_node<>, #llvm.md_node<#llvm.md_const<0 : i32>, #llvm.md_string<"foo.buffer">>>]
 llvm.named_metadata "foo.kernel" [
   #llvm.md_node<
-    #llvm.md_func<@md_kernel>,
+    #llvm.md_value<@md_kernel>,
     #llvm.md_node<>,
     #llvm.md_node<
       #llvm.md_const<0 : i32>,
diff --git a/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir b/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
index 9f09062c2a44b..377eeb44e84df 100644
--- a/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
@@ -59,7 +59,7 @@ llvm.named_metadata "foo.language_version" [
 
 llvm.named_metadata "foo.kernel" [
   #llvm.md_node<
-    #llvm.md_func<@my_kernel>,
+    #llvm.md_value<@my_kernel>,
     #llvm.md_node<>,
     #llvm.md_node<#buf0>>
 ]
@@ -69,8 +69,8 @@ llvm.named_metadata "foo.kernel" [
 
 llvm.named_metadata "foo.global_refs" [
   #llvm.md_node<
-    #llvm.md_func<@metadata_global>,
-    #llvm.md_func<@metadata_alias>,
-    #llvm.md_func<@metadata_ifunc>>
+    #llvm.md_value<@metadata_global>,
+    #llvm.md_value<@metadata_alias>,
+    #llvm.md_value<@metadata_ifunc>>
 ]
 // CHECK-DAG: ![[GLOBAL_REFS]] = !{ptr @metadata_global, ptr @metadata_alias, ptr @metadata_ifunc}
diff --git a/mlir/test/python/dialects/llvm.py b/mlir/test/python/dialects/llvm.py
index 1ed77cf3b84b3..069813623d6a9 100644
--- a/mlir/test/python/dialects/llvm.py
+++ b/mlir/test/python/dialects/llvm.py
@@ -232,11 +232,11 @@ def testMetadataAttrs():
     # CHECK: #llvm.md_const<42 : i32>
     print(md_const)
 
-    # MDFuncAttr
-    md_func = llvm.MDFuncAttr.get("my_kernel")
-    # CHECK: #llvm.md_func<@my_kernel>
-    print(md_func)
-    assert md_func.name == "my_kernel"
+    # MDValueAttr
+    md_value = llvm.MDValueAttr.get("my_kernel")
+    # CHECK: #llvm.md_value<@my_kernel>
+    print(md_value)
+    assert md_value.name == "my_kernel"
 
     # MDNodeAttr - empty
     md_empty = llvm.MDNodeAttr.get([])
@@ -326,7 +326,7 @@ def testNamedMetadata():
             [
                 llvm.MDNodeAttr.get(
                     [
-                        llvm.MDFuncAttr.get("my_kernel"),
+                        llvm.MDValueAttr.get("my_kernel"),
                         llvm.MDNodeAttr.get([]),
                         buf0,
                     ]
@@ -336,7 +336,7 @@ def testNamedMetadata():
     )
     # CHECK:       llvm.named_metadata "foo.kernel" [
     # CHECK-SAME:  #llvm.md_node<
-    # CHECK-SAME:      #llvm.md_func<@my_kernel>,
+    # CHECK-SAME:      #llvm.md_value<@my_kernel>,
     # CHECK-SAME:      #llvm.md_node<>,
     # CHECK-SAME:      #llvm.md_node<
     # CHECK-SAME:          #llvm.md_const<0 : i32>,



More information about the Mlir-commits mailing list