[Mlir-commits] [mlir] 610a310 - [MLIR][LLVM] Share LLVM metadata attribute translation (#203016)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Aug 1 06:08:37 PDT 2026
Author: Akimasa Watanuki
Date: 2026-08-01T22:08:29+09:00
New Revision: 610a3105af18f5efd127d2eaa1e4633de830b593
URL: https://github.com/llvm/llvm-project/commit/610a3105af18f5efd127d2eaa1e4633de830b593
DIFF: https://github.com/llvm/llvm-project/commit/610a3105af18f5efd127d2eaa1e4633de830b593.diff
LOG: [MLIR][LLVM] Share LLVM metadata attribute translation (#203016)
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.
Rename `MDFuncAttr` to `MDGlobalValueAttr` to reflect its support for
symbol-backed global values.
Added:
Modified:
mlir/include/mlir-c/Dialect/LLVM.h
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
mlir/lib/Bindings/Python/DialectLLVM.cpp
mlir/lib/CAPI/Dialect/LLVM.cpp
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Dialect/LLVMIR/invalid.mlir
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/LLVMIR/llvmir-invalid.mlir
mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir
mlir/test/python/dialects/llvm.py
Removed:
################################################################################
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 09d3ad198a3b2..28c4cdb98931d 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -510,18 +510,19 @@ 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 MDGlobalValueAttr referencing a symbol-backed global value.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMMDGlobalValueAttrGet(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 MDGlobalValueAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDGlobalValueAttr(MlirAttribute attr);
-/// Returns the TypeID of MDFuncAttr.
-MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void);
+/// Returns the TypeID of MDGlobalValueAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDGlobalValueAttrGetTypeID(void);
-/// Returns the symbol name of an LLVM MDFuncAttr.
-MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr);
+/// Returns the symbol name of an LLVM MDGlobalValueAttr.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMMDGlobalValueAttrGetName(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 6e2d4628c6173..55bbf2a02f706 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1774,15 +1774,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_MDGlobalValueAttr : LLVM_Attr<"MDGlobalValue", "md_global_value"> {
+ let summary = "LLVM global 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 global value as LLVM metadata, corresponding to
+ `llvm::ValueAsMetadata::get(value)` in LLVM IR.
Example:
```mlir
- #llvm.md_func<@my_kernel>
+ #llvm.md_global_value<@my_kernel>
```
}];
let parameters = (ins "FlatSymbolRefAttr":$name);
@@ -1794,7 +1794,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_global_value`, or nested `#llvm.md_node`.
Example:
```mlir
@@ -1806,8 +1806,13 @@ 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)">;
+ LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDGlobalValueAttr,
+ LLVM_MDNodeAttr],
+ "LLVM metadata attribute (md_string, md_const, md_global_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 42279011e9536..84f71054994f4 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2527,7 +2527,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_global_value<@symbol>` -> `llvm::ValueAsMetadata` of a
+ symbol-backed global value.
* `#llvm.md_node<...>` -> `llvm::MDNode` over any of the above.
These can be nested arbitrarily to form metadata trees. Lowering to LLVM
@@ -2561,12 +2562,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;
@@ -2702,7 +2705,7 @@ def LLVM_NamedMetadataOp
]
llvm.named_metadata "foo.kernel" [
#llvm.md_node<
- #llvm.md_func<@my_kernel>,
+ #llvm.md_global_value<@my_kernel>,
#llvm.md_node<>,
#llvm.md_node<
#llvm.md_node<#llvm.md_const<0 : i32>,
@@ -2713,13 +2716,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/Bindings/Python/DialectLLVM.cpp b/mlir/lib/Bindings/Python/DialectLLVM.cpp
index 7e4f24b556613..ebc9dda5ffdaf 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 MDGlobalValueAttr : PyConcreteAttribute<MDGlobalValueAttr> {
+ static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDGlobalValueAttr;
static constexpr GetTypeIDFunctionTy getTypeIdFunction =
- mlirLLVMMDFuncAttrGetTypeID;
- static constexpr const char *pyClassName = "MDFuncAttr";
+ mlirLLVMMDGlobalValueAttrGetTypeID;
+ static constexpr const char *pyClassName = "MDGlobalValueAttr";
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 MDGlobalValueAttr(
context->getRef(),
- mlirLLVMMDFuncAttrGet(context.get()->get(), symRef));
+ mlirLLVMMDGlobalValueAttrGet(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 MDGlobalValueAttr &self) {
+ MlirAttribute symRef = mlirLLVMMDGlobalValueAttrGetName(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);
+ MDGlobalValueAttr::bind(m);
MDNodeAttr::bind(m);
m.def(
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 8082de122e74e..bae811704cad3 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -590,21 +590,22 @@ MlirAttribute mlirLLVMMDConstantAttrGetValue(MlirAttribute attr) {
return wrap((Attribute)cast<MDConstantAttr>(unwrap(attr)).getValue());
}
-MlirAttribute mlirLLVMMDFuncAttrGet(MlirContext ctx, MlirAttribute name) {
- return wrap(
- MDFuncAttr::get(unwrap(ctx), cast<FlatSymbolRefAttr>(unwrap(name))));
+MlirAttribute mlirLLVMMDGlobalValueAttrGet(MlirContext ctx,
+ MlirAttribute name) {
+ return wrap(MDGlobalValueAttr::get(unwrap(ctx),
+ cast<FlatSymbolRefAttr>(unwrap(name))));
}
-bool mlirLLVMAttrIsAMDFuncAttr(MlirAttribute attr) {
- return isa<MDFuncAttr>(unwrap(attr));
+bool mlirLLVMAttrIsAMDGlobalValueAttr(MlirAttribute attr) {
+ return isa<MDGlobalValueAttr>(unwrap(attr));
}
-MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void) {
- return wrap(MDFuncAttr::getTypeID());
+MlirTypeID mlirLLVMMDGlobalValueAttrGetTypeID(void) {
+ return wrap(MDGlobalValueAttr::getTypeID());
}
-MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr) {
- return wrap((Attribute)cast<MDFuncAttr>(unwrap(attr)).getName());
+MlirAttribute mlirLLVMMDGlobalValueAttrGetName(MlirAttribute attr) {
+ return wrap((Attribute)cast<MDGlobalValueAttr>(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 efa67fa9f9af6..6382dfcbc8ad2 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -4736,7 +4736,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::MDGlobalValueAttr,
LLVM::MDNodeAttr>(value))
if (isa<LLVM::LLVMMetadataType>(type))
return LLVM::MetadataAsValueOp::create(builder, loc, type, value);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 489ba85410771..3e0a228c773d5 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -210,52 +210,28 @@ 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/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 595dfa6b8dd7a..725d7cf6c8413 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -178,7 +178,8 @@ static Attribute convertMetadataToAttrImpl(
auto *fn = dyn_cast<llvm::Function>(vam->getValue());
if (!fn)
return {};
- return MDFuncAttr::get(ctx, FlatSymbolRefAttr::get(ctx, fn->getName()));
+ return MDGlobalValueAttr::get(ctx,
+ FlatSymbolRefAttr::get(ctx, fn->getName()));
}
if (auto *node = dyn_cast<llvm::MDNode>(md)) {
// Metadata attributes cannot preserve distinctness, so bail out.
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index b76a803f93ad9..47e63e2aa279a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1582,6 +1582,59 @@ 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 a) -> FailureOr<llvm::Metadata *> {
+ return llvm::MDString::get(llvmContext, a.getValue().getValue());
+ })
+ .Case([&](MDConstantAttr 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([&](MDGlobalValueAttr 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 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/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index d5ea5c8de862e..bde7807dadb87 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/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index e5214ecebad23..d1766052964ba 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -1161,8 +1161,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_global_value<@md_kernel>
+ %2 = llvm.mlir.metadata_as_value #llvm.md_global_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
@@ -1233,10 +1233,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_global_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_global_value<@md_kernel>,
#llvm.md_node<>,
#llvm.md_node<
#llvm.md_const<0 : i32>,
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..abb6043b630cb 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>,
@@ -36,10 +59,18 @@ llvm.named_metadata "foo.language_version" [
llvm.named_metadata "foo.kernel" [
#llvm.md_node<
- #llvm.md_func<@my_kernel>,
+ #llvm.md_global_value<@my_kernel>,
#llvm.md_node<>,
#llvm.md_node<#buf0>>
]
// 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_global_value<@metadata_global>,
+ #llvm.md_global_value<@metadata_alias>,
+ #llvm.md_global_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..d63fea70d4259 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"
+ # MDGlobalValueAttr
+ md_global_value = llvm.MDGlobalValueAttr.get("my_kernel")
+ # CHECK: #llvm.md_global_value<@my_kernel>
+ print(md_global_value)
+ assert md_global_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.MDGlobalValueAttr.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_global_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