[Mlir-commits] [mlir] [mlir][gpu] Fix address space casts in gpu.alloc/gpu.dealloc lowering (PR #234394)
Jared Hoberock
llvmlistbot at llvm.org
Wed Oct 21 14:50:20 PDT 2026
https://github.com/jaredhoberock created https://github.com/llvm/llvm-project/pull/234394
In `GPUToLLVMConversion`, fix mismatches in address space when lowering `gpu.alloc` and `gpu.dealloc`.
Memory spaces aren't simple integers (they can be attributes) so the `gpu.alloc` lowering must take the address space from the type converter instead of simply reading the memory space as an integer.
Additionally, the `gpu.dealloc` lowering passed the descriptor's pointer directly to `mgpuMemFree`. Now it gets cast to the default address space expected by the runtime.
Adds unit tests for `gpu.alloc` on an attribute memory space and for `gpu.dealloc` on a non-default address space.
Assisted-by: Claude
>From 133967398bb2308f3ffa361d953560654c2937ac Mon Sep 17 00:00:00 2001
From: Jared Hoberock <jaredhoberock at gmail.com>
Date: Tue, 20 Oct 2026 12:49:50 -0500
Subject: [PATCH] [mlir][gpu] Fix gpu.alloc and gpu.dealloc lowering for
address spaces
The `gpu.alloc` lowering casts the pointer returned by `mgpuMemAlloc` to
the address space given by `memRefType.getMemorySpaceAsInt()`. The memref
descriptor's pointers are in the address space the type converter gives
the memref's memory space. For a memory space attribute the converter
maps to an address space, such as `#ptr.generic_space`,
`getMemorySpaceAsInt` asserts. The cast now uses the address space the
type converter computes.
The `gpu.dealloc` lowering passes the descriptor's allocated pointer to
`mgpuMemFree`, whose parameter is in the default address space. For a
memref in another address space, the call fails to verify ("operand type
mismatch"). The pointer is now cast to the default address space first.
Assisted-by: Claude
---
.../GPUCommon/GPUToLLVMConversion.cpp | 7 ++++++-
.../lower-alloc-to-gpu-runtime-calls.mlir | 19 +++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp b/mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp
index da807d732beece..7744d3b21e885c 100644
--- a/mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp
+++ b/mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp
@@ -797,7 +797,8 @@ LogicalResult ConvertAllocOpToGpuRuntimeCallPattern::matchAndRewrite(
// Cast the runtime-returned pointer to the memref's address space if it
// isn't there already, so it fits the descriptor's pointer slots.
- unsigned dstAddrSpace = memRefType.getMemorySpaceAsInt();
+ unsigned dstAddrSpace =
+ *getTypeConverter()->getMemRefAddressSpace(memRefType);
unsigned srcAddrSpace =
cast<LLVM::LLVMPointerType>(allocatedPtr.getType()).getAddressSpace();
if (dstAddrSpace != srcAddrSpace) {
@@ -837,6 +838,10 @@ LogicalResult ConvertDeallocOpToGpuRuntimeCallPattern::matchAndRewrite(
Value pointer =
MemRefDescriptor(adaptor.getMemref()).allocatedPtr(rewriter, loc);
+ // The runtime frees a pointer in the default address space.
+ if (pointer.getType() != llvmPointerType)
+ pointer =
+ LLVM::AddrSpaceCastOp::create(rewriter, loc, llvmPointerType, pointer);
auto nullPtr = mlir::LLVM::ZeroOp::create(rewriter, loc, llvmPointerType);
Value stream = adaptor.getAsyncDependencies().empty()
? nullPtr
diff --git a/mlir/test/Conversion/GPUCommon/lower-alloc-to-gpu-runtime-calls.mlir b/mlir/test/Conversion/GPUCommon/lower-alloc-to-gpu-runtime-calls.mlir
index 5d5c0093edf719..84072c8a3ea208 100644
--- a/mlir/test/Conversion/GPUCommon/lower-alloc-to-gpu-runtime-calls.mlir
+++ b/mlir/test/Conversion/GPUCommon/lower-alloc-to-gpu-runtime-calls.mlir
@@ -36,6 +36,25 @@ module attributes {gpu.container_module} {
return
}
+ // CHECK-LABEL: llvm.func @dealloc_address_space
+ func.func @dealloc_address_space(%arg0 : memref<10xf32, 1>) {
+ // CHECK: %[[pointer:.*]] = llvm.extractvalue {{.*}}[0]
+ // CHECK: %[[generic:.*]] = llvm.addrspacecast %[[pointer]] : !llvm.ptr<1> to !llvm.ptr
+ // CHECK: llvm.call @mgpuMemFree(%[[generic]], {{.*}})
+ gpu.dealloc %arg0 : memref<10xf32, 1>
+ return
+ }
+
+ // CHECK-LABEL: llvm.func @alloc_dealloc_generic_space
+ func.func @alloc_dealloc_generic_space() {
+ // CHECK: llvm.call @mgpuMemAlloc
+ // CHECK-NOT: llvm.addrspacecast
+ // CHECK: llvm.call @mgpuMemFree
+ %0 = gpu.alloc () : memref<10xf32, #ptr.generic_space>
+ gpu.dealloc %0 : memref<10xf32, #ptr.generic_space>
+ return
+ }
+
// CHECK-LABEL: llvm.func @alloc_sync
// CHECK-SAME: %[[size:.*]]: i64
func.func @alloc_sync(%size : index) {
More information about the Mlir-commits
mailing list