[Mlir-commits] [mlir] [MLIR][LLVM] Model llvm.module_asm instruction (PR #151996)
Morris Hafner
llvmlistbot at llvm.org
Mon Aug 4 09:27:21 PDT 2025
https://github.com/mmha created https://github.com/llvm/llvm-project/pull/151996
This patch adds a new llvm.module_asm operator which models LLVM's `module asm` blocks. It provides translation to LLVM IR but does not check for the validity of asm_string.
>From b00351c4a436525842cc0c954adae3acd47194e0 Mon Sep 17 00:00:00 2001
From: Morris Hafner <mhafner at nvidia.com>
Date: Mon, 4 Aug 2025 18:08:33 +0200
Subject: [PATCH] [MLIR][LLVM] Model llvm.module_asm instruction
This patch adds a new llvm.module_asm operator which models LLVM's `module asm` blocks. It provides translation to LLVM IR but does not check for the validity of asm_string.
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 23 +++++++++++++++++++
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 6 +++++
mlir/test/Dialect/LLVMIR/canonicalize.mlir | 8 +++++++
mlir/test/Target/LLVMIR/llvmir.mlir | 9 ++++++++
4 files changed, 46 insertions(+)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 3f27f6d9ae8b7..b9c138c70a940 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2399,6 +2399,29 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
let hasVerifier = 1;
}
+def LLVM_ModuleAsmOp : LLVM_Op<"module_asm"> {
+ let description = [{
+ The ModuleAsmOp mirrors the underlying LLVM "module asm" semantics,
+ allowing target-specific assembly code to be embedded at module level.
+
+ Module asm blocks are concatenated and emitted outside of any function,
+ corresponding to GCC's file scope inline assembly. The assembly string
+ must be parseable by LLVM's integrated assembler and can reference
+ module-level symbols but not local variables.
+
+ Example:
+ ```
+ llvm.module_asm "my_function: ret"
+ llvm.module_asm ".globl my_symbol"
+ ```
+ }];
+ let arguments = (ins StrAttr:$asm_string);
+
+ let assemblyFormat = [{
+ attr-dict $asm_string
+ }];
+}
+
//===--------------------------------------------------------------------===//
// CallIntrinsicOp
//===--------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 0f675a0a5df5d..3b91fcab9a926 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -505,6 +505,12 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
return success();
}
+ if (auto moduleAsmOp = dyn_cast<LLVM::ModuleAsmOp>(opInst)) {
+ moduleTranslation.getLLVMModule()->appendModuleInlineAsm(
+ moduleAsmOp.getAsmString());
+ return success();
+ }
+
if (auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
auto operands = moduleTranslation.lookupValues(invOp.getCalleeOperands());
SmallVector<llvm::OperandBundleDef> opBundles =
diff --git a/mlir/test/Dialect/LLVMIR/canonicalize.mlir b/mlir/test/Dialect/LLVMIR/canonicalize.mlir
index 8accf6e263863..326058884500b 100644
--- a/mlir/test/Dialect/LLVMIR/canonicalize.mlir
+++ b/mlir/test/Dialect/LLVMIR/canonicalize.mlir
@@ -307,3 +307,11 @@ llvm.func @inline_asm_side_effects(%x : i32) {
llvm.inline_asm has_side_effects "inline asm with side effects", "r" %x : (i32) -> ()
llvm.return
}
+
+// -----
+
+// CHECK-LABEL: llvm.module_asm
+// CHECK-SAME: ".global some_symbol"
+// CHECK-NEXT: llvm.module_asm ".global another_symbol"
+llvm.module_asm ".global some_symbol"
+llvm.module_asm ".global another_symbol"
\ No newline at end of file
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index fc1993b50ba2d..a4c301c12b3b0 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2088,6 +2088,15 @@ llvm.func @useInlineAsm2(%arg0: !llvm.ptr, %arg1: i64, %arg2: !llvm.ptr, %arg3:
// -----
+module {
+ // CHECK: module asm ".global file_scope_asm_symbol"
+ // CHECK-NEXT: module asm "some_asm_label:"
+ llvm.module_asm ".global file_scope_asm_symbol"
+ llvm.module_asm "some_asm_label:"
+}
+
+// -----
+
llvm.func @fastmathFlagsFunc(f32) -> f32
// CHECK-LABEL: @fastmathFlags
More information about the Mlir-commits
mailing list