[Mlir-commits] [mlir] [mlir][llvm] adds an attribute for the module level assembly (PR #151318)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Jul 31 01:31:19 PDT 2025


https://github.com/gitoleg updated https://github.com/llvm/llvm-project/pull/151318

>From dd8b762c237f4a7a8c4087757f695a0879c8f05b Mon Sep 17 00:00:00 2001
From: gitoleg <forown at yandex.ru>
Date: Wed, 30 Jul 2025 15:36:44 +0300
Subject: [PATCH 1/5] [mlir][llvm] adds an attribute for the module level
 assembly

---
 mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td | 3 +++
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp    | 4 ++++
 mlir/test/Target/LLVMIR/module-asm.mlir         | 5 +++++
 3 files changed, 12 insertions(+)
 create mode 100644 mlir/test/Target/LLVMIR/module-asm.mlir

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
index b5ea8fc5da500..107bf3edb657a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
@@ -83,6 +83,9 @@ def LLVM_Dialect : Dialect {
       return "llvm.emit_c_interface";
     }
 
+    /// Name of the module level assembly attribute.
+    static StringRef getModuleLevelAsmAttrName() { return "llvm.module_asm"; }
+
     /// Name of the dependent libraries attribute.
     static StringRef getDependentLibrariesAttrName() {
       return "llvm.dependent_libraries";
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index b997e559885e2..2c2ef598aa6a9 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2276,6 +2276,10 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
     llvmModule->setTargetTriple(
         llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
 
+  if (auto asmAttr =
+          m->getDiscardableAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName()))
+    llvmModule->setModuleInlineAsm(cast<StringAttr>(asmAttr).getValue());
+
   return llvmModule;
 }
 
diff --git a/mlir/test/Target/LLVMIR/module-asm.mlir b/mlir/test/Target/LLVMIR/module-asm.mlir
new file mode 100644
index 0000000000000..fa8158ac2677a
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/module-asm.mlir
@@ -0,0 +1,5 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+module attributes {llvm.module_asm = "foo"} {}
+
+// CHECK: module asm "foo"
\ No newline at end of file

>From bc7cf6c3a25b081cf0c27599973b9a46d59643af Mon Sep 17 00:00:00 2001
From: gitoleg <forown at yandex.ru>
Date: Wed, 30 Jul 2025 18:36:43 +0300
Subject: [PATCH 2/5] use ArrayAttr

---
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 7 +++++--
 mlir/test/Target/LLVMIR/module-asm.mlir      | 5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 2c2ef598aa6a9..4048b30c2b811 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2277,8 +2277,11 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
         llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
 
   if (auto asmAttr =
-          m->getDiscardableAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName()))
-    llvmModule->setModuleInlineAsm(cast<StringAttr>(asmAttr).getValue());
+          m->getDiscardableAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
+    auto arr = cast<ArrayAttr>(asmAttr);
+    for (unsigned i = 0; i < arr.size(); ++i)
+      llvmModule->appendModuleInlineAsm(cast<StringAttr>(arr[i]).getValue());
+  }
 
   return llvmModule;
 }
diff --git a/mlir/test/Target/LLVMIR/module-asm.mlir b/mlir/test/Target/LLVMIR/module-asm.mlir
index fa8158ac2677a..f3404dd1a7001 100644
--- a/mlir/test/Target/LLVMIR/module-asm.mlir
+++ b/mlir/test/Target/LLVMIR/module-asm.mlir
@@ -1,5 +1,6 @@
 // RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
 
-module attributes {llvm.module_asm = "foo"} {}
+module attributes {llvm.module_asm = ["foo", "bar"]} {}
 
-// CHECK: module asm "foo"
\ No newline at end of file
+// CHECK: module asm "foo"
+// CHECK: module asm "bar"
\ No newline at end of file

>From 5bdb44d07ba5524235957d0d88ce5393de8c8d11 Mon Sep 17 00:00:00 2001
From: gitoleg <forown at yandex.ru>
Date: Thu, 31 Jul 2025 09:40:00 +0300
Subject: [PATCH 3/5] some changes after review

