diff --git a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h --- a/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h +++ b/mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h @@ -16,6 +16,7 @@ class Pass; #define GEN_PASS_DECL_CONVERTFUNCTOLLVMPASS +#define GEN_PASS_DECL_SETMODULEDATALAYOUTPASS #include "mlir/Conversion/Passes.h.inc" } // namespace mlir diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -328,6 +328,21 @@ // FuncToLLVM //===----------------------------------------------------------------------===// +def SetModuleDataLayoutPass : Pass<"set-module-datalayout", "ModuleOp"> { + let summary = "Attach a datalayout string as a module attribute"; + let description = [{ + Verify that the dataLayout string is a valid LLVM datalayout string and + attach it as an attribute `LLVMDialect::getDataLayoutAttrName()` to the + module. + }]; + let options = [ + Option<"dataLayout", "data-layout", "std::string", + /*default=*/"\"\"", + "String description (LLVM format) of the data layout that is " + "expected on the produced module">, + ]; +} + def ConvertFuncToLLVMPass : Pass<"convert-func-to-llvm", "ModuleOp"> { let summary = "Convert from the Func dialect to the LLVM dialect"; let description = [{ diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp --- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp +++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp @@ -49,6 +49,7 @@ namespace mlir { #define GEN_PASS_DEF_CONVERTFUNCTOLLVMPASS +#define GEN_PASS_DEF_SETMODULEDATALAYOUTPASS #include "mlir/Conversion/Passes.h.inc" } // namespace mlir @@ -772,7 +773,23 @@ LLVMConversionTarget target(getContext()); if (failed(applyPartialConversion(m, target, std::move(patterns)))) signalPassFailure(); + } +}; + +struct SetModuleDataLayoutPass + : public impl::SetModuleDataLayoutPassBase { + using Base::Base; + /// Run the dialect converter on the module. + void runOnOperation() override { + if (failed(LLVM::LLVMDialect::verifyDataLayoutString( + this->dataLayout, [this](const Twine &message) { + getOperation().emitError() << message.str(); + }))) { + signalPassFailure(); + return; + } + ModuleOp m = getOperation(); m->setAttr(LLVM::LLVMDialect::getDataLayoutAttrName(), StringAttr::get(m.getContext(), this->dataLayout)); } diff --git a/mlir/test/Conversion/FuncToLLVM/convert-data-layout.mlir b/mlir/test/Conversion/FuncToLLVM/convert-data-layout.mlir --- a/mlir/test/Conversion/FuncToLLVM/convert-data-layout.mlir +++ b/mlir/test/Conversion/FuncToLLVM/convert-data-layout.mlir @@ -1,5 +1,7 @@ -// RUN: mlir-opt -convert-func-to-llvm='use-opaque-pointers=1' %s | FileCheck %s -// RUN-32: mlir-opt -convert-func-to-llvm='data-layout=p:32:32:32 use-opaque-pointers=1' %s | FileCheck %s +// RUN: mlir-opt -convert-func-to-llvm='use-opaque-pointers=1' -set-module-datalayout %s | FileCheck %s + +// RUN-32: mlir-opt -convert-func-to-llvm='use-opaque-pointers=1' -set-module-datalayout='data-layout=p:32:32:32' %s \ +// RUN-32: | FileCheck %s // CHECK: module attributes {llvm.data_layout = ""} // CHECK-32: module attributes {llvm.data_layout ="p:32:32:32"}