Skip to content

Commit 4e49103

Browse files
Add SPIR-V friendly builtins for Image Read/Write instructions
1 parent 798890e commit 4e49103

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall,
216216
// Check if the extracted name begins with:
217217
// - "__spirv_ImageSampleExplicitLod"
218218
// - "__spirv_ImageRead"
219+
// - "__spirv_ImageWrite"
219220
// - "__spirv_ImageQuerySizeLod"
220221
// - "__spirv_UDotKHR"
221222
// - "__spirv_SDotKHR"
@@ -233,20 +234,21 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall,
233234
// - "__spirv_SConvert"
234235
// - "__spirv_FConvert"
235236
// - "__spirv_SatConvert"
236-
// and contains return type information at the end "_R<type>".
237+
// and maybe contains return type information at the end "_R<type>".
237238
// If so, extract the plain builtin name without the type information.
238239
static const std::regex SpvWithR(
239-
"(__spirv_(ImageSampleExplicitLod|ImageRead|ImageQuerySizeLod|UDotKHR|"
240+
"(__spirv_(ImageSampleExplicitLod|ImageRead|ImageWrite|ImageQuerySizeLod|"
241+
"UDotKHR|"
240242
"SDotKHR|SUDotKHR|SDotAccSatKHR|UDotAccSatKHR|SUDotAccSatKHR|"
241243
"ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|"
242244
"SubgroupImageMediaBlockReadINTEL|SubgroupImageMediaBlockWriteINTEL|"
243245
"Convert|"
244-
"UConvert|SConvert|FConvert|SatConvert).*)_R[^_]*_?(\\w+)?.*");
246+
"UConvert|SConvert|FConvert|SatConvert)[^_]*)(_R[^_]*_?(\\w+)?.*)?");
245247
std::smatch Match;
246248
if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 1) {
247249
std::ssub_match SubMatch;
248250
if (DecorationId && Match.size() > 3) {
249-
SubMatch = Match[3];
251+
SubMatch = Match[4];
250252
*DecorationId = demangledPostfixToDecorationId(SubMatch.str());
251253
}
252254
SubMatch = Match[1];
@@ -1931,6 +1933,9 @@ static bool generateReadImageInst(const StringRef DemangledCall,
19311933
const SPIRV::IncomingCall *Call,
19321934
MachineIRBuilder &MIRBuilder,
19331935
SPIRVGlobalRegistry *GR) {
1936+
if (Call->isSpirvOp())
1937+
return buildOpFromWrapper(MIRBuilder, SPIRV::OpImageRead, Call,
1938+
GR->getSPIRVTypeID(Call->ReturnType));
19341939
Register Image = Call->Arguments[0];
19351940
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
19361941
bool HasOclSampler = DemangledCall.contains_insensitive("ocl_sampler");
@@ -2010,6 +2015,9 @@ static bool generateReadImageInst(const StringRef DemangledCall,
20102015
static bool generateWriteImageInst(const SPIRV::IncomingCall *Call,
20112016
MachineIRBuilder &MIRBuilder,
20122017
SPIRVGlobalRegistry *GR) {
2018+
if (Call->isSpirvOp())
2019+
return buildOpFromWrapper(MIRBuilder, SPIRV::OpImageWrite, Call,
2020+
Register(0));
20132021
MIRBuilder.buildInstr(SPIRV::OpImageWrite)
20142022
.addUse(Call->Arguments[0]) // Image.
20152023
.addUse(Call->Arguments[1]) // Coordinate.

llvm/lib/Target/SPIRV/SPIRVBuiltins.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,13 @@ def : DemangledBuiltin<"__spirv_DotAccSat", OpenCL_std, IntegerDot, 3, 3>;
110110
def : DemangledBuiltin<"read_imagei", OpenCL_std, ReadImage, 2, 4>;
111111
def : DemangledBuiltin<"read_imageui", OpenCL_std, ReadImage, 2, 4>;
112112
def : DemangledBuiltin<"read_imagef", OpenCL_std, ReadImage, 2, 4>;
113+
def : DemangledBuiltin<"__spirv_ImageRead", OpenCL_std, ReadImage, 2, 0>;
113114

114115
def : DemangledBuiltin<"write_imagef", OpenCL_std, WriteImage, 3, 4>;
115116
def : DemangledBuiltin<"write_imagei", OpenCL_std, WriteImage, 3, 4>;
116117
def : DemangledBuiltin<"write_imageui", OpenCL_std, WriteImage, 3, 4>;
117118
def : DemangledBuiltin<"write_imageh", OpenCL_std, WriteImage, 3, 4>;
119+
def : DemangledBuiltin<"__spirv_ImageWrite", OpenCL_std, WriteImage, 3, 0>;
118120

119121
def : DemangledBuiltin<"__translate_sampler_initializer", OpenCL_std, SampleImage, 1, 1>;
120122
def : DemangledBuiltin<"__spirv_SampledImage", OpenCL_std, SampleImage, 2, 2>;

llvm/test/CodeGen/SPIRV/transcoding/spirv-types.ll

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,61 @@ define spir_func void @test_sampler(target("spirv.Image", float, 1, 1, 0, 0, 0,
8585
}
8686

8787
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"))
88-
8988
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)
89+
90+
; CHECK-SPIRV: %[[#]] = OpImageRead
91+
; CHECK-SPIRV: %[[#]] = OpImageRead
92+
; CHECK-SPIRV: %[[#]] = OpImageRead
93+
; CHECK-SPIRV: %[[#]] = OpImageRead
94+
; CHECK-SPIRV: %[[#]] = OpImageRead
95+
; CHECK-SPIRV: %[[#]] = OpImageRead
96+
; CHECK-SPIRV: %[[#]] = OpImageRead
97+
; CHECK-SPIRV: %[[#]] = OpImageSampleExplicitLod
98+
99+
define dso_local spir_kernel void @reads() {
100+
%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)
101+
%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)
102+
%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)
103+
%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)
104+
%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)
105+
%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)
106+
%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)
107+
%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)
108+
ret void
109+
}
110+
111+
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>)
112+
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>)
113+
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>)
114+
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)
115+
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>)
116+
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)
117+
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>)
118+
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)
119+
120+
; CHECK-SPIRV: OpImageWrite
121+
; CHECK-SPIRV: OpImageWrite
122+
; CHECK-SPIRV: OpImageWrite
123+
; CHECK-SPIRV: OpImageWrite
124+
; CHECK-SPIRV: OpImageWrite
125+
; CHECK-SPIRV: OpImageWrite
126+
; CHECK-SPIRV: OpImageWrite
127+
128+
define dso_local spir_kernel void @writes() {
129+
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)
130+
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)
131+
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)
132+
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)
133+
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)
134+
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)
135+
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)
136+
ret void
137+
}
138+
139+
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)
140+
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>)
141+
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>)
142+
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)
143+
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)
144+
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>)
145+
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)

0 commit comments

Comments
 (0)