[Mlir-commits] [mlir] [MLIR][NVVM] Fix `inline_ptx` when there is only clobber register (PR #194380)
Guray Ozen
llvmlistbot at llvm.org
Mon Apr 27 07:17:32 PDT 2026
https://github.com/grypp updated https://github.com/llvm/llvm-project/pull/194380
>From 5fda897f6b3b03e1b723fb71b4e680cc58f4bb2e Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Mon, 27 Apr 2026 15:56:47 +0200
Subject: [PATCH 1/2] [MLIR][NVVM] Fix inline_ptx when there is only clobber
register
The interface crashes when there is only clobber register (read-write) today.There isn't any PTX instruction with only clobber register but the compiler should not crash.
---
.../LLVMIR/IR/BasicPtxBuilderInterface.cpp | 34 ++++++++++++-------
.../Conversion/NVVMToLLVM/nvvm-to-llvm.mlir | 17 ++++++++++
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
index 9ce413ceeaf6b..0138630ad9dd7 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
@@ -130,7 +130,7 @@ static SmallVector<Value> extractStructElements(PatternRewriter &rewriter,
SmallVector<Value> elems;
for (unsigned i : llvm::seq<unsigned>(0, structTy.getBody().size()))
- elems.push_back(LLVM::ExtractValueOp::create(rewriter, loc, structVal, i));
+ elems.push_back(rewriter.create<LLVM::ExtractValueOp>(loc, structVal, i));
return elems;
}
@@ -505,21 +505,31 @@ void PtxBuilder::buildAndReplaceOp() {
return;
}
- // Case 1: Simple path, return single scalar
+ // Case 1: Simple path, single scalar inline asm result.
if (!needsPackUnpack(interfaceOp, needsManualRegisterMapping,
registerModifiers)) {
- if (inlineAsmOp->getNumResults() > 0) {
+ // Sub-case 1a: the wrapper op has a declared result -- replace it
+ // directly with the inline asm result.
+ if (interfaceOp->getNumResults() > 0) {
rewriter.replaceOp(interfaceOp, inlineAsmOp->getResults());
- } else {
- // RW-only case with no declared results: forward the RW value.
- SmallVector<Value> results;
- for (auto [m, v] : llvm::zip(registerModifiers, ptxOperands))
- if (m == PTXRegisterMod::ReadWrite) {
- results.push_back(v);
- break;
- }
- rewriter.replaceOp(interfaceOp, results);
+ return;
}
+ // Sub-case 1b: RW-only, no declared result. The inline asm produces a
+ // single value that represents the post-asm value of the read-write
+ // operand; forward it to that operand's uses and erase the wrapper.
+ if (inlineAsmOp->getNumResults() > 0) {
+ Value postAsm = inlineAsmOp->getResult(0);
+ for (auto [m, v] : llvm::zip(registerModifiers, ptxOperands)) {
+ if (m != PTXRegisterMod::ReadWrite)
+ continue;
+ v.replaceUsesWithIf(postAsm, [&](OpOperand &use) {
+ Operation *owner = use.getOwner();
+ return owner != interfaceOp && owner != inlineAsmOp;
+ });
+ break;
+ }
+ }
+ rewriter.eraseOp(interfaceOp);
return;
}
diff --git a/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir b/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir
index a188aec18134c..a648295dda52c 100644
--- a/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir
+++ b/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir
@@ -771,3 +771,20 @@ llvm.func @cvt_i8_bf16(%a : i8) {
-> i16
llvm.return
}
+
+
+// CHECK-LABEL: @inline_ptx_single_rw_no_result(
+// CHECK-SAME: %[[arg0:[a-zA-Z0-9_]+]]: f32, %[[arg1:[a-zA-Z0-9_]+]]: f32)
+llvm.func @inline_ptx_single_rw_no_result(%a : f32, %b : f32) -> f32 {
+ // Single read-write operand and no declared results: the inline asm result
+ // value represents the post-asm value of the RW operand and must replace
+ // its uses (without trying to replace the wrapper op's non-existent result).
+ // CHECK: %[[C:.+]] = llvm.fadd %[[arg0]], %[[arg1]] : f32
+ // CHECK: %[[S0:.+]] = llvm.inline_asm has_side_effects asm_dialect = att "asm1 ", "=f,0" %[[C]] : (f32) -> f32
+ // CHECK: %[[R:.+]] = llvm.fadd %[[S0]], %[[arg0]] : f32
+ // CHECK: llvm.return %[[R]] : f32
+ %c = llvm.fadd %a, %b : f32
+ nvvm.inline_ptx "asm1 " rw(%c : f32)
+ %a2 = llvm.fadd %c, %a : f32
+ llvm.return %a2 : f32
+}
\ No newline at end of file
>From 9e5657094879ad29f983a0e5d8669bd5bf563f65 Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Mon, 27 Apr 2026 16:17:15 +0200
Subject: [PATCH 2/2] fz
---
mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
index 0138630ad9dd7..1747d5e383ca6 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
@@ -130,7 +130,7 @@ static SmallVector<Value> extractStructElements(PatternRewriter &rewriter,
SmallVector<Value> elems;
for (unsigned i : llvm::seq<unsigned>(0, structTy.getBody().size()))
- elems.push_back(rewriter.create<LLVM::ExtractValueOp>(loc, structVal, i));
+ elems.push_back(LLVM::ExtractValueOp::create(rewriter, loc, structVal, i));
return elems;
}
More information about the Mlir-commits
mailing list