From 73dfc6d450ad0438558bee20505c426319f7624b Mon Sep 17 00:00:00 2001 From: nrudenko Date: Tue, 1 Sep 2020 16:26:24 +0300 Subject: [PATCH] Implement OpTypeBufferSurfaceINTEL according to the spec published at: https://github.com/intel/llvm/pull/1612 --- lib/SPIRV/SPIRVReader.cpp | 17 +++++ lib/SPIRV/SPIRVReader.h | 1 + lib/SPIRV/SPIRVWriter.cpp | 7 ++ lib/SPIRV/VectorComputeUtil.cpp | 9 +++ lib/SPIRV/VectorComputeUtil.h | 7 ++ lib/SPIRV/libSPIRV/SPIRVModule.cpp | 7 ++ lib/SPIRV/libSPIRV/SPIRVModule.h | 3 + lib/SPIRV/libSPIRV/SPIRVOpCode.h | 5 +- lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 1 + lib/SPIRV/libSPIRV/SPIRVType.h | 45 +++++++++++++ lib/SPIRV/libSPIRV/spirv.hpp | 5 ++ test/transcoding/buffer_surface_intel.ll | 82 ++++++++++++++++++++++++ 12 files changed, 188 insertions(+), 1 deletion(-) create mode 100755 test/transcoding/buffer_surface_intel.ll diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 55061c549f..f02a746b0d 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -429,6 +429,12 @@ SPIRVToLLVM::transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage *PST) { kSPIRVTypeName::PipeStorage; } +std::string SPIRVToLLVM::transVCTypeName(SPIRVTypeBufferSurfaceINTEL *PST) { + if (PST->hasAccessQualifier()) + return VectorComputeUtil::getVCBufferSurfaceName(PST->getAccessQualifier()); + return VectorComputeUtil::getVCBufferSurfaceName(); +} + Type *SPIRVToLLVM::transType(SPIRVType *T, bool IsClassMember) { auto Loc = TypeMap.find(T); if (Loc != TypeMap.end()) @@ -517,6 +523,14 @@ Type *SPIRVToLLVM::transType(SPIRVType *T, bool IsClassMember) { // OpenCL Compiler does not use this instruction case OpTypeVmeImageINTEL: return nullptr; + + case OpTypeBufferSurfaceINTEL: { + auto PST = static_cast(T); + return mapType(T, + getOrCreateOpaquePtrType(M, transVCTypeName(PST), + SPIRAddressSpace::SPIRAS_Global)); + } + default: { auto OC = T->getOpCode(); if (isOpaqueGenericTypeOpCode(OC) || isSubgroupAvcINTELTypeOpCode(OC)) { @@ -3630,6 +3644,9 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) { if (F->getCallingConv() != CallingConv::SPIR_KERNEL) return true; + if (BF->hasDecorate(DecorationVectorComputeFunctionINTEL)) + return true; + // Generate metadata for kernel_arg_addr_space addOCLKernelArgumentMetadata( Context, SPIR_MD_KERNEL_ARG_ADDR_SPACE, BF, F, diff --git a/lib/SPIRV/SPIRVReader.h b/lib/SPIRV/SPIRVReader.h index a03b315fe7..79e8529229 100644 --- a/lib/SPIRV/SPIRVReader.h +++ b/lib/SPIRV/SPIRVReader.h @@ -248,6 +248,7 @@ class SPIRVToLLVM { std::string transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage *PST); std::string transOCLImageTypeAccessQualifier(SPIRV::SPIRVTypeImage *ST); std::string transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe *ST); + std::string transVCTypeName(SPIRVTypeBufferSurfaceINTEL *PST); Value *oclTransConstantSampler(SPIRV::SPIRVConstantSampler *BCS, BasicBlock *BB); diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index dbb43526d8..18c091142f 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -350,6 +350,13 @@ SPIRVType *LLVMToSPIRV::transType(Type *T) { return mapType(T, BM->addQueueType()); } } + if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) { + if (STName.startswith(kVCType::VCBufferSurface)) { + // VCBufferSurface always have Access Qualifier + auto Access = getAccessQualifier(STName); + return mapType(T, BM->addBufferSurfaceINTELType(Access)); + } + } if (isPointerToOpaqueStructType(T)) { return mapType( diff --git a/lib/SPIRV/VectorComputeUtil.cpp b/lib/SPIRV/VectorComputeUtil.cpp index b090b20805..b3ef728440 100755 --- a/lib/SPIRV/VectorComputeUtil.cpp +++ b/lib/SPIRV/VectorComputeUtil.cpp @@ -149,4 +149,13 @@ getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept { } } +std::string getVCBufferSurfaceName() { + return std::string(kVCType::VCBufferSurface) + kAccessQualPostfix::Type; +} + +std::string getVCBufferSurfaceName(SPIRVAccessQualifierKind Access) { + return std::string(kVCType::VCBufferSurface) + + getAccessQualifierPostfix(Access).str() + kAccessQualPostfix::Type; +} + } // namespace VectorComputeUtil diff --git a/lib/SPIRV/VectorComputeUtil.h b/lib/SPIRV/VectorComputeUtil.h index f550dca7b0..978d5ab096 100755 --- a/lib/SPIRV/VectorComputeUtil.h +++ b/lib/SPIRV/VectorComputeUtil.h @@ -87,6 +87,9 @@ getVCGlobalVarStorageClass(SPIRAddressSpace AddressSpace) noexcept; SPIRAddressSpace getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept; +std::string getVCBufferSurfaceName(); +std::string getVCBufferSurfaceName(SPIRVAccessQualifierKind Access); + } // namespace VectorComputeUtil /////////////////////////////////////////////////////////////////////////////// @@ -107,6 +110,10 @@ const static char VCByteOffset[] = "VCByteOffset"; const static char VCSIMTCall[] = "VCSIMTCall"; } // namespace kVCMetadata +namespace kVCType { +const static char VCBufferSurface[] = "intel.buffer"; +} + /////////////////////////////////////////////////////////////////////////////// // // Map definitions diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.cpp b/lib/SPIRV/libSPIRV/SPIRVModule.cpp index d88cf21ffb..70b4dc4673 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.cpp +++ b/lib/SPIRV/libSPIRV/SPIRVModule.cpp @@ -248,6 +248,8 @@ class SPIRVModuleImpl : public SPIRVModule { void createForwardPointers() override; SPIRVType *addSubgroupAvcINTELType(Op) override; SPIRVTypeVmeImageINTEL *addVmeImageINTELType(SPIRVTypeImage *T) override; + SPIRVTypeBufferSurfaceINTEL * + addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) override; // Constant creation functions SPIRVInstruction *addBranchInst(SPIRVLabel *, SPIRVBasicBlock *) override; @@ -963,6 +965,11 @@ SPIRVModuleImpl::addVmeImageINTELType(SPIRVTypeImage *T) { return addType(new SPIRVTypeVmeImageINTEL(this, getId(), T)); } +SPIRVTypeBufferSurfaceINTEL * +SPIRVModuleImpl::addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) { + return addType(new SPIRVTypeBufferSurfaceINTEL(this, getId(), Access)); +} + SPIRVType *SPIRVModuleImpl::addSubgroupAvcINTELType(Op TheOpCode) { return addType(new SPIRVTypeSubgroupAvcINTEL(TheOpCode, this, getId())); } diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.h b/lib/SPIRV/libSPIRV/SPIRVModule.h index d3d45cf580..b0e0f2ba88 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.h +++ b/lib/SPIRV/libSPIRV/SPIRVModule.h @@ -89,6 +89,7 @@ class SPIRVInstTemplateBase; class SPIRVAsmTargetINTEL; class SPIRVAsmINTEL; class SPIRVAsmCallINTEL; +class SPIRVTypeBufferSurfaceINTEL; typedef SPIRVBasicBlock SPIRVLabel; struct SPIRVTypeImageDescriptor; @@ -243,6 +244,8 @@ class SPIRVModule { virtual SPIRVTypePipe *addPipeType() = 0; virtual SPIRVType *addSubgroupAvcINTELType(Op) = 0; virtual SPIRVTypeVmeImageINTEL *addVmeImageINTELType(SPIRVTypeImage *) = 0; + virtual SPIRVTypeBufferSurfaceINTEL * + addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) = 0; virtual void createForwardPointers() = 0; // Constants creation functions diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCode.h b/lib/SPIRV/libSPIRV/SPIRVOpCode.h index d20e037c4a..8aac5eef86 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCode.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCode.h @@ -196,10 +196,13 @@ inline bool isSubgroupAvcINTELEvaluateOpcode(Op OpCode) { OC <= OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL); } +inline bool isVCOpCode(Op OpCode) { return OpCode == OpTypeBufferSurfaceINTEL; } + inline bool isTypeOpCode(Op OpCode) { unsigned OC = OpCode; return (OpTypeVoid <= OC && OC <= OpTypePipe) || OC == OpTypePipeStorage || - isSubgroupAvcINTELTypeOpCode(OpCode) || OC == OpTypeVmeImageINTEL; + isSubgroupAvcINTELTypeOpCode(OpCode) || OC == OpTypeVmeImageINTEL || + isVCOpCode(OpCode); } inline bool isSpecConstantOpCode(Op OpCode) { diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index d183b8434c..ee0b0de6d0 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -515,3 +515,4 @@ _SPIRV_OP(CrossWorkgroupCastToPtrINTEL, 5938) _SPIRV_OP(ReadPipeBlockingINTEL, 5946) _SPIRV_OP(WritePipeBlockingINTEL, 5947) _SPIRV_OP(FPGARegINTEL, 5949) +_SPIRV_OP(TypeBufferSurfaceINTEL, 6086) diff --git a/lib/SPIRV/libSPIRV/SPIRVType.h b/lib/SPIRV/libSPIRV/SPIRVType.h index 80b890c983..0b8a351d12 100644 --- a/lib/SPIRV/libSPIRV/SPIRVType.h +++ b/lib/SPIRV/libSPIRV/SPIRVType.h @@ -824,6 +824,51 @@ bool isType(const T1 *Ty, unsigned Bits = 0) { return static_cast(Ty)->getBitWidth() == Bits; } +class SPIRVTypeBufferSurfaceINTEL : public SPIRVType { +public: + const static Op OC = OpTypeBufferSurfaceINTEL; + const static SPIRVWord FixedWC = 2; + SPIRVTypeBufferSurfaceINTEL(SPIRVModule *M, SPIRVId TheId, + SPIRVAccessQualifierKind TheAccess) + : SPIRVType(M, FixedWC + 1, OC, TheId), AccessKind(TheAccess) { + validate(); + } + SPIRVTypeBufferSurfaceINTEL(SPIRVModule *M, SPIRVId TheId) + : SPIRVType(M, FixedWC, OC, TheId) { + validate(); + } + SPIRVTypeBufferSurfaceINTEL() : SPIRVType(OC) {} + + SPIRVCapVec getRequiredCapability() const override { + return getVec(CapabilityVectorComputeINTEL); + } + + SPIRVExtSet getRequiredExtensions() const override { + return getSet(ExtensionID::SPV_INTEL_vector_compute); + } + + bool hasAccessQualifier() const { return AccessKind.hasValue(); } + SPIRVAccessQualifierKind getAccessQualifier() const { + assert(hasAccessQualifier()); + return AccessKind.getValue(); + } + +protected: + _SPIRV_DEF_ENCDEC2(Id, AccessKind) + void validate() const override { + assert(OpCode == OC); + assert(WordCount == FixedWC + (AccessKind ? 1 : 0)); + } + void setWordCount(SPIRVWord TheWC) override { + if (TheWC > FixedWC) + AccessKind = SPIRVAccessQualifierKind::AccessQualifierMax; + WordCount = TheWC; + } + +private: + llvm::Optional AccessKind; +}; + // SPV_INTEL_device_side_avc_motion_estimation extension types class SPIRVTypeVmeImageINTEL : public SPIRVType { public: diff --git a/lib/SPIRV/libSPIRV/spirv.hpp b/lib/SPIRV/libSPIRV/spirv.hpp index 2cf9504780..01fae5578c 100644 --- a/lib/SPIRV/libSPIRV/spirv.hpp +++ b/lib/SPIRV/libSPIRV/spirv.hpp @@ -1565,6 +1565,7 @@ enum Op { OpReadPipeBlockingINTEL = 5946, OpWritePipeBlockingINTEL = 5947, OpFPGARegINTEL = 5949, + OpTypeBufferSurfaceINTEL = 6086, OpMax = 0x7fffffff, }; @@ -2096,6 +2097,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: + *hasResult = true; + *hasResultType = false; + break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ diff --git a/test/transcoding/buffer_surface_intel.ll b/test/transcoding/buffer_surface_intel.ll new file mode 100755 index 0000000000..e0bb85e85e --- /dev/null +++ b/test/transcoding/buffer_surface_intel.ll @@ -0,0 +1,82 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-allow-unknown-intrinsics +; RUN: llvm-spirv %t.spv -o %t.spt --to-text +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-dis %t.bc -o %t.ll +; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV +; RUN: FileCheck %s --input-file %t.ll -check-prefix=LLVM + +target triple = "spir" + +; LLVM-DAG: %intel.buffer_ro_t = type opaque +; LLVM-DAG: %intel.buffer_wo_t = type opaque +; LLVM-DAG: %intel.buffer_rw_t = type opaque +; LLVM-DAG: %opencl.image1d_rw_t = type opaque +; LLVM-DAG: %opencl.image1d_buffer_wo_t = type opaque +; LLVM-DAG: %opencl.image2d_wo_t = type opaque +; LLVM-DAG: %opencl.image3d_ro_t = type opaque +%intel.buffer_ro_t = type opaque +%intel.buffer_wo_t = type opaque +%intel.buffer_rw_t = type opaque +%opencl.image1d_rw_t = type opaque +%opencl.image1d_buffer_wo_t = type opaque +%opencl.image2d_wo_t = type opaque +%opencl.image3d_ro_t = type opaque + +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)*) +; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)*) + +declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)*) +declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)*) + +; SPV-DAG: TypeInt [[INT:[0-9]+]] 32 0 +; SPV-DAG: TypeVoid [[VOID:[0-9]+]] +; SPV-DAG: TypeBufferSurfaceINTEL [[BUFRO:[0-9]+]] 0{{(^|[^0-9])}} +; SPV-DAG: TypeBufferSurfaceINTEL [[BUFWO:[0-9]+]] 1{{(^|[^0-9])}} +; SPV-DAG: TypeBufferSurfaceINTEL [[BUFRW:[0-9]+]] 2{{(^|[^0-9])}} +; SPV-DAG: TypeImage [[IMAGE1D_RW:[0-9]+]] {{[0-9]+}} 0 0 0 0 0 0 2 +; SPV-DAG: TypeImage [[IMAGE1D_BUF_WO:[0-9]+]] {{[0-9]+}} 5 0 0 0 0 0 1 +; SPV-DAG: TypeImage [[IMAGE2D_WO:[0-9]+]] {{[0-9]+}} 1 0 0 0 0 0 1 +; SPV-DAG: TypeImage [[IMAGE3D_RO:[0-9]+]] {{[0-9]+}} 2 0 0 0 0 0 0 +; SPV-DAG: TypeFunction [[BUFINTR_RO:[0-9]+]] [[INT]] [[BUFRO]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction [[BUFINTR_WO:[0-9]+]] [[INT]] [[BUFWO]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction [[BUFINTR_RW:[0-9]+]] [[INT]] [[BUFRW]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE1D_RW]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE1D_BUF_WO]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE2D_WO]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE3D_RO]]{{(^|[^0-9])}} +; SPV-DAG: TypeFunction {{[0-9]+}} [[VOID]] [[BUFRO]] [[BUFWO]] [[BUFRW]] [[IMAGE1D_RW]] [[IMAGE1D_BUF_WO]] [[IMAGE2D_WO]] [[IMAGE3D_RO]]{{(^|[^0-9])}} + +; LLVM-DAG: define spir_kernel void @test(%intel.buffer_ro_t addrspace(1)* %buf_ro, %intel.buffer_wo_t addrspace(1)* %buf_wo, %intel.buffer_rw_t addrspace(1)* %buf_rw, %opencl.image1d_rw_t addrspace(1)* %im1d, %opencl.image1d_buffer_wo_t addrspace(1)* %im1db, %opencl.image2d_wo_t addrspace(1)* %im2d, %opencl.image3d_ro_t addrspace(1)* %im3d) +define spir_kernel void @test(%intel.buffer_ro_t addrspace(1)* %buf_ro, %intel.buffer_wo_t addrspace(1)* %buf_wo, %intel.buffer_rw_t addrspace(1)* %buf_rw, %opencl.image1d_rw_t addrspace(1)* %im1d, %opencl.image1d_buffer_wo_t addrspace(1)* %im1db, %opencl.image2d_wo_t addrspace(1)* %im2d, %opencl.image3d_ro_t addrspace(1)* %im3d) #0 { +entry: +; LLVM: %0 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)* %buf_ro) +; LLVM: %1 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)* %buf_wo) +; LLVM: %2 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)* %buf_rw) +; LLVM: %3 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)* %im1d) +; LLVM: %4 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)* %im1db) +; LLVM: %5 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)* %im2d) +; LLVM: %6 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)* %im3d) +; LLVM: ret void + %0 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)* %buf_ro) + %1 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)* %buf_wo) + %2 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)* %buf_rw) + %3 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)* %im1d) + %4 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)* %im1db) + %5 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)* %im2d) + %6 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)* %im3d) + ret void +} + + +attributes #0 = { "VCFunction" }