Skip to content

Commit cc7eff1

Browse files
AlexeySachkovsvenvh
authored andcommitted
Backport fix translation of read_image* built-ins to SPIR-V to 9.0 release
There are several overloads of read_image function defined by OpenCL C spec, but all of them use the same SPIR-V instruction, so, we need to add one more optional postfix to differentiate instructions with the same argument types, but different return types. Example: - int4 read_imagei(image2d_t, sampler_t, int2) - float4 read_imagef(image2d_t, sampler_t, int2) Both functions above are represented by the same SPIR-V instruction and we need to distinguish them in SPIR-V friendly LLVM IR. Signed-off-by: Alexey Sachkov <alexey.sachkov@intel.com>
1 parent a4b2532 commit cc7eff1

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

lib/SPIRV/OCL20ToSPIRV.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,23 @@ void OCL20ToSPIRV::transBuiltin(CallInst *CI, OCLBuiltinTransInfo &Info) {
10271027
unsigned ExtOp = ~0U;
10281028
if (StringRef(Info.UniqName).startswith(kSPIRVName::Prefix))
10291029
return;
1030-
if (OCLSPIRVBuiltinMap::find(Info.UniqName, &OC))
1031-
Info.UniqName = getSPIRVFuncName(OC);
1032-
else if ((ExtOp = getExtOp(Info.MangledName, Info.UniqName)) != ~0U)
1030+
if (OCLSPIRVBuiltinMap::find(Info.UniqName, &OC)) {
1031+
if (OC == OpImageRead) {
1032+
// There are several read_image* functions defined by OpenCL C spec, but
1033+
// all of them use the same SPIR-V Instruction - some of them might only
1034+
// differ by return type, so, we need to include return type into the
1035+
// mangling scheme to get them differentiated.
1036+
//
1037+
// Example: int4 read_imagei(image2d_t, sampler_t, int2)
1038+
// uint4 read_imageui(image2d_t, sampler_t, int2)
1039+
// Both functions above are represented by the same SPIR-V
1040+
// instruction: argument types are the same, only return type is
1041+
// different
1042+
Info.UniqName = getSPIRVFuncName(OC, CI->getType());
1043+
} else {
1044+
Info.UniqName = getSPIRVFuncName(OC);
1045+
}
1046+
} else if ((ExtOp = getExtOp(Info.MangledName, Info.UniqName)) != ~0U)
10331047
Info.UniqName = getSPIRVExtFuncName(SPIRVEIS_OpenCL, ExtOp);
10341048
else
10351049
return;

test/read_image.cl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -triple spir64 -finclude-default-header -O0 -cl-std=CL2.0 -emit-llvm-bc %s -o %t.bc
2+
// RUN: llvm-spirv %t.bc -o %t.spv
3+
// RUN: spirv-val %t.spv
4+
// RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5+
// RUN: llvm-spirv -s %t.bc -o %t1.bc
6+
// RUN: llvm-dis %t1.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
7+
8+
// CHECK-SPIRV: TypeInt [[IntTy:[0-9]+]]
9+
// CHECK-SPIRV: TypeVector [[IVecTy:[0-9]+]] [[IntTy]]
10+
// CHECK-SPIRV: TypeFloat [[FloatTy:[0-9]+]]
11+
// CHECK-SPIRV: TypeVector [[FVecTy:[0-9]+]] [[FloatTy]]
12+
// CHECK-SPIRV: ImageRead [[IVecTy]]
13+
// CHECK-SPIRV: ImageRead [[FVecTy]]
14+
15+
// CHECK-LLVM: call spir_func <4 x i32> @_Z24__spirv_ImageRead_Ruint414ocl_image3d_roDv4_i
16+
// CHECK-LLVM: call spir_func <4 x float> @_Z25__spirv_ImageRead_Rfloat414ocl_image3d_roDv4_i
17+
18+
__kernel void kernelA(__read_only image3d_t input) {
19+
uint4 c = read_imageui(input, (int4)(0, 0, 0, 0));
20+
}
21+
22+
__kernel void kernelB(__read_only image3d_t input) {
23+
float4 f = read_imagef(input, (int4)(0, 0, 0, 0));
24+
}

0 commit comments

Comments
 (0)