Skip to content

Commit 951a6ad

Browse files
[OpaquePointers] Add support for translating target extension types. (#1799)
The target extension type for SPIR-V is essentially target("spirv.TypeName", <image type>, <int params>). Most of the work to support translation of these types has already happened beforehand, so the primary step here is to enable translation work in SPIRVWriter as well as making the SPIRVBuiltinHelpers work with target types as well. Constructing LLVM IR from SPIR-V using these types is not yet supported, mainly out of uncertainty of the proper interface to let the resultant consumers indicate that they wish to support these types.
1 parent 6a0368f commit 951a6ad

File tree

5 files changed

+303
-3
lines changed

5 files changed

+303
-3
lines changed

lib/SPIRV/SPIRVBuiltinHelper.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,18 @@ Type *BuiltinCallHelper::adjustImageType(Type *T, StringRef OldImageKind,
279279
}
280280
return TypedPointerType::get(StructTy, TypedPtrTy->getAddressSpace());
281281
}
282+
283+
if (auto *TargetTy = dyn_cast<TargetExtType>(T)) {
284+
StringRef Name = TargetTy->getName();
285+
if (!Name.consume_front(kSPIRVTypeName::PrefixAndDelim) ||
286+
Name != OldImageKind)
287+
report_fatal_error("Type did not have expected image kind");
288+
return TargetExtType::get(
289+
TargetTy->getContext(),
290+
(Twine(kSPIRVTypeName::PrefixAndDelim) + NewImageKind).str(),
291+
TargetTy->type_params(), TargetTy->int_params());
292+
}
293+
282294
report_fatal_error("Expected type to be a SPIRV image type");
283295
}
284296

@@ -307,6 +319,19 @@ Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
307319
StringRef InnerTypeName,
308320
ArrayRef<unsigned> Parameters,
309321
bool UseRealType) {
322+
if (UseTargetTypes) {
323+
std::string BaseName = (Twine(kSPIRVTypeName::PrefixAndDelim) +
324+
SPIRVOpaqueTypeOpCodeMap::rmap(TypeOpcode))
325+
.str();
326+
SmallVector<Type *, 1> TypeParams;
327+
if (!InnerTypeName.empty()) {
328+
TypeParams.push_back(getLLVMTypeForSPIRVImageSampledTypePostfix(
329+
InnerTypeName, M->getContext()));
330+
}
331+
return TargetExtType::get(M->getContext(), BaseName, TypeParams,
332+
Parameters);
333+
}
334+
310335
std::string FullName;
311336
{
312337
raw_string_ostream OS(FullName);
@@ -328,6 +353,23 @@ Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
328353
: TypedPointerType::get(STy, AddrSpace);
329354
}
330355

356+
void BuiltinCallHelper::initialize(llvm::Module &M) {
357+
this->M = &M;
358+
// We want to use pointers-to-opaque-structs for the special types if:
359+
// * We are translating from SPIR-V to LLVM IR (which means we are using
360+
// OpenCL mangling rules)
361+
// * There are %opencl.* or %spirv.* struct type names already present.
362+
UseTargetTypes = Rules != ManglingRules::OpenCL;
363+
for (StructType *Ty : M.getIdentifiedStructTypes()) {
364+
if (!Ty->isOpaque() || !Ty->hasName())
365+
continue;
366+
StringRef Name = Ty->getName();
367+
if (Name.startswith("opencl.") || Name.startswith("spirv.")) {
368+
UseTargetTypes = false;
369+
}
370+
}
371+
}
372+
331373
BuiltinCallMutator::ValueTypePair
332374
BuiltinCallHelper::getCallValue(CallInst *CI, unsigned ArgNo) {
333375
Function *CalledFunc = CI->getCalledFunction();

lib/SPIRV/SPIRVBuiltinHelper.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ class BuiltinCallHelper {
252252

253253
protected:
254254
llvm::Module *M = nullptr;
255+
bool UseTargetTypes = false;
255256

256257
public:
257258
/// Initialize details about how to mangle and demangle builtins correctly.
@@ -265,7 +266,7 @@ class BuiltinCallHelper {
265266

266267
/// Initialize the module that will be operated on. This method must be called
267268
/// before future methods.
268-
void initialize(llvm::Module &M) { this->M = &M; }
269+
void initialize(llvm::Module &M);
269270

270271
/// Return a mutator that will replace the given call instruction with a call
271272
/// to the given function name. The function name will have its name mangled

lib/SPIRV/SPIRVUtil.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ bool getParameterTypes(Function *F, SmallVectorImpl<Type *> &ArgTys,
885885
LLVM_DEBUG(dbgs() << "Failed to recover type of argument " << *ArgTy
886886
<< " of function " << F->getName() << "\n");
887887
DemangledSuccessfully = false;
888-
} else if (!DemangledTy)
888+
} else if (ArgTy->isTargetExtTy() || !DemangledTy)
889889
DemangledTy = ArgTy;
890890
*ArgIter++ = DemangledTy;
891891
}
@@ -1336,6 +1336,25 @@ static SPIR::RefParamType transTypeDesc(Type *Ty,
13361336
}
13371337
return SPIR::RefParamType(new SPIR::UserDefinedType(Name.str()));
13381338
}
1339+
if (auto *TargetTy = dyn_cast<TargetExtType>(Ty)) {
1340+
std::string FullName;
1341+
{
1342+
raw_string_ostream OS(FullName);
1343+
StringRef Name = TargetTy->getName();
1344+
if (Name.consume_front(kSPIRVTypeName::PrefixAndDelim)) {
1345+
OS << "__spirv_" << Name;
1346+
} else {
1347+
OS << Name;
1348+
}
1349+
if (!TargetTy->int_params().empty())
1350+
OS << "_";
1351+
for (Type *InnerTy : TargetTy->type_params())
1352+
OS << "_" << convertTypeToPostfix(InnerTy);
1353+
for (unsigned Param : TargetTy->int_params())
1354+
OS << "_" << Param;
1355+
}
1356+
return SPIR::RefParamType(new SPIR::UserDefinedType(FullName));
1357+
}
13391358

13401359
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
13411360
auto *ET = TPT->getElementType();

lib/SPIRV/SPIRVWriter.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,47 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
474474
return mapType(T, getSPIRVFunctionType(RT, PT));
475475
}
476476

477+
if (auto *TargetTy = dyn_cast<TargetExtType>(T)) {
478+
StringRef Name = TargetTy->getName();
479+
if (Name.consume_front(kSPIRVTypeName::PrefixAndDelim)) {
480+
auto Opcode = SPIRVOpaqueTypeOpCodeMap::map(Name.str());
481+
auto CastAccess = [](unsigned Val) {
482+
return static_cast<SPIRVAccessQualifierKind>(Val);
483+
};
484+
switch (Opcode) {
485+
case OpTypePipe: {
486+
auto *PipeT = BM->addPipeType();
487+
PipeT->setPipeAcessQualifier(CastAccess(TargetTy->getIntParameter(0)));
488+
return mapType(T, PipeT);
489+
}
490+
case OpTypeImage: {
491+
auto *SampledTy = transType(TargetTy->getTypeParameter(0));
492+
ArrayRef<unsigned> Ops = TargetTy->int_params();
493+
SPIRVTypeImageDescriptor Desc(static_cast<SPIRVImageDimKind>(Ops[0]),
494+
Ops[1], Ops[2], Ops[3], Ops[4], Ops[5]);
495+
return mapType(T,
496+
BM->addImageType(SampledTy, Desc, CastAccess(Ops[6])));
497+
}
498+
case OpTypeSampledImage: {
499+
auto *ImageTy = static_cast<SPIRVTypeImage *>(transType(adjustImageType(
500+
T, kSPIRVTypeName::SampledImg, kSPIRVTypeName::Image)));
501+
return mapType(T, BM->addSampledImageType(ImageTy));
502+
}
503+
case OpTypeVmeImageINTEL: {
504+
auto *ImageTy = static_cast<SPIRVTypeImage *>(transType(adjustImageType(
505+
T, kSPIRVTypeName::VmeImageINTEL, kSPIRVTypeName::Image)));
506+
return mapType(T, BM->addVmeImageINTELType(ImageTy));
507+
}
508+
case OpTypeQueue:
509+
return mapType(T, BM->addQueueType());
510+
case OpTypeDeviceEvent:
511+
return mapType(T, BM->addDeviceEventType());
512+
default:
513+
return mapType(T, BM->addOpaqueGenericType(Opcode));
514+
}
515+
}
516+
}
517+
477518
llvm_unreachable("Not implemented!");
478519
return 0;
479520
}
@@ -1097,6 +1138,9 @@ SPIRVValue *LLVMToSPIRVBase::transConstant(Value *V) {
10971138
return BM->addNullConstant(
10981139
bcast<SPIRVTypePointer>(transType(CPNull->getType())));
10991140

1141+
if (isa<ConstantTargetNone>(V))
1142+
return BM->addNullConstant(transType(V->getType()));
1143+
11001144
if (auto CAZero = dyn_cast<ConstantAggregateZero>(V)) {
11011145
Type *AggType = CAZero->getType();
11021146
if (const StructType *ST = dyn_cast<StructType>(AggType))
@@ -2788,7 +2832,7 @@ SPIRVValue *LLVMToSPIRVBase::oclTransSpvcCastSampler(CallInst *CI,
27882832
auto FT = F->getFunctionType();
27892833
auto RT = FT->getReturnType();
27902834
assert(FT->getNumParams() == 1);
2791-
if (!RT->isOpaquePointerTy()) {
2835+
if (RT->isPointerTy() && !RT->isOpaquePointerTy()) {
27922836
StructType *ST = dyn_cast<StructType>(RT->getNonOpaquePointerElementType());
27932837
(void)ST;
27942838
assert(isSPIRVStructType(ST, kSPIRVTypeName::Sampler) ||
+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
;; Test SPIR-V opaque types
2+
;;
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-spirv %t.bc -spirv-text -o %t.spv.txt
5+
; RUN: FileCheck < %t.spv.txt %s --check-prefix=CHECK-SPIRV
6+
; RUN: llvm-spirv %t.bc -o %t.from-llvm.spv
7+
; RUN: llvm-spirv -to-binary %t.spv.txt -o %t.from-text.spv
8+
; RUN: llvm-spirv %t.bc -o %t.spv
9+
; RUN: spirv-val %t.spv
10+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
11+
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc
12+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
13+
; RUN: llvm-spirv --spirv-target-env=SPV-IR -r %t.spv -o %t.rev.bc
14+
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc
15+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM-SPIRV
16+
17+
; Check that produced SPIR-V friendly IR is correctly recognized
18+
; RUN: llvm-spirv %t.rev.bc -opaque-pointers=0 -spirv-text -o %t.spv.txt
19+
; RUN: FileCheck < %t.spv.txt %s --check-prefix=CHECK-SPIRV
20+
21+
; CHECK-SPIRV: 2 Capability Float16
22+
; CHECK-SPIRV: 2 Capability ImageBasic
23+
; CHECK-SPIRV: 2 Capability ImageReadWrite
24+
; CHECK-SPIRV: 2 Capability Pipes
25+
; CHECK-SPIRV: 2 Capability DeviceEnqueue
26+
27+
; CHECK-SPIRV-DAG: 2 TypeVoid [[VOID:[0-9]+]]
28+
; CHECK-SPIRV-DAG: 4 TypeInt [[INT:[0-9]+]] 32 0
29+
; CHECK-SPIRV-DAG: 3 TypeFloat [[HALF:[0-9]+]] 16
30+
; CHECK-SPIRV-DAG: 3 TypeFloat [[FLOAT:[0-9]+]] 32
31+
; CHECK-SPIRV-DAG: 3 TypePipe [[PIPE_RD:[0-9]+]] 0
32+
; CHECK-SPIRV-DAG: 3 TypePipe [[PIPE_WR:[0-9]+]] 1
33+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1D_RD:[0-9]+]] [[VOID]] 0 0 0 0 0 0 0
34+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2D_RD:[0-9]+]] [[INT]] 1 0 0 0 0 0 0
35+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG3D_RD:[0-9]+]] [[INT]] 2 0 0 0 0 0 0
36+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2DD_RD:[0-9]+]] [[FLOAT]] 1 1 0 0 0 0 0
37+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2DA_RD:[0-9]+]] [[HALF]] 1 0 1 0 0 0 0
38+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1DB_RD:[0-9]+]] [[FLOAT]] 5 0 0 0 0 0 0
39+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1D_WR:[0-9]+]] [[VOID]] 0 0 0 0 0 0 1
40+
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2D_RW:[0-9]+]] [[VOID]] 1 0 0 0 0 0 2
41+
; CHECK-SPIRV-DAG: 2 TypeDeviceEvent [[DEVEVENT:[0-9]+]]
42+
; CHECK-SPIRV-DAG: 2 TypeEvent [[EVENT:[0-9]+]]
43+
; CHECK-SPIRV-DAG: 2 TypeQueue [[QUEUE:[0-9]+]]
44+
; CHECK-SPIRV-DAG: 2 TypeReserveId [[RESID:[0-9]+]]
45+
; CHECK-SPIRV-DAG: 2 TypeSampler [[SAMP:[0-9]+]]
46+
; CHECK-SPIRV-DAG: 3 TypeSampledImage [[SAMPIMG:[0-9]+]] [[IMG2DD_RD]]
47+
48+
; ModuleID = 'cl-types.cl'
49+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
50+
target triple = "spir-unknown-unknown"
51+
52+
; CHECK-LLVM-DAG: %opencl.pipe_ro_t = type opaque
53+
; CHECK-LLVM-DAG: %opencl.pipe_wo_t = type opaque
54+
; CHECK-LLVM-DAG: %opencl.image3d_ro_t = type opaque
55+
; CHECK-LLVM-DAG: %opencl.image2d_depth_ro_t = type opaque
56+
; CHECK-LLVM-DAG: %opencl.image2d_array_ro_t = type opaque
57+
; CHECK-LLVM-DAG: %opencl.image1d_buffer_ro_t = type opaque
58+
; CHECK-LLVM-DAG: %opencl.image1d_ro_t = type opaque
59+
; CHECK-LLVM-DAG: %opencl.image1d_wo_t = type opaque
60+
; CHECK-LLVM-DAG: %opencl.image2d_ro_t = type opaque
61+
; CHECK-LLVM-DAG: %opencl.image2d_rw_t = type opaque
62+
; CHECK-LLVM-DAG: %opencl.clk_event_t = type opaque
63+
; CHECK-LLVM-DAG: %opencl.event_t = type opaque
64+
; CHECK-LLVM-DAG: %opencl.queue_t = type opaque
65+
; CHECK-LLVM-DAG: %opencl.reserve_id_t = type opaque
66+
67+
; CHECK-LLVM-SPIRV-DAG: %spirv.Pipe._0 = type opaque
68+
; CHECK-LLVM-SPIRV-DAG: %spirv.Pipe._1 = type opaque
69+
70+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_0_0_0_0_0_0_0 = type opaque
71+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._uint_1_0_0_0_0_0_0 = type opaque
72+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._uint_2_0_0_0_0_0_0 = type opaque
73+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._float_1_1_0_0_0_0_0 = type opaque
74+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._half_1_0_1_0_0_0_0 = type opaque
75+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._float_5_0_0_0_0_0_0 = type opaque
76+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_0_0_0_0_0_0_1 = type opaque
77+
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_1_0_0_0_0_0_2 = type opaque
78+
; CHECK-LLVM-SPIRV-DAG: %spirv.DeviceEvent = type opaque
79+
; CHECK-LLVM-SPIRV-DAG: %spirv.Event = type opaque
80+
; CHECK-LLVM-SPIRV-DAG: %spirv.Queue = type opaque
81+
; CHECK-LLVM-SPIRV-DAG: %spirv.ReserveId = type opaque
82+
; CHECK-LLVM-SPIRV-DAG: %spirv.Sampler = type opaque
83+
; CHECK-LLVM-SPIRV-DAG: %spirv.SampledImage._float_1_1_0_0_0_0_0 = type opaque
84+
85+
; CHECK-SPIRV: {{[0-9]+}} Function
86+
; CHECK-SPIRV: 3 FunctionParameter [[PIPE_RD]] {{[0-9]+}}
87+
; CHECK-SPIRV: 3 FunctionParameter [[PIPE_WR]] {{[0-9]+}}
88+
; CHECK-SPIRV: 3 FunctionParameter [[IMG1D_RD]] {{[0-9]+}}
89+
; CHECK-SPIRV: 3 FunctionParameter [[IMG2D_RD]] {{[0-9]+}}
90+
; CHECK-SPIRV: 3 FunctionParameter [[IMG3D_RD]] {{[0-9]+}}
91+
; CHECK-SPIRV: 3 FunctionParameter [[IMG2DA_RD]] {{[0-9]+}}
92+
; CHECK-SPIRV: 3 FunctionParameter [[IMG1DB_RD]] {{[0-9]+}}
93+
; CHECK-SPIRV: 3 FunctionParameter [[IMG1D_WR]] {{[0-9]+}}
94+
; CHECK-SPIRV: 3 FunctionParameter [[IMG2D_RW]] {{[0-9]+}}
95+
96+
; CHECK-LLVM: define spir_kernel void @foo(
97+
; CHECK-LLVM-SAME: %opencl.pipe_ro_t addrspace(1)* %a,
98+
; CHECK-LLVM-SAME: %opencl.pipe_wo_t addrspace(1)* %b,
99+
; CHECK-LLVM-SAME: %opencl.image1d_ro_t addrspace(1)* %c1,
100+
; CHECK-LLVM-SAME: %opencl.image2d_ro_t addrspace(1)* %d1,
101+
; CHECK-LLVM-SAME: %opencl.image3d_ro_t addrspace(1)* %e1,
102+
; CHECK-LLVM-SAME: %opencl.image2d_array_ro_t addrspace(1)* %f1,
103+
; CHECK-LLVM-SAME: %opencl.image1d_buffer_ro_t addrspace(1)* %g1,
104+
; CHECK-LLVM-SAME: %opencl.image1d_wo_t addrspace(1)* %c2,
105+
; CHECK-LLVM-SAME: %opencl.image2d_rw_t addrspace(1)* %d3)
106+
; CHECK-LLVM-SAME: !kernel_arg_addr_space [[AS:![0-9]+]]
107+
; CHECK-LLVM-SAME: !kernel_arg_access_qual [[AQ:![0-9]+]]
108+
; CHECK-LLVM-SAME: !kernel_arg_type [[TYPE:![0-9]+]]
109+
; CHECK-LLVM-SAME: !kernel_arg_type_qual [[TQ:![0-9]+]]
110+
; CHECK-LLVM-SAME: !kernel_arg_base_type [[TYPE]]
111+
112+
; Function Attrs: nounwind readnone
113+
define spir_kernel void @foo(
114+
target("spirv.Pipe", 0) %a,
115+
target("spirv.Pipe", 1) %b,
116+
target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) %c1,
117+
target("spirv.Image", i32, 1, 0, 0, 0, 0, 0, 0) %d1,
118+
target("spirv.Image", i32, 2, 0, 0, 0, 0, 0, 0) %e1,
119+
target("spirv.Image", half, 1, 0, 1, 0, 0, 0, 0) %f1,
120+
target("spirv.Image", float, 5, 0, 0, 0, 0, 0, 0) %g1,
121+
target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1) %c2,
122+
target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 2) %d3) #0 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 !kernel_arg_base_type !4 !kernel_arg_type_qual !5 {
123+
entry:
124+
ret void
125+
}
126+
127+
; CHECK-SPIRV: {{[0-9]+}} Function
128+
; CHECK-SPIRV: 3 FunctionParameter [[DEVEVENT]] {{[0-9]+}}
129+
; CHECK-SPIRV: 3 FunctionParameter [[EVENT]] {{[0-9]+}}
130+
; CHECK-SPIRV: 3 FunctionParameter [[QUEUE]] {{[0-9]+}}
131+
; CHECK-SPIRV: 3 FunctionParameter [[RESID]] {{[0-9]+}}
132+
133+
; CHECK-LLVM: define spir_func void @bar(
134+
; CHECK-LLVM: %opencl.clk_event_t* %a,
135+
; CHECK-LLVM: %opencl.event_t* %b,
136+
; CHECK-LLVM: %opencl.queue_t* %c,
137+
; CHECK-LLVM: %opencl.reserve_id_t* %d)
138+
139+
define spir_func void @bar(
140+
target("spirv.DeviceEvent") %a,
141+
target("spirv.Event") %b,
142+
target("spirv.Queue") %c,
143+
target("spirv.ReserveId") %d) {
144+
ret void
145+
}
146+
147+
; CHECK-SPIRV: {{[0-9]+}} Function
148+
; CHECK-SPIRV: 3 FunctionParameter [[IMG2DD_RD]] [[IMG_ARG:[0-9]+]]
149+
; CHECK-SPIRV: 3 FunctionParameter [[SAMP]] [[SAMP_ARG:[0-9]+]]
150+
; CHECK-SPIRV: 5 SampledImage [[SAMPIMG]] [[SAMPIMG_VAR:[0-9]+]] [[IMG_ARG]] [[SAMP_ARG]]
151+
; CHECK-SPIRV: 7 ImageSampleExplicitLod {{[0-9]+}} {{[0-9]+}} [[SAMPIMG_VAR]]
152+
153+
; CHECK-LLVM: define spir_func void @test_sampler(
154+
; CHECK-LLVM: %opencl.image2d_depth_ro_t addrspace(1)* %srcimg.coerce,
155+
; CHECK-LLVM: %opencl.sampler_t addrspace(2)* %s.coerce)
156+
; CHECK-LLVM: call spir_func float @_Z11read_imagef20ocl_image2d_depth_ro11ocl_samplerDv4_if(%opencl.image2d_depth_ro_t addrspace(1)* %srcimg.coerce, %opencl.sampler_t addrspace(2)* %s.coerce, <4 x i32> zeroinitializer, float 1.000000e+00)
157+
158+
; CHECK-LLVM-SPIRV: call spir_func %spirv.SampledImage._float_1_1_0_0_0_0_0 addrspace(1)* @_Z20__spirv_SampledImagePU3AS134__spirv_Image__float_1_1_0_0_0_0_0PU3AS215__spirv_Sampler(%spirv.Image._float_1_1_0_0_0_0_0 addrspace(1)* %srcimg.coerce, %spirv.Sampler addrspace(2)* %s.coerce)
159+
; CHECK-LLVM-SPIRV: call spir_func <4 x float> @_Z38__spirv_ImageSampleExplicitLod_Rfloat4PU3AS141__spirv_SampledImage__float_1_1_0_0_0_0_0Dv4_iif(%spirv.SampledImage._float_1_1_0_0_0_0_0 addrspace(1)* %1, <4 x i32> zeroinitializer, i32 2, float 1.000000e+00)
160+
161+
define spir_func void @test_sampler(target("spirv.Image", float, 1, 1, 0, 0, 0, 0, 0) %srcimg.coerce,
162+
target("spirv.Sampler") %s.coerce) {
163+
%1 = tail call spir_func target("spirv.SampledImage", 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) %srcimg.coerce, target("spirv.Sampler") %s.coerce) #1
164+
%2 = tail call spir_func <4 x float> @_Z38__spirv_ImageSampleExplicitLod_Rfloat4PU3AS120__spirv_SampledImageDv4_iif(target("spirv.SampledImage", float, 1, 1, 0, 0, 0, 0, 0) %1, <4 x i32> zeroinitializer, i32 2, float 1.000000e+00) #1
165+
ret void
166+
}
167+
168+
declare spir_func target("spirv.SampledImage", 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"))
169+
170+
declare spir_func <4 x float> @_Z38__spirv_ImageSampleExplicitLod_Rfloat4PU3AS120__spirv_SampledImageDv4_iif(target("spirv.SampledImage", float, 1, 1, 0, 0, 0, 0, 0), <4 x i32>, i32, float)
171+
172+
attributes #0 = { nounwind readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
173+
174+
!opencl.enable.FP_CONTRACT = !{}
175+
!opencl.spir.version = !{!6}
176+
!opencl.ocl.version = !{!7}
177+
!opencl.used.extensions = !{!8}
178+
!opencl.used.optional.core.features = !{!9}
179+
!opencl.compiler.options = !{!8}
180+
181+
; CHECK-LLVM-DAG: [[AS]] = !{i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1}
182+
; CHECK-LLVM-DAG: [[AQ]] = !{!"read_only", !"write_only", !"read_only", !"read_only", !"read_only", !"read_only", !"read_only", !"write_only", !"read_write"}
183+
; CHECK-LLVM-DAG: [[TYPE]] = !{!"pipe", !"pipe", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
184+
; CHECK-LLVM-DAG: [[TQ]] = !{!"pipe", !"pipe", !"", !"", !"", !"", !"", !"", !""}
185+
186+
!1 = !{i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1}
187+
!2 = !{!"read_only", !"write_only", !"read_only", !"read_only", !"read_only", !"read_only", !"read_only", !"write_only", !"read_write"}
188+
!3 = !{!"int", !"int", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
189+
!4 = !{!"int", !"int", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
190+
!5 = !{!"pipe", !"pipe", !"", !"", !"", !"", !"", !"", !""}
191+
!6 = !{i32 1, i32 2}
192+
!7 = !{i32 2, i32 0}
193+
!8 = !{!"cl_khr_fp16"}
194+
!9 = !{!"cl_images"}

0 commit comments

Comments
 (0)