Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
#define MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
#ifndef MLIR_DIALECT_LLVMIR_DATALAYOUTIMPORTER_H
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the need to move this file to the LLVM dialect?

Copy link
Contributor Author

@rolfmorel rolfmorel Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we can have a #llvm.data_layout<DATA_LAYOUT_STR> attribute. The DATA_LAYOUT_STR is parsed by this importer and yields an unwieldly
#dlti.dl_spec<"dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64, !llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>>
(instead of #llvm.data_layout<"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128">).

What the attribute does is to just show the compact encoding, i.e. the string. It serves as a proxy to the dl_spec representation, which is kept hidden.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having these files in LLVM dialect is actually independent of whether we have #llvm.data_layout. Either way the pass that converts a #llvm.target attr to a representation of MLIR's data layout spec will need this parser. As this pass cannot depend on code in mlir/lib/Target, the importer should be in the LLVM dialect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general it doesn't matter if the textual version of the IR looks ugly, it's IR. It's preferable to have only one way to specify things, and in this case I'd argue that the verbose approach is better.

Re the second comment. You can make the Attr interface return the DL attribute, that way the interface impl and the importer still live in target.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: why is the DLTI using dense attributes for storing integers?
The example above would be much shorter with simple integers I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with getting rid of the #llvm.data_layout attr. 👍

You can make the Attr interface return the DL attribute, that way the interface impl and the importer still live in target.

I think that works. 👍

Side note: why is the DLTI using dense attributes for storing integers?
The example above would be much shorter with simple integers I think.

Yes, I would think an ArrayAttr would be a shorter and valid encoding. Will look into it after this PR lands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All LLVM dependencies are now inside include/Target / lib/Target.

#llvm.data_layout is gone.

#define MLIR_DIALECT_LLVMIR_DATALAYOUTIMPORTER_H

#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/BuiltinAttributes.h"
Expand All @@ -38,23 +38,30 @@ namespace detail {
/// null if the bit width is not supported.
FloatType getFloatType(MLIRContext *context, unsigned width);

/// Helper class that translates an LLVM data layout to an MLIR data layout
/// specification. Only integer, float, pointer, alloca memory space, stack
/// alignment, and endianness entries are translated. The class also returns all
/// entries from the default data layout specification found in the language
/// reference (https://llvm.org/docs/LangRef.html#data-layout) if they are not
/// overwritten by the provided data layout.
/// Helper class that translates an LLVM data layout string to an MLIR data
/// layout specification. Only integer, float, pointer, alloca memory space,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's MLIR data layout specification? Is there any reference akin to https://llvm.org/docs/LangRef.html#data-layout?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's this page: https://mlir.llvm.org/docs/DataLayout/#data-layout-specifications

It doesn't do a good job of specifying all the properties that are supported. Nor does it clearly explain how those properties are encoded in dl_specs.

Is there any consensus on whether tracking issues on Github are worth the effort?

/// stack alignment, and endianness entries are translated. The class also
/// returns all entries from the default data layout specification found in the
/// language reference (https://llvm.org/docs/LangRef.html#data-layout) if they
/// are not overwritten by the provided data layout.
class DataLayoutImporter {
public:
DataLayoutImporter(MLIRContext *context,
const llvm::DataLayout &llvmDataLayout)
: context(context) {
translateDataLayout(llvmDataLayout);
DataLayoutImporter(MLIRContext *context, StringRef dataLayoutStr)
: dataLayoutStr(dataLayoutStr), context(context) {
// Append the default data layout string specified in the language reference
// (https://llvm.org/docs/LangRef.html#data-layout) to the supplied data
// layout string. The translation then parses the string and ignores the
// default value if a specific kind occurs in both strings. Additionally,
// the following default values exist:
// - non-default address space pointer specifications default to the default
// address space pointer specification
// - the alloca address space defaults to the default address space.
dataLayoutSpec = dataLayoutSpecFromDataLayoutStr();
}

/// Returns the MLIR data layout specification translated from the LLVM
/// data layout.
DataLayoutSpecInterface getDataLayout() const { return dataLayout; }
DataLayoutSpecInterface getDataLayoutSpec() const { return dataLayoutSpec; }

/// Returns the last data layout token that has been processed before
/// the data layout translation failed.
Expand All @@ -66,7 +73,7 @@ class DataLayoutImporter {

private:
/// Translates the LLVM `dataLayout` to an MLIR data layout specification.
void translateDataLayout(const llvm::DataLayout &llvmDataLayout);
DataLayoutSpecInterface dataLayoutSpecFromDataLayoutStr();

/// Tries to parse the letter only prefix that identifies the specification
/// and removes the consumed characters from the beginning of the string.
Expand Down Expand Up @@ -116,17 +123,18 @@ class DataLayoutImporter {
/// Adds legal int widths entry if there is none yet.
LogicalResult tryToEmplaceLegalIntWidthsEntry(StringRef token);

std::string layoutStr = {};
std::string dataLayoutStr = {};
DataLayoutSpecInterface dataLayoutSpec;

StringRef lastToken = {};
SmallVector<StringRef> unhandledTokens;
llvm::MapVector<StringAttr, DataLayoutEntryInterface> keyEntries;
llvm::MapVector<TypeAttr, DataLayoutEntryInterface> typeEntries;
MLIRContext *context;
DataLayoutSpecInterface dataLayout;
};

} // namespace detail
} // namespace LLVM
} // namespace mlir

#endif // MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
#endif // MLIR_DIALECT_LLVMIR_DATALAYOUTIMPORTER_H
123 changes: 123 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include "mlir/Dialect/LLVMIR/LLVMDialect.td"
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/CommonAttrConstraints.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"

// All of the attributes will extend this class.
class LLVM_Attr<string name, string attrMnemonic,
Expand Down Expand Up @@ -1304,6 +1305,128 @@ def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features">
let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// LLVM_TargetAttr
//===----------------------------------------------------------------------===//

def LLVM_TargetAttr : LLVM_Attr<"Target", "target",
[DLTIQueryInterface]> {
let summary = "LLVM target info: triple, chip, features";
let description = [{
An attribute to hold LLVM target information, specifying LLVM's target
`triple` string, the target `chip` string (i.e. the `cpu` string), and
target `features` string as an attribute. The latter two are optional.

Has facilities to obtain the corresponding `llvm::TargetMachine` and
`llvm::DataLayout`, given the relevant LLVM backend is loaded.

---

Responds to DLTI-queries on the keys:
* A query for `"triple"` returns the `StringAttr` for the `triple`.
* A query for `"chip"` returns the `StringAttr` for the `chip`/`cpu`.
* A query for `"features"` returns the `StringAttr`, if provided.
}];
let parameters = (ins "StringAttr":$triple,
"StringAttr":$chip,
OptionalParameter<"StringAttr", "">:$features);

let assemblyFormat = [{`<` struct($triple, $chip, $features) `>`}];

let extraClassDeclaration = [{
FailureOr<Attribute> query(DataLayoutEntryKey key);
}];
}

//===----------------------------------------------------------------------===//
// LLVM_DataLayoutAttr
//===----------------------------------------------------------------------===//

def LLVM_DataLayoutAttr
Copy link
Contributor

@fabianmcg fabianmcg Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need an LLVM dedicated attr? AFAIK we already were able to store data layouts in MLIR and translate them to LLVM IR, did I miss a change there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above: due to ungainly DLTI attributes.

Compare with this attribute:

module attributes {dlti.dl_spec = #llvm.data_layout<"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128">, llvm.target = #llvm.target<triple = "x86_64-unknown-linux", chip = "skylake", features = "+mmx,+sse">} {
}

to without:

module attributes {dlti.dl_spec = #dlti.dl_spec<"dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64, !llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>>, llvm.target = #llvm.target<triple = "x86_64-unknown-linux", chip = "skylake", features = "+mmx,+sse">} {
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as above, I would argue verbose is better, it doesn't have to look pretty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #llvm.data_layout attr is now gone.

: LLVM_Attr<"DataLayout", "data_layout", [DataLayoutSpecInterface]> {
let summary = "LLVM data layout string, exposed through DLTI";
let description = [{
An attribute to hold a LLVM data layout string.

The LLVM data layout string is parsed and mapped to the corresponding MLIR
data layout specification. The `#llvm.data_layout` attribute then serves as
a proxy, forwarding all DLTI queries to the underlying MLIR data layout
specification.

The default data layout string specified in the language reference
(https://llvm.org/docs/LangRef.html#data-layout) is used to derive
unspecified elements of the data layout string.
}];
let parameters = (ins OptionalParameter<"StringAttr", "\"\"">:$data_layout_str,
OptionalParameter<"DataLayoutSpecInterface", "{}">:$data_layout_spec);
let builders = [
AttrBuilder<(ins "llvm::StringRef":$data_layout_str), [{
auto importer = LLVM::detail::DataLayoutImporter($_ctxt, data_layout_str);
auto dataLayoutSpec = importer.getDataLayoutSpec();
return $_get($_ctxt, mlir::StringAttr::get($_ctxt, data_layout_str), dataLayoutSpec);
}]>
];
let assemblyFormat = "(`<` $data_layout_str^ `>`)?";
let extraClassDeclaration = [{
// Forward all DataLayoutSpecInterface methods to the underlying
// DataLayoutSpecInterface.
template <typename Ty>
DataLayoutEntryList getSpecForType() {
return getDataLayoutSpec().getSpecForType(TypeID::get<Ty>());
}
void bucketEntriesByType(
::llvm::MapVector<::mlir::TypeID, ::mlir::DataLayoutEntryList> &types,
::llvm::MapVector<::mlir::StringAttr,
::mlir::DataLayoutEntryInterface> &ids) {
getDataLayoutSpec().bucketEntriesByType(types, ids);
}
::mlir::DataLayoutSpecInterface
combineWith(ArrayRef<::mlir::DataLayoutSpecInterface> specs) const {
return getDataLayoutSpec().combineWith(specs);
}
DataLayoutEntryListRef getEntries() const { return getDataLayoutSpec().getEntries(); }
LogicalResult verifySpec(Location loc) {
return getDataLayoutSpec().verifySpec(loc);
}
StringAttr getEndiannessIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getEndiannessIdentifier(context);
}
StringAttr getDefaultMemorySpaceIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getDefaultMemorySpaceIdentifier(context);
}
StringAttr getAllocaMemorySpaceIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getAllocaMemorySpaceIdentifier(context);
}
StringAttr getManglingModeIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getManglingModeIdentifier(context);
}
StringAttr getProgramMemorySpaceIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getProgramMemorySpaceIdentifier(context);
}
StringAttr getGlobalMemorySpaceIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getGlobalMemorySpaceIdentifier(context);
}
StringAttr getStackAlignmentIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getStackAlignmentIdentifier(context);
}
StringAttr getFunctionPointerAlignmentIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getFunctionPointerAlignmentIdentifier(context);
}
StringAttr getLegalIntWidthsIdentifier(MLIRContext *context) const {
return getDataLayoutSpec().getLegalIntWidthsIdentifier(context);
}
::mlir::DataLayoutEntryList getSpecForType(TypeID type) const {
return getDataLayoutSpec().getSpecForType(type);
}
::mlir::DataLayoutEntryInterface getSpecForIdentifier(StringAttr identifier) const {
return getDataLayoutSpec().getSpecForIdentifier(identifier);
}
FailureOr<Attribute> query(DataLayoutEntryKey key) const {
return getDataLayoutSpec().query(key);
}
}];
}

//===----------------------------------------------------------------------===//
// UndefAttr
//===----------------------------------------------------------------------===//
Expand Down
7 changes: 5 additions & 2 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
#ifndef MLIR_DIALECT_LLVMIR_LLVMATTRS_H_
#define MLIR_DIALECT_LLVMIR_LLVMATTRS_H_

#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
#include <optional>

#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.h.inc"

#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need these?

Suggested change
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the mlir::LLVM::TargetAttrInterface has methods that return the DataLayout and TargetMachine.

Look at mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h to see that having dependency on LLVM's headers is not a big deal. For clarity's sake, due moving the parts that require linking to mlir/Target the LLVM dialect does not gain any linking dependencies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually those dependencies there are spurious and legacy, see #150692 for removal

Ideally the LLVM dialect shouldn't depend on llvm/IR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will have another go at getting these bits to live in mlir/lib/Target.

Copy link
Contributor Author

@rolfmorel rolfmorel Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All LLVM dependencies are now inside include/Target / lib/Target.


namespace mlir {
namespace LLVM {

Expand Down Expand Up @@ -89,8 +92,8 @@ class TBAANodeAttr : public Attribute {
// TODO: this shouldn't be needed after we unify the attribute generation, i.e.
// --gen-attr-* and --gen-attrdef-*.
using cconv::CConv;
using tailcallkind::TailCallKind;
using linkage::Linkage;
using tailcallkind::TailCallKind;
} // namespace LLVM
} // namespace mlir

Expand Down
50 changes: 50 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVMIR_INTERFACES

include "mlir/IR/OpBase.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"

def FastmathFlagsInterface : OpInterface<"FastmathFlagsInterface"> {
let description = [{
Expand Down Expand Up @@ -532,4 +533,53 @@ def LLVM_DIRecursiveTypeAttrInterface
];
}

def LLVM_TargetAttrInterface
: AttrInterface<"TargetAttrInterface", [DLTIQueryInterface]> {
let description = [{
Interface for attributes that describe LLVM targets.

These attributes should be able to return the specified target `triple`,
`chip` and `features` and are expected to be able to produce the
corresponding `llvm::TargetMachine` and `llvm::DataLayout`. These methods
can fail in case the backend is not available.

Implementing attributes should provide a `DLTIQueryInterface::query()`
implementation which responds to keys `"triple"`, `"chip"` and `"features"`
by returning appropriate `StringAttr`s.
}];
let cppNamespace = "::mlir::LLVM";
let methods = [
InterfaceMethod<
/*description=*/"Returns the target triple identifier.",
/*retTy=*/"StringAttr",
/*methodName=*/"getTripleAttr",
/*args=*/(ins)
>,
InterfaceMethod<
/*description=*/"Returns the target chip (i.e. \"cpu\") identifier.",
/*retTy=*/"StringAttr",
/*methodName=*/"getChipAttr",
/*args=*/(ins)
>,
InterfaceMethod<
/*description=*/"Returns the target features as a string.",
/*retTy=*/"StringAttr",
/*methodName=*/"getFeaturesAttr",
/*args=*/(ins)
>,
InterfaceMethod<
/*description=*/"Returns the target machine.",
/*retTy=*/"FailureOr<std::unique_ptr<::llvm::TargetMachine>>",
/*methodName=*/"getTargetMachine",
/*args=*/(ins)
>,
InterfaceMethod<
/*description=*/"Returns the data layout associated to the target machine.",
/*retTy=*/"FailureOr<::llvm::DataLayout>",
/*methodName=*/"getDataLayout",
/*args=*/(ins)
>
];
}

#endif // LLVMIR_INTERFACES
11 changes: 11 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ def LLVMRequestCWrappersPass
}];
}

def LLVMDataLayoutFromTarget : Pass<"llvm-data-layout-from-target", "::mlir::ModuleOp"> {
let summary = "Derive data layout attributes from LLVM target attributes";
let dependentDialects = ["mlir::DLTIDialect"];
let description = [{
Checks modules for LLVM-dialect's `TargetAttrInterface`-implementing
attributes and derives `DataLayoutSpecInterface`-implementing data layout
attributes from the specified target by querying the corresponding
LLVM-backend.
}];
}

def NVVMOptimizeForTargetPass : Pass<"llvm-optimize-for-nvvm-target"> {
let summary = "Optimize NVVM IR";
}
Expand Down
2 changes: 2 additions & 0 deletions mlir/include/mlir/InitAllDialects.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#include "mlir/Dialect/XeGPU/IR/XeGPU.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Interfaces/CastInterfaces.h"
#include "mlir/Target/LLVM/Target.h"
#include "mlir/Target/LLVM/NVVM/Target.h"
#include "mlir/Target/LLVM/ROCDL/Target.h"
#include "mlir/Target/SPIRV/Target.h"
Expand Down Expand Up @@ -172,6 +173,7 @@ inline void registerAllDialects(DialectRegistry &registry) {
gpu::registerBufferDeallocationOpInterfaceExternalModels(registry);
gpu::registerValueBoundsOpInterfaceExternalModels(registry);
LLVM::registerInlinerInterface(registry);
LLVM::registerLLVMTargetInterfaceExternalModels(registry);
NVVM::registerInlinerInterface(registry);
linalg::registerAllDialectInterfaceImplementations(registry);
linalg::registerRuntimeVerifiableOpInterfaceExternalModels(registry);
Expand Down
30 changes: 30 additions & 0 deletions mlir/include/mlir/Target/LLVM/Target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===- Target.h - MLIR LLVM target registration -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for attaching the LLVM target interface.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_LLVM_TARGET_H
#define MLIR_TARGET_LLVM_TARGET_H

namespace mlir {
class DialectRegistry;
class MLIRContext;
namespace LLVM {
/// Registers the `TargetAttrInterface` for the `#llvm.target` attribute in the
/// given registry.
void registerLLVMTargetInterfaceExternalModels(DialectRegistry &registry);

/// Registers the `TargetAttrInterface` for the `#llvm.target` attribute in the
/// registry associated with the given context.
void registerLLVMTargetInterfaceExternalModels(MLIRContext &context);
} // namespace LLVM
} // namespace mlir

#endif // MLIR_TARGET_LLVM_TARGET_H
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/DLTI/DLTI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ void DLTIDialect::initialize() {
LogicalResult DLTIDialect::verifyOperationAttribute(Operation *op,
NamedAttribute attr) {
if (attr.getName() == DLTIDialect::kDataLayoutAttrName) {
if (!llvm::isa<DataLayoutSpecAttr>(attr.getValue())) {
if (!llvm::dyn_cast<DataLayoutSpecInterface>(attr.getValue())) {
return op->emitError() << "'" << DLTIDialect::kDataLayoutAttrName
<< "' is expected to be a #dlti.dl_spec attribute";
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/DLTI/Traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ LogicalResult mlir::impl::verifyHasDefaultDLTIDataLayoutTrait(Operation *op) {
}

DataLayoutSpecInterface mlir::impl::getDataLayoutSpec(Operation *op) {
return op->getAttrOfType<DataLayoutSpecAttr>(
return op->getAttrOfType<DataLayoutSpecInterface>(
DLTIDialect::kDataLayoutAttrName);
}

Expand Down
Loading