Skip to content

Commit

Permalink
[OpaquePointers] Add support for translating target extension types. (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
jcranmer-intel authored Mar 13, 2023
1 parent 6a0368f commit 951a6ad
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 3 deletions.
42 changes: 42 additions & 0 deletions lib/SPIRV/SPIRVBuiltinHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,18 @@ Type *BuiltinCallHelper::adjustImageType(Type *T, StringRef OldImageKind,
}
return TypedPointerType::get(StructTy, TypedPtrTy->getAddressSpace());
}

if (auto *TargetTy = dyn_cast<TargetExtType>(T)) {
StringRef Name = TargetTy->getName();
if (!Name.consume_front(kSPIRVTypeName::PrefixAndDelim) ||
Name != OldImageKind)
report_fatal_error("Type did not have expected image kind");
return TargetExtType::get(
TargetTy->getContext(),
(Twine(kSPIRVTypeName::PrefixAndDelim) + NewImageKind).str(),
TargetTy->type_params(), TargetTy->int_params());
}

report_fatal_error("Expected type to be a SPIRV image type");
}

Expand Down Expand Up @@ -307,6 +319,19 @@ Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
StringRef InnerTypeName,
ArrayRef<unsigned> Parameters,
bool UseRealType) {
if (UseTargetTypes) {
std::string BaseName = (Twine(kSPIRVTypeName::PrefixAndDelim) +
SPIRVOpaqueTypeOpCodeMap::rmap(TypeOpcode))
.str();
SmallVector<Type *, 1> TypeParams;
if (!InnerTypeName.empty()) {
TypeParams.push_back(getLLVMTypeForSPIRVImageSampledTypePostfix(
InnerTypeName, M->getContext()));
}
return TargetExtType::get(M->getContext(), BaseName, TypeParams,
Parameters);
}

std::string FullName;
{
raw_string_ostream OS(FullName);
Expand All @@ -328,6 +353,23 @@ Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
: TypedPointerType::get(STy, AddrSpace);
}

void BuiltinCallHelper::initialize(llvm::Module &M) {
this->M = &M;
// We want to use pointers-to-opaque-structs for the special types if:
// * We are translating from SPIR-V to LLVM IR (which means we are using
// OpenCL mangling rules)
// * There are %opencl.* or %spirv.* struct type names already present.
UseTargetTypes = Rules != ManglingRules::OpenCL;
for (StructType *Ty : M.getIdentifiedStructTypes()) {
if (!Ty->isOpaque() || !Ty->hasName())
continue;
StringRef Name = Ty->getName();
if (Name.startswith("opencl.") || Name.startswith("spirv.")) {
UseTargetTypes = false;
}
}
}

BuiltinCallMutator::ValueTypePair
BuiltinCallHelper::getCallValue(CallInst *CI, unsigned ArgNo) {
Function *CalledFunc = CI->getCalledFunction();
Expand Down
3 changes: 2 additions & 1 deletion lib/SPIRV/SPIRVBuiltinHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ class BuiltinCallHelper {

protected:
llvm::Module *M = nullptr;
bool UseTargetTypes = false;

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

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

/// Return a mutator that will replace the given call instruction with a call
/// to the given function name. The function name will have its name mangled
Expand Down
21 changes: 20 additions & 1 deletion lib/SPIRV/SPIRVUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ bool getParameterTypes(Function *F, SmallVectorImpl<Type *> &ArgTys,
LLVM_DEBUG(dbgs() << "Failed to recover type of argument " << *ArgTy
<< " of function " << F->getName() << "\n");
DemangledSuccessfully = false;
} else if (!DemangledTy)
} else if (ArgTy->isTargetExtTy() || !DemangledTy)
DemangledTy = ArgTy;
*ArgIter++ = DemangledTy;
}
Expand Down Expand Up @@ -1336,6 +1336,25 @@ static SPIR::RefParamType transTypeDesc(Type *Ty,
}
return SPIR::RefParamType(new SPIR::UserDefinedType(Name.str()));
}
if (auto *TargetTy = dyn_cast<TargetExtType>(Ty)) {
std::string FullName;
{
raw_string_ostream OS(FullName);
StringRef Name = TargetTy->getName();
if (Name.consume_front(kSPIRVTypeName::PrefixAndDelim)) {
OS << "__spirv_" << Name;
} else {
OS << Name;
}
if (!TargetTy->int_params().empty())
OS << "_";
for (Type *InnerTy : TargetTy->type_params())
OS << "_" << convertTypeToPostfix(InnerTy);
for (unsigned Param : TargetTy->int_params())
OS << "_" << Param;
}
return SPIR::RefParamType(new SPIR::UserDefinedType(FullName));
}

if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
auto *ET = TPT->getElementType();
Expand Down
46 changes: 45 additions & 1 deletion lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,47 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
return mapType(T, getSPIRVFunctionType(RT, PT));
}

if (auto *TargetTy = dyn_cast<TargetExtType>(T)) {
StringRef Name = TargetTy->getName();
if (Name.consume_front(kSPIRVTypeName::PrefixAndDelim)) {
auto Opcode = SPIRVOpaqueTypeOpCodeMap::map(Name.str());
auto CastAccess = [](unsigned Val) {
return static_cast<SPIRVAccessQualifierKind>(Val);
};
switch (Opcode) {
case OpTypePipe: {
auto *PipeT = BM->addPipeType();
PipeT->setPipeAcessQualifier(CastAccess(TargetTy->getIntParameter(0)));
return mapType(T, PipeT);
}
case OpTypeImage: {
auto *SampledTy = transType(TargetTy->getTypeParameter(0));
ArrayRef<unsigned> Ops = TargetTy->int_params();
SPIRVTypeImageDescriptor Desc(static_cast<SPIRVImageDimKind>(Ops[0]),
Ops[1], Ops[2], Ops[3], Ops[4], Ops[5]);
return mapType(T,
BM->addImageType(SampledTy, Desc, CastAccess(Ops[6])));
}
case OpTypeSampledImage: {
auto *ImageTy = static_cast<SPIRVTypeImage *>(transType(adjustImageType(
T, kSPIRVTypeName::SampledImg, kSPIRVTypeName::Image)));
return mapType(T, BM->addSampledImageType(ImageTy));
}
case OpTypeVmeImageINTEL: {
auto *ImageTy = static_cast<SPIRVTypeImage *>(transType(adjustImageType(
T, kSPIRVTypeName::VmeImageINTEL, kSPIRVTypeName::Image)));
return mapType(T, BM->addVmeImageINTELType(ImageTy));
}
case OpTypeQueue:
return mapType(T, BM->addQueueType());
case OpTypeDeviceEvent:
return mapType(T, BM->addDeviceEventType());
default:
return mapType(T, BM->addOpaqueGenericType(Opcode));
}
}
}

llvm_unreachable("Not implemented!");
return 0;
}
Expand Down Expand Up @@ -1097,6 +1138,9 @@ SPIRVValue *LLVMToSPIRVBase::transConstant(Value *V) {
return BM->addNullConstant(
bcast<SPIRVTypePointer>(transType(CPNull->getType())));

if (isa<ConstantTargetNone>(V))
return BM->addNullConstant(transType(V->getType()));

if (auto CAZero = dyn_cast<ConstantAggregateZero>(V)) {
Type *AggType = CAZero->getType();
if (const StructType *ST = dyn_cast<StructType>(AggType))
Expand Down Expand Up @@ -2788,7 +2832,7 @@ SPIRVValue *LLVMToSPIRVBase::oclTransSpvcCastSampler(CallInst *CI,
auto FT = F->getFunctionType();
auto RT = FT->getReturnType();
assert(FT->getNumParams() == 1);
if (!RT->isOpaquePointerTy()) {
if (RT->isPointerTy() && !RT->isOpaquePointerTy()) {
StructType *ST = dyn_cast<StructType>(RT->getNonOpaquePointerElementType());
(void)ST;
assert(isSPIRVStructType(ST, kSPIRVTypeName::Sampler) ||
Expand Down
194 changes: 194 additions & 0 deletions test/transcoding/spirv-target-types.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
;; Test SPIR-V opaque types
;;
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -spirv-text -o %t.spv.txt
; RUN: FileCheck < %t.spv.txt %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.bc -o %t.from-llvm.spv
; RUN: llvm-spirv -to-binary %t.spv.txt -o %t.from-text.spv
; RUN: llvm-spirv %t.bc -o %t.spv
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
; RUN: llvm-spirv --spirv-target-env=SPV-IR -r %t.spv -o %t.rev.bc
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM-SPIRV

; Check that produced SPIR-V friendly IR is correctly recognized
; RUN: llvm-spirv %t.rev.bc -opaque-pointers=0 -spirv-text -o %t.spv.txt
; RUN: FileCheck < %t.spv.txt %s --check-prefix=CHECK-SPIRV

; CHECK-SPIRV: 2 Capability Float16
; CHECK-SPIRV: 2 Capability ImageBasic
; CHECK-SPIRV: 2 Capability ImageReadWrite
; CHECK-SPIRV: 2 Capability Pipes
; CHECK-SPIRV: 2 Capability DeviceEnqueue

; CHECK-SPIRV-DAG: 2 TypeVoid [[VOID:[0-9]+]]
; CHECK-SPIRV-DAG: 4 TypeInt [[INT:[0-9]+]] 32 0
; CHECK-SPIRV-DAG: 3 TypeFloat [[HALF:[0-9]+]] 16
; CHECK-SPIRV-DAG: 3 TypeFloat [[FLOAT:[0-9]+]] 32
; CHECK-SPIRV-DAG: 3 TypePipe [[PIPE_RD:[0-9]+]] 0
; CHECK-SPIRV-DAG: 3 TypePipe [[PIPE_WR:[0-9]+]] 1
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1D_RD:[0-9]+]] [[VOID]] 0 0 0 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2D_RD:[0-9]+]] [[INT]] 1 0 0 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG3D_RD:[0-9]+]] [[INT]] 2 0 0 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2DD_RD:[0-9]+]] [[FLOAT]] 1 1 0 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2DA_RD:[0-9]+]] [[HALF]] 1 0 1 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1DB_RD:[0-9]+]] [[FLOAT]] 5 0 0 0 0 0 0
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG1D_WR:[0-9]+]] [[VOID]] 0 0 0 0 0 0 1
; CHECK-SPIRV-DAG: 10 TypeImage [[IMG2D_RW:[0-9]+]] [[VOID]] 1 0 0 0 0 0 2
; CHECK-SPIRV-DAG: 2 TypeDeviceEvent [[DEVEVENT:[0-9]+]]
; CHECK-SPIRV-DAG: 2 TypeEvent [[EVENT:[0-9]+]]
; CHECK-SPIRV-DAG: 2 TypeQueue [[QUEUE:[0-9]+]]
; CHECK-SPIRV-DAG: 2 TypeReserveId [[RESID:[0-9]+]]
; CHECK-SPIRV-DAG: 2 TypeSampler [[SAMP:[0-9]+]]
; CHECK-SPIRV-DAG: 3 TypeSampledImage [[SAMPIMG:[0-9]+]] [[IMG2DD_RD]]

; ModuleID = 'cl-types.cl'
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"
target triple = "spir-unknown-unknown"

; CHECK-LLVM-DAG: %opencl.pipe_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.pipe_wo_t = type opaque
; CHECK-LLVM-DAG: %opencl.image3d_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image2d_depth_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image2d_array_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image1d_buffer_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image1d_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image1d_wo_t = type opaque
; CHECK-LLVM-DAG: %opencl.image2d_ro_t = type opaque
; CHECK-LLVM-DAG: %opencl.image2d_rw_t = type opaque
; CHECK-LLVM-DAG: %opencl.clk_event_t = type opaque
; CHECK-LLVM-DAG: %opencl.event_t = type opaque
; CHECK-LLVM-DAG: %opencl.queue_t = type opaque
; CHECK-LLVM-DAG: %opencl.reserve_id_t = type opaque

; CHECK-LLVM-SPIRV-DAG: %spirv.Pipe._0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Pipe._1 = type opaque

; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_0_0_0_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._uint_1_0_0_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._uint_2_0_0_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._float_1_1_0_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._half_1_0_1_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._float_5_0_0_0_0_0_0 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_0_0_0_0_0_0_1 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Image._void_1_0_0_0_0_0_2 = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.DeviceEvent = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Event = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Queue = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.ReserveId = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.Sampler = type opaque
; CHECK-LLVM-SPIRV-DAG: %spirv.SampledImage._float_1_1_0_0_0_0_0 = type opaque

; CHECK-SPIRV: {{[0-9]+}} Function
; CHECK-SPIRV: 3 FunctionParameter [[PIPE_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[PIPE_WR]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG1D_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG2D_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG3D_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG2DA_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG1DB_RD]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG1D_WR]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[IMG2D_RW]] {{[0-9]+}}

; CHECK-LLVM: define spir_kernel void @foo(
; CHECK-LLVM-SAME: %opencl.pipe_ro_t addrspace(1)* %a,
; CHECK-LLVM-SAME: %opencl.pipe_wo_t addrspace(1)* %b,
; CHECK-LLVM-SAME: %opencl.image1d_ro_t addrspace(1)* %c1,
; CHECK-LLVM-SAME: %opencl.image2d_ro_t addrspace(1)* %d1,
; CHECK-LLVM-SAME: %opencl.image3d_ro_t addrspace(1)* %e1,
; CHECK-LLVM-SAME: %opencl.image2d_array_ro_t addrspace(1)* %f1,
; CHECK-LLVM-SAME: %opencl.image1d_buffer_ro_t addrspace(1)* %g1,
; CHECK-LLVM-SAME: %opencl.image1d_wo_t addrspace(1)* %c2,
; CHECK-LLVM-SAME: %opencl.image2d_rw_t addrspace(1)* %d3)
; CHECK-LLVM-SAME: !kernel_arg_addr_space [[AS:![0-9]+]]
; CHECK-LLVM-SAME: !kernel_arg_access_qual [[AQ:![0-9]+]]
; CHECK-LLVM-SAME: !kernel_arg_type [[TYPE:![0-9]+]]
; CHECK-LLVM-SAME: !kernel_arg_type_qual [[TQ:![0-9]+]]
; CHECK-LLVM-SAME: !kernel_arg_base_type [[TYPE]]

; Function Attrs: nounwind readnone
define spir_kernel void @foo(
target("spirv.Pipe", 0) %a,
target("spirv.Pipe", 1) %b,
target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) %c1,
target("spirv.Image", i32, 1, 0, 0, 0, 0, 0, 0) %d1,
target("spirv.Image", i32, 2, 0, 0, 0, 0, 0, 0) %e1,
target("spirv.Image", half, 1, 0, 1, 0, 0, 0, 0) %f1,
target("spirv.Image", float, 5, 0, 0, 0, 0, 0, 0) %g1,
target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1) %c2,
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 {
entry:
ret void
}

; CHECK-SPIRV: {{[0-9]+}} Function
; CHECK-SPIRV: 3 FunctionParameter [[DEVEVENT]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[EVENT]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[QUEUE]] {{[0-9]+}}
; CHECK-SPIRV: 3 FunctionParameter [[RESID]] {{[0-9]+}}

; CHECK-LLVM: define spir_func void @bar(
; CHECK-LLVM: %opencl.clk_event_t* %a,
; CHECK-LLVM: %opencl.event_t* %b,
; CHECK-LLVM: %opencl.queue_t* %c,
; CHECK-LLVM: %opencl.reserve_id_t* %d)

define spir_func void @bar(
target("spirv.DeviceEvent") %a,
target("spirv.Event") %b,
target("spirv.Queue") %c,
target("spirv.ReserveId") %d) {
ret void
}

; CHECK-SPIRV: {{[0-9]+}} Function
; CHECK-SPIRV: 3 FunctionParameter [[IMG2DD_RD]] [[IMG_ARG:[0-9]+]]
; CHECK-SPIRV: 3 FunctionParameter [[SAMP]] [[SAMP_ARG:[0-9]+]]
; CHECK-SPIRV: 5 SampledImage [[SAMPIMG]] [[SAMPIMG_VAR:[0-9]+]] [[IMG_ARG]] [[SAMP_ARG]]
; CHECK-SPIRV: 7 ImageSampleExplicitLod {{[0-9]+}} {{[0-9]+}} [[SAMPIMG_VAR]]

; CHECK-LLVM: define spir_func void @test_sampler(
; CHECK-LLVM: %opencl.image2d_depth_ro_t addrspace(1)* %srcimg.coerce,
; CHECK-LLVM: %opencl.sampler_t addrspace(2)* %s.coerce)
; 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)

; 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)
; 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)

define spir_func void @test_sampler(target("spirv.Image", float, 1, 1, 0, 0, 0, 0, 0) %srcimg.coerce,
target("spirv.Sampler") %s.coerce) {
%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
%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
ret void
}

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"))

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)

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" }

!opencl.enable.FP_CONTRACT = !{}
!opencl.spir.version = !{!6}
!opencl.ocl.version = !{!7}
!opencl.used.extensions = !{!8}
!opencl.used.optional.core.features = !{!9}
!opencl.compiler.options = !{!8}

; CHECK-LLVM-DAG: [[AS]] = !{i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1}
; CHECK-LLVM-DAG: [[AQ]] = !{!"read_only", !"write_only", !"read_only", !"read_only", !"read_only", !"read_only", !"read_only", !"write_only", !"read_write"}
; CHECK-LLVM-DAG: [[TYPE]] = !{!"pipe", !"pipe", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
; CHECK-LLVM-DAG: [[TQ]] = !{!"pipe", !"pipe", !"", !"", !"", !"", !"", !"", !""}

!1 = !{i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1}
!2 = !{!"read_only", !"write_only", !"read_only", !"read_only", !"read_only", !"read_only", !"read_only", !"write_only", !"read_write"}
!3 = !{!"int", !"int", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
!4 = !{!"int", !"int", !"image1d_t", !"image2d_t", !"image3d_t", !"image2d_array_t", !"image1d_buffer_t", !"image1d_t", !"image2d_t"}
!5 = !{!"pipe", !"pipe", !"", !"", !"", !"", !"", !"", !""}
!6 = !{i32 1, i32 2}
!7 = !{i32 2, i32 0}
!8 = !{!"cl_khr_fp16"}
!9 = !{!"cl_images"}

0 comments on commit 951a6ad

Please sign in to comment.