-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Description
Background:
Conversion to SPIR-V does not have a one-shot conversion pass like llvm convert-to-llvm
. Instead it is encouraged to use progressive lowering (https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp#L153). However, progressive lowering doesn't always work and we end up with builtin.unrealized_conversion_cast
that fails in convert-gpu-to-spirv
.
Let's take the following test case:
module @gemm attributes {gpu.container_module, spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [Addresses, Int64, Int8, Kernel, Linkage, Vector16], []>, api=OpenCL, #spirv.resource_limits<>>} {
gpu.module @test_kernel [#spirv.target_env<#spirv.vce<v1.4,[Addresses, Int64, Int8, Kernel, Linkage], []>, #spirv.resource_limits<>>] attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [Addresses, Int64, Int8, Kernel, Linkage], []>, api=OpenCL, #spirv.resource_limits<>>} {
func.func private @external_func_with_linkage(vector<1xi1>, i8, i64) attributes {linkage_attributes = #spirv.linkage_attributes<linkage_name = "external_func_with_linkage", linkage_type = <Import>>}
gpu.func @test_kernel(%arg0: memref<512xf32>, %arg1: memref<512xf32>, %arg2: memref<512xf32>) kernel attributes {spirv.entry_point_abi = #spirv.entry_point_abi<>} {
%cst = arith.constant dense<true> : vector<1xi1>
%cst_i8 = arith.constant 1 : i8
%c16 = arith.constant 16 : index
%thread_id_x = gpu.thread_id x
%0 = arith.muli %thread_id_x, %c16 : index
%2 = arith.index_castui %0 : index to i64
func.call @external_func_with_linkage(%cst, %cst_i8, %2) : (vector<1xi1>, i8, i64) -> ()
gpu.return
}
}
}
If we use the following pipeline, it fails in convert-gpu-to-spirv
due to the builtin.unrealized_conversion_cast
on the result of %thread_id_x = gpu.thread_id x
which is used in an Arith op. During the convert-arith-to-spirv
, this builtin.unrealized_conversion_cast
to facilitate %0 = arith.muli %thread_id_x, %c16 : index
conversion to SPIR-V.
Pipeline:
-convert-index-to-spirv -convert-arith-to-spirv -convert-func-to-spirv -reconcile-unrealized-casts -convert-gpu-to-spirv
Am I doing something wrong here? If not, what could be the potential solution? Should we perhaps have a one-shot-spirv conversion pass (i.e. convert-gpu-to-spirv
)