[MLIR]GPU default pipeline leaves `vector.transfer_read` and an unreconciled memref descriptor cast
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The default `gpu-lower-to-nvvm-pipeline` does not fully lower a rank-1 `vector.transfer_read` inside a `gpu.module`. During `convert-gpu-to-nvvm`, the memref argument is converted to an LLVM descriptor, but the surviving vector operation still expects a memref.
A descriptor-to- memref `builtin.unrealized_conversion_cast` is inserted and cannot be reconciled because it remains consumed by the vector operation. GPU binary serialization later fails during LLVM translation. This appears to be a rejects-valid bug.
### Input Program
input.mlir
```llvm
module attributes {gpu.container_module} {
gpu.module @kernels {
gpu.func @transfer_read(%input : memref, %output : memref) kernel {
%c0 = arith.constant 0 : index
%padding = arith.constant 0.0 : f32
%value = vector.transfer_read %input[%c0], %padding
: memref, vector<4xf32>
%first = vector.extract %value[0] : f32 from vector<4xf32>
memref.store %first, %output[%c0] : memref
gpu.return
}
}
func.func @main() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c4 = arith.constant 4 : index
%input = gpu.alloc host_shared (%c4) : memref
%output = gpu.alloc host_shared (%c1) : memref
%one = arith.constant 1.0 : f32
%zero = arith.constant 0.0 : f32
scf.for %i = %c0 to %c4 step %c1 {
memref.store %one, %input[%i] : memref
}
memref.store %zero, %output[%c0] : memref
gpu.launch_func @kernels::@transfer_read
blocks in (%c1, %c1, %c1) threads in (%c1, %c1, %c1)
args(%input : memref, %output : memref)
%unranked = memref.cast %output : memref to memref<*xf32>
call @printMemrefF32(%unranked) : (memref<*xf32>) -> ()
return
}
func.func private @printMemrefF32(memref<*xf32>)
attributes {llvm.emit_c_interface}
}
```
### Used Command
```bash
mlir-opt input.mlir \
--gpu-lower-to-nvvm-pipeline='cubin-chip=sm_89 cubin-features=+ptx80 opt-level=3 allow-pattern-rollback=0' \
-o /tmp/lower.mlir
```
### Actual result
mlir-opt exits with code 1:
```bash
error: LLVM Translation failed for operation:
builtin.unrealized_conversion_cast
note: see current operation: %9 = "builtin.unrealized_conversion_cast"(%8)
: (!llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>)
-> memref
error: Failed creating the llvm::Module.
```
The relevant cast first appears in the output of the nested convert-gpu-to-nvvm pass. The preceding default convert-vector-to-scf pass leaves the rank-1 transfer operation unchanged.
### Expected result
The pipeline should fully lower this legal rank-1 transfer operation and should not leave an unreconciled materialization cast.
Contributor guide
Research direction
Start with input.mlir and reproduce the failure using the shown mlir-opt gpu-lower-to-nvvm-pipeline command. Inspect the default convert-vector-to-scf and nested convert-gpu-to-nvvm stages, focusing on the rank-1 vector.transfer_read and the resulting memref descriptor cast; done means the legal transfer lowers fully without an unreconciled cast or LLVM translation failure.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100