[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.
This commit is contained in:
parent
ecb50ab04f
commit
610a3105af
15 changed files with 204 additions and 102 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ public:
|
|||
/// 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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1847,6 +1847,11 @@ llvm.mlir.alias external @y5 : i32 {
|
|||
|
||||
// -----
|
||||
|
||||
// expected-error@+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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
Loading…
Reference in a new issue