Skip to content

Commit 5609575

Browse files
jcranmer-intelFreddyLeaf
authored andcommitted
Add support for translating target extension types. (intel#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. Original commit: KhronosGroup/SPIRV-LLVM-Translator@951a6ad
1 parent 91c5663 commit 5609575

File tree

5 files changed

+303
-3
lines changed

5 files changed

+303
-3
lines changed

llvm-spirv/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();

llvm-spirv/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

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

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

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

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,47 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
478478
return mapType(T, getSPIRVFunctionType(RT, PT));
479479
}
480480

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

1159+
if (isa<ConstantTargetNone>(V))
1160+
return BM->addNullConstant(transType(V->getType()));
1161+
11181162
if (auto CAZero = dyn_cast<ConstantAggregateZero>(V)) {
11191163
Type *AggType = CAZero->getType();
11201164
if (const StructType *ST = dyn_cast<StructType>(AggType))
@@ -2855,7 +2899,7 @@ SPIRVValue *LLVMToSPIRVBase::oclTransSpvcCastSampler(CallInst *CI,
28552899
auto FT = F->getFunctionType();
28562900
auto RT = FT->getReturnType();
28572901
assert(FT->getNumParams() == 1);
2858-
if (!RT->isOpaquePointerTy()) {
2902+
if (RT->isPointerTy() && !RT->isOpaquePointerTy()) {
28592903
StructType *ST = dyn_cast<StructType>(RT->getNonOpaquePointerElementType());
28602904
(void)ST;
28612905
assert(isSPIRVStructType(ST, kSPIRVTypeName::Sampler) ||
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)