---
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 8 ++++----
 mlir/test/Target/LLVMIR/module-asm.mlir      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 4048b30c2b811..ffc502566fab8 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2276,11 +2276,11 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
     llvmModule->setTargetTriple(
         llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
 
-  if (auto asmAttr =
-          m->getDiscardableAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
+  if (auto asmAttr = m->getDiscardableAttr(
+          LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
     auto arr = cast<ArrayAttr>(asmAttr);
-    for (unsigned i = 0; i < arr.size(); ++i)
-      llvmModule->appendModuleInlineAsm(cast<StringAttr>(arr[i]).getValue());
+    for (auto elt : arr)
+      llvmModule->appendModuleInlineAsm(cast<StringAttr>(elt).getValue());
   }
 
   return llvmModule;
diff --git a/mlir/test/Target/LLVMIR/module-asm.mlir b/mlir/test/Target/LLVMIR/module-asm.mlir
index f3404dd1a7001..2afb37cf005bf 100644
--- a/mlir/test/Target/LLVMIR/module-asm.mlir
+++ b/mlir/test/Target/LLVMIR/module-asm.mlir
@@ -3,4 +3,4 @@
 module attributes {llvm.module_asm = ["foo", "bar"]} {}
 
 // CHECK: module asm "foo"
-// CHECK: module asm "bar"
\ No newline at end of file
+// CHECK: module asm "bar"

>From 7a20b31c2bae69367fb223d9cdcde52aa953ca84 Mon Sep 17 00:00:00 2001
From: gitoleg <forown at yandex.ru>
Date: Thu, 31 Jul 2025 10:39:05 +0300
Subject: [PATCH 4/5] added import implementation

---
 mlir/include/mlir/Target/LLVMIR/ModuleImport.h |  4 ++++
 mlir/lib/Target/LLVMIR/ModuleImport.cpp        | 15 +++++++++++++++
 mlir/test/Target/LLVMIR/Import/module-asm.ll   |  5 +++++
 3 files changed, 24 insertions(+)
 create mode 100644 mlir/test/Target/LLVMIR/Import/module-asm.ll

diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 17ef8e44afd2d..b3fc3fb65c85d 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -83,6 +83,10 @@ class ModuleImport {
   /// specification.
   void convertTargetTriple();
 
+  /// Converts the module level asm of the LLVM module to an MLIR module
+  /// level asm specification.
+  void convertModuleLevelAsm();
+
   /// Stores the mapping between an LLVM value and its MLIR counterpart.
   void mapValue(llvm::Value *llvm, Value mlir) { mapValue(llvm) = mlir; }
 
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 58e3c44ec0049..59774d2046eab 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -30,6 +30,7 @@
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/Comdat.h"
 #include "llvm/IR/Constants.h"
@@ -1063,6 +1064,19 @@ void ModuleImport::convertTargetTriple() {
       builder.getStringAttr(llvmModule->getTargetTriple().str()));
 }
 
+void ModuleImport::convertModuleLevelAsm() {
+  auto str = llvmModule->getModuleInlineAsm();
+  llvm::SmallVector<mlir::Attribute> arr;
+
+  for (auto line : llvm::split(str, '\n'))
+    if (!line.empty())
+      arr.push_back(builder.getStringAttr(line));
+
+  mlirModule->setAttr(
+      LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
+      builder.getArrayAttr(arr));
+}
+
 LogicalResult ModuleImport::convertFunctions() {
   for (llvm::Function &func : llvmModule->functions())
     if (failed(processFunction(&func)))
@@ -3199,5 +3213,6 @@ OwningOpRef<ModuleOp> mlir::translateLLVMIRToModule(
   if (failed(moduleImport.convertIFuncs()))
     return {};
   moduleImport.convertTargetTriple();
+  moduleImport.convertModuleLevelAsm();
   return module;
 }
diff --git a/mlir/test/Target/LLVMIR/Import/module-asm.ll b/mlir/test/Target/LLVMIR/Import/module-asm.ll
new file mode 100644
index 0000000000000..38f6ea448acba
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/module-asm.ll
@@ -0,0 +1,5 @@
+; RUN: mlir-translate -import-llvm %s | FileCheck %s
+; CHECK: llvm.module_asm = ["foo", "bar"]
+
+module asm "foo"
+module asm "bar"

>From 5d8479f1dab3bfd4c5335b53d531d8ecfa921988 Mon Sep 17 00:00:00 2001
From: gitoleg <forown at yandex.ru>
Date: Thu, 31 Jul 2025 11:22:43 +0300
Subject: [PATCH 5/5] added checks for attributes

---
 mlir/lib/Target/LLVMIR/ModuleImport.cpp      |  5 ++---
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 13 ++++++++++++-
 mlir/test/Target/LLVMIR/invalid-module.mlir  | 10 +++++++++-
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 59774d2046eab..7de6cd19d09c2 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1072,9 +1072,8 @@ void ModuleImport::convertModuleLevelAsm() {
     if (!line.empty())
       arr.push_back(builder.getStringAttr(line));
 
-  mlirModule->setAttr(
-      LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
-      builder.getArrayAttr(arr));
+  mlirModule->setAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
+                      builder.getArrayAttr(arr));
 }
 
 LogicalResult ModuleImport::convertFunctions() {
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index ffc502566fab8..25aa6eba3e1f5 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2278,9 +2278,20 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
 
   if (auto asmAttr = m->getDiscardableAttr(
           LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
+    if (!isa<ArrayAttr>(asmAttr)) {
+      m->emitError("expected an array attribute for a module level asm");
+      return nullptr;
+    }
+
     auto arr = cast<ArrayAttr>(asmAttr);
-    for (auto elt : arr)
+    for (auto elt : arr) {
+      if (!isa<StringAttr>(elt)) {
+        m->emitError(
+            "expected a string attribute for each entry of a module level asm");
+        return nullptr;
+      }
       llvmModule->appendModuleInlineAsm(cast<StringAttr>(elt).getValue());
+    }
   }
 
   return llvmModule;
diff --git a/mlir/test/Target/LLVMIR/invalid-module.mlir b/mlir/test/Target/LLVMIR/invalid-module.mlir
index 7fd5f26998a09..2725612b2f0f6 100644
--- a/mlir/test/Target/LLVMIR/invalid-module.mlir
+++ b/mlir/test/Target/LLVMIR/invalid-module.mlir
@@ -1,6 +1,14 @@
-// RUN: mlir-translate -verify-diagnostics -mlir-to-llvmir --no-implicit-module %s
+// RUN: mlir-translate -verify-diagnostics -mlir-to-llvmir --no-implicit-module -split-input-file %s
 
 // expected-error at below {{'llvm.func' op can not be translated to an LLVMIR module}}
 llvm.func @foo() {
   llvm.return
 }
+
+// -----
+// expected-error at below {{expected an array attribute for a module level asm}}
+module attributes {llvm.module_asm = "foo"} {}
+
+// -----
+// expected-error at below {{expected a string attribute for each entry of a module level asm}}
+module attributes {llvm.module_asm = [42]} {}
\ No newline at end of file



More information about the Mlir-commits mailing list