Skip to content

[SPIR-V] Built-in variables: mapping from an OpenCL to SPIR-V BuiltIn and SPIR-V friendly builtins for Image Read/Write instructions #127242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall,
// Check if the extracted name begins with:
// - "__spirv_ImageSampleExplicitLod"
// - "__spirv_ImageRead"
// - "__spirv_ImageWrite"
// - "__spirv_ImageQuerySizeLod"
// - "__spirv_UDotKHR"
// - "__spirv_SDotKHR"
Expand All @@ -233,20 +234,21 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall,
// - "__spirv_SConvert"
// - "__spirv_FConvert"
// - "__spirv_SatConvert"
// and contains return type information at the end "_R<type>".
// and maybe contains return type information at the end "_R<type>".
// If so, extract the plain builtin name without the type information.
static const std::regex SpvWithR(
"(__spirv_(ImageSampleExplicitLod|ImageRead|ImageQuerySizeLod|UDotKHR|"
"(__spirv_(ImageSampleExplicitLod|ImageRead|ImageWrite|ImageQuerySizeLod|"
"UDotKHR|"
"SDotKHR|SUDotKHR|SDotAccSatKHR|UDotAccSatKHR|SUDotAccSatKHR|"
"ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|"
"SubgroupImageMediaBlockReadINTEL|SubgroupImageMediaBlockWriteINTEL|"
"Convert|"
"UConvert|SConvert|FConvert|SatConvert).*)_R[^_]*_?(\\w+)?.*");
"UConvert|SConvert|FConvert|SatConvert)[^_]*)(_R[^_]*_?(\\w+)?.*)?");
std::smatch Match;
if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 1) {
std::ssub_match SubMatch;
if (DecorationId && Match.size() > 3) {
SubMatch = Match[3];
SubMatch = Match[4];
*DecorationId = demangledPostfixToDecorationId(SubMatch.str());
}
SubMatch = Match[1];
Expand Down Expand Up @@ -1931,6 +1933,9 @@ static bool generateReadImageInst(const StringRef DemangledCall,
const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
if (Call->isSpirvOp())
return buildOpFromWrapper(MIRBuilder, SPIRV::OpImageRead, Call,
GR->getSPIRVTypeID(Call->ReturnType));
Register Image = Call->Arguments[0];
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
bool HasOclSampler = DemangledCall.contains_insensitive("ocl_sampler");
Expand Down Expand Up @@ -2010,6 +2015,9 @@ static bool generateReadImageInst(const StringRef DemangledCall,
static bool generateWriteImageInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
if (Call->isSpirvOp())
return buildOpFromWrapper(MIRBuilder, SPIRV::OpImageWrite, Call,
Register(0));
MIRBuilder.buildInstr(SPIRV::OpImageWrite)
.addUse(Call->Arguments[0]) // Image.
.addUse(Call->Arguments[1]) // Coordinate.
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ def : DemangledBuiltin<"__spirv_DotAccSat", OpenCL_std, IntegerDot, 3, 3>;
def : DemangledBuiltin<"read_imagei", OpenCL_std, ReadImage, 2, 4>;
def : DemangledBuiltin<"read_imageui", OpenCL_std, ReadImage, 2, 4>;
def : DemangledBuiltin<"read_imagef", OpenCL_std, ReadImage, 2, 4>;
def : DemangledBuiltin<"__spirv_ImageRead", OpenCL_std, ReadImage, 2, 0>;

def : DemangledBuiltin<"write_imagef", OpenCL_std, WriteImage, 3, 4>;
def : DemangledBuiltin<"write_imagei", OpenCL_std, WriteImage, 3, 4>;
def : DemangledBuiltin<"write_imageui", OpenCL_std, WriteImage, 3, 4>;
def : DemangledBuiltin<"write_imageh", OpenCL_std, WriteImage, 3, 4>;
def : DemangledBuiltin<"__spirv_ImageWrite", OpenCL_std, WriteImage, 3, 0>;

def : DemangledBuiltin<"__translate_sampler_initializer", OpenCL_std, SampleImage, 1, 1>;
def : DemangledBuiltin<"__spirv_SampledImage", OpenCL_std, SampleImage, 2, 2>;
Expand Down Expand Up @@ -1323,6 +1325,15 @@ multiclass DemangledGetBuiltin<string name, InstructionSet set, BuiltinGroup gro
}

// Builtin variable records:
defm : DemangledGetBuiltin<"get_global_linear_id", OpenCL_std, Variable, GlobalLinearId>;
defm : DemangledGetBuiltin<"get_local_linear_id", OpenCL_std, Variable, LocalInvocationIndex>;
defm : DemangledGetBuiltin<"get_work_dim", OpenCL_std, Variable, WorkDim>;
defm : DemangledGetBuiltin<"get_sub_group_size", OpenCL_std, Variable, SubgroupSize>;
defm : DemangledGetBuiltin<"get_max_sub_group_size", OpenCL_std, Variable, SubgroupMaxSize>;
defm : DemangledGetBuiltin<"get_num_sub_groups", OpenCL_std, Variable, NumSubgroups>;
defm : DemangledGetBuiltin<"get_enqueued_num_sub_groups", OpenCL_std, Variable, NumEnqueuedSubgroups>;
defm : DemangledGetBuiltin<"get_sub_group_id", OpenCL_std, Variable, SubgroupId>;
defm : DemangledGetBuiltin<"get_sub_group_local_id", OpenCL_std, Variable, SubgroupLocalInvocationId>;
defm : DemangledGetBuiltin<"get_sub_group_eq_mask", OpenCL_std, Variable, SubgroupEqMask>;
defm : DemangledGetBuiltin<"get_sub_group_ge_mask", OpenCL_std, Variable, SubgroupGeMask>;
defm : DemangledGetBuiltin<"get_sub_group_gt_mask", OpenCL_std, Variable, SubgroupGtMask>;
Expand All @@ -1339,6 +1350,7 @@ defm : DemangledGetBuiltin<"get_global_size", OpenCL_std, GetQuery, GlobalSize>;
defm : DemangledGetBuiltin<"get_group_id", OpenCL_std, GetQuery, WorkgroupId>;
defm : DemangledGetBuiltin<"get_enqueued_local_size", OpenCL_std, GetQuery, EnqueuedWorkgroupSize>;
defm : DemangledGetBuiltin<"get_num_groups", OpenCL_std, GetQuery, NumWorkgroups>;
defm : DemangledGetBuiltin<"get_global_offset", OpenCL_std, GetQuery, GlobalOffset>;
defm : DemangledGetBuiltin<"__hlsl_wave_get_lane_index", GLSL_std_450, Wave, SubgroupLocalInvocationId>;

//===----------------------------------------------------------------------===//
Expand Down
85 changes: 66 additions & 19 deletions llvm/test/CodeGen/SPIRV/builtin_vars-decorate.ll
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s

; CHECK: OpName %[[#WD:]] "__spirv_BuiltInWorkDim"
; CHECK: OpName %[[#GS:]] "__spirv_BuiltInGlobalSize"
; CHECK: OpName %[[#GII:]] "__spirv_BuiltInGlobalInvocationId"
; CHECK: OpName %[[#WS:]] "__spirv_BuiltInWorkgroupSize"
; CHECK: OpName %[[#EWS:]] "__spirv_BuiltInEnqueuedWorkgroupSize"
; CHECK: OpName %[[#LLI:]] "__spirv_BuiltInLocalInvocationId"
; CHECK: OpName %[[#NW:]] "__spirv_BuiltInNumWorkgroups"
; CHECK: OpName %[[#WI:]] "__spirv_BuiltInWorkgroupId"
; CHECK: OpName %[[#GO:]] "__spirv_BuiltInGlobalOffset"
; CHECK: OpName %[[#GLI:]] "__spirv_BuiltInGlobalLinearId"
; CHECK: OpName %[[#LLII:]] "__spirv_BuiltInLocalInvocationIndex"
; CHECK: OpName %[[#SS:]] "__spirv_BuiltInSubgroupSize"
; CHECK: OpName %[[#SMS:]] "__spirv_BuiltInSubgroupMaxSize"
; CHECK: OpName %[[#NS:]] "__spirv_BuiltInNumSubgroups"
; CHECK: OpName %[[#NES:]] "__spirv_BuiltInNumEnqueuedSubgroups"
; CHECK: OpName %[[#SI:]] "__spirv_BuiltInSubgroupId"
; CHECK: OpName %[[#SLII:]] "__spirv_BuiltInSubgroupLocalInvocationId"
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: OpName %[[#WD:]] "__spirv_BuiltInWorkDim"
; CHECK-DAG: OpName %[[#GS:]] "__spirv_BuiltInGlobalSize"
; CHECK-DAG: OpName %[[#GII:]] "__spirv_BuiltInGlobalInvocationId"
; CHECK-DAG: OpName %[[#WS:]] "__spirv_BuiltInWorkgroupSize"
; CHECK-DAG: OpName %[[#EWS:]] "__spirv_BuiltInEnqueuedWorkgroupSize"
; CHECK-DAG: OpName %[[#LLI:]] "__spirv_BuiltInLocalInvocationId"
; CHECK-DAG: OpName %[[#NW:]] "__spirv_BuiltInNumWorkgroups"
; CHECK-DAG: OpName %[[#WI:]] "__spirv_BuiltInWorkgroupId"
; CHECK-DAG: OpName %[[#GO:]] "__spirv_BuiltInGlobalOffset"
; CHECK-DAG: OpName %[[#GLI:]] "__spirv_BuiltInGlobalLinearId"
; CHECK-DAG: OpName %[[#LLII:]] "__spirv_BuiltInLocalInvocationIndex"
; CHECK-DAG: OpName %[[#SS:]] "__spirv_BuiltInSubgroupSize"
; CHECK-DAG: OpName %[[#SMS:]] "__spirv_BuiltInSubgroupMaxSize"
; CHECK-DAG: OpName %[[#NS:]] "__spirv_BuiltInNumSubgroups"
; CHECK-DAG: OpName %[[#NES:]] "__spirv_BuiltInNumEnqueuedSubgroups"
; CHECK-DAG: OpName %[[#SI:]] "__spirv_BuiltInSubgroupId"
; CHECK-DAG: OpName %[[#SLII:]] "__spirv_BuiltInSubgroupLocalInvocationId"

; CHECK-DAG: OpDecorate %[[#NW]] BuiltIn NumWorkgroups
; CHECK-DAG: OpDecorate %[[#WS]] BuiltIn WorkgroupSize
Expand All @@ -35,6 +36,33 @@
; CHECK-DAG: OpDecorate %[[#NES]] BuiltIn NumEnqueuedSubgroups
; CHECK-DAG: OpDecorate %[[#SI]] BuiltIn SubgroupId
; CHECK-DAG: OpDecorate %[[#SLII]] BuiltIn SubgroupLocalInvocationId

; CHECK-DAG: %[[#SizeT:]] = OpTypeInt 64 0
; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#SizeTPtr:]] = OpTypePointer Input %[[#SizeT]]
; CHECK-DAG: %[[#Int32Ptr:]] = OpTypePointer Input %[[#Int32]]

; CHECK-DAG: %[[#GLI]] = OpVariable %[[#SizeTPtr]] Input
; CHECK-DAG: %[[#LLII]] = OpVariable %[[#SizeTPtr]] Input
; CHECK-DAG: %[[#WD]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#SS]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#SMS]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#NS]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#NES]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#SI]] = OpVariable %[[#Int32Ptr]] Input
; CHECK-DAG: %[[#SLII]] = OpVariable %[[#Int32Ptr]] Input

; CHECK: OpFunction
; CHECK: %[[#]] = OpLoad %[[#SizeT]] %[[#GLI]]
; CHECK: %[[#]] = OpLoad %[[#SizeT]] %[[#LLII]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#WD]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#SS]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#SMS]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#NS]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#NES]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#SI]]
; CHECK: %[[#]] = OpLoad %[[#Int32]] %[[#SLII]]

@__spirv_BuiltInWorkDim = external addrspace(1) global i32
@__spirv_BuiltInGlobalSize = external addrspace(1) global <3 x i32>
@__spirv_BuiltInGlobalInvocationId = external addrspace(1) global <3 x i32>
Expand All @@ -55,5 +83,24 @@

define spir_kernel void @_Z1wv() {
entry:
%r1 = tail call spir_func i64 @get_global_linear_id()
%r2 = tail call spir_func i64 @get_local_linear_id()
%r3 = tail call spir_func i32 @get_work_dim()
%r4 = tail call spir_func i32 @get_sub_group_size()
%r5 = tail call spir_func i32 @get_max_sub_group_size()
%r6 = tail call spir_func i32 @get_num_sub_groups()
%r7 = tail call spir_func i32 @get_enqueued_num_sub_groups()
%r8 = tail call spir_func i32 @get_sub_group_id()
%r9 = tail call spir_func i32 @get_sub_group_local_id()
ret void
}

declare spir_func i64 @get_global_linear_id()
declare spir_func i64 @get_local_linear_id()
declare spir_func i32 @get_work_dim()
declare spir_func i32 @get_sub_group_size()
declare spir_func i32 @get_max_sub_group_size()
declare spir_func i32 @get_num_sub_groups()
declare spir_func i32 @get_enqueued_num_sub_groups()
declare spir_func i32 @get_sub_group_id()
declare spir_func i32 @get_sub_group_local_id()
9 changes: 6 additions & 3 deletions llvm/test/CodeGen/SPIRV/transcoding/builtin_vars.ll
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-SPIRV: OpDecorate %[[#Id:]] BuiltIn GlobalLinearId
; CHECK-SPIRV: %[[#Id:]] = OpVariable %[[#]]
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK: OpDecorate %[[#Id:]] BuiltIn GlobalLinearId
; CHECK: %[[#Id:]] = OpVariable %[[#]]

@__spirv_BuiltInGlobalLinearId = external addrspace(1) global i32

Expand Down
58 changes: 57 additions & 1 deletion llvm/test/CodeGen/SPIRV/transcoding/spirv-types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,61 @@ define spir_func void @test_sampler(target("spirv.Image", float, 1, 1, 0, 0, 0,
}

declare spir_func target("spirv.Image", float, 1, 1, 0, 0, 0, 0, 0) @_Z20__spirv_SampledImagePU3AS1K34__spirv_Image__float_1_1_0_0_0_0_0PU3AS1K15__spirv_Sampler(target("spirv.Image", float, 1, 1, 0, 0, 0, 0, 0), target("spirv.Sampler"))

declare spir_func <4 x float> @_Z38__spirv_ImageSampleExplicitLod_Rfloat4PU3AS120__spirv_SampledImageDv4_iif(target("spirv.Image", float, 1, 1, 0, 0, 0, 0, 0), <4 x i32>, i32, float)

; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageRead
; CHECK-SPIRV: %[[#]] = OpImageSampleExplicitLod

define dso_local spir_kernel void @reads() {
%1 = tail call spir_func i32 @_Z17__spirv_ImageReadIi14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0) poison, <4 x i32> zeroinitializer)
%2 = tail call spir_func <2 x i32> @_Z17__spirv_ImageReadIDv2_i14ocl_image2d_roS0_ET_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) poison, <2 x i32> zeroinitializer)
%3 = tail call spir_func <4 x i32> @_Z17__spirv_ImageReadIDv4_j14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0) poison, <4 x i32> zeroinitializer)
%4 = tail call spir_func signext i16 @_Z17__spirv_ImageReadIs14ocl_image1d_roiET_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) poison, i32 0)
%5 = tail call spir_func zeroext i16 @_Z17__spirv_ImageReadIt14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0) poison, <4 x i32> zeroinitializer)
%6 = tail call spir_func <2 x float> @_Z17__spirv_ImageReadIDv2_f14ocl_image1d_roiET_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) poison, i32 0)
%7 = tail call spir_func half @_Z17__spirv_ImageReadIDF16_14ocl_image2d_roDv2_iET_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) poison, <2 x i32> zeroinitializer)
%8 = tail call spir_func <4 x i32> @_Z30__spirv_ImageSampleExplicitLodI32__spirv_SampledImage__image1d_roDv4_jfET0_T_T1_if(target("spirv.SampledImage", void, 0, 0, 0, 0, 0, 0, 0) poison, float 0.000000e+00, i32 2, float 0.000000e+00)
ret void
}

declare dso_local spir_func i32 @_Z17__spirv_ImageReadIi14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0), <4 x i32>)
declare dso_local spir_func <2 x i32> @_Z17__spirv_ImageReadIDv2_i14ocl_image2d_roS0_ET_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0), <2 x i32>)
declare dso_local spir_func <4 x i32> @_Z17__spirv_ImageReadIDv4_j14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0), <4 x i32>)
declare dso_local spir_func signext i16 @_Z17__spirv_ImageReadIs14ocl_image1d_roiET_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0), i32)
declare dso_local spir_func zeroext i16 @_Z17__spirv_ImageReadIt14ocl_image3d_roDv4_iET_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 0), <4 x i32>)
declare dso_local spir_func <2 x float> @_Z17__spirv_ImageReadIDv2_f14ocl_image1d_roiET_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0), i32)
declare dso_local spir_func half @_Z17__spirv_ImageReadIDF16_14ocl_image2d_roDv2_iET_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0), <2 x i32>)
declare dso_local spir_func <4 x i32> @_Z30__spirv_ImageSampleExplicitLodI32__spirv_SampledImage__image1d_roDv4_jfET0_T_T1_if(target("spirv.SampledImage", void, 0, 0, 0, 0, 0, 0, 0), float noundef, i32 noundef, float noundef)

; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite
; CHECK-SPIRV: OpImageWrite

define dso_local spir_kernel void @writes() {
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_iiEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1) poison, <4 x i32> zeroinitializer, i32 zeroinitializer)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image2d_woDv2_iS1_EvT_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 1) poison, <2 x i32> zeroinitializer, <2 x i32> zeroinitializer)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_iDv4_jEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1) poison, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image1d_woisEvT_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1) poison, i32 0, i16 signext 0)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_itEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1) poison, <4 x i32> zeroinitializer, i16 zeroext 0)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image1d_woiDv2_fEvT_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1) poison, i32 0, <2 x float> zeroinitializer)
call spir_func void @_Z18__spirv_ImageWriteI14ocl_image2d_woDv2_iDF16_EvT_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 1) poison, <2 x i32> zeroinitializer, half zeroinitializer)
ret void
}

declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_iiEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1), <4 x i32>, i32)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image2d_woDv2_iS1_EvT_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 1), <2 x i32>, <2 x i32>)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_iDv4_jEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1), <4 x i32>, <4 x i32>)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image1d_woisEvT_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1), i32, i16 signext)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image3d_woDv4_itEvT_T0_T1_(target("spirv.Image", void, 2, 0, 0, 0, 0, 0, 1), <4 x i32>, i16 zeroext)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image1d_woiDv2_fEvT_T0_T1_(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1), i32, <2 x float>)
declare dso_local spir_func void @_Z18__spirv_ImageWriteI14ocl_image2d_woDv2_iDF16_EvT_T0_T1_(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 1), <2 x i32>, half)