From 76e2161c594ada9e823cda7b1c26a40e26b0ac62 Mon Sep 17 00:00:00 2001 From: Sven van Haastregt Date: Tue, 19 Nov 2024 11:26:10 +0100 Subject: [PATCH] [Backport to 17] [SPIR-V 1.1] SPIRVReader: Add OpSizeOf support (#2853) (#2863) The `OpSizeOf` instruction was added in SPIR-V 1.1, but not supported yet. (cherry picked from commit 9aeb7eb92d7c0cb79ddc4ef87be87dd4d9645356) --- lib/SPIRV/SPIRVReader.cpp | 9 ++++++++ lib/SPIRV/libSPIRV/SPIRVEntry.h | 1 - lib/SPIRV/libSPIRV/SPIRVInstruction.h | 10 ++++++++ lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 1 + test/OpSizeOf.spvasm | 33 +++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 test/OpSizeOf.spvasm diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 4d7c3eb231..66793e25d9 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -1607,6 +1607,15 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, case OpUndef: return mapValue(BV, UndefValue::get(transType(BV->getType()))); + case OpSizeOf: { + Type *ResTy = transType(BV->getType()); + auto *BI = static_cast(BV); + SPIRVType *TypeArg = reinterpret_cast(BI->getOpValue(0)); + Type *EltTy = transType(TypeArg->getPointerElementType()); + uint64_t Size = M->getDataLayout().getTypeStoreSize(EltTy).getFixedValue(); + return mapValue(BV, ConstantInt::get(ResTy, Size)); + } + case OpVariable: { auto BVar = static_cast(BV); auto *PreTransTy = BVar->getType()->getPointerElementType(); diff --git a/lib/SPIRV/libSPIRV/SPIRVEntry.h b/lib/SPIRV/libSPIRV/SPIRVEntry.h index 5f360ede42..7b10d181b5 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEntry.h +++ b/lib/SPIRV/libSPIRV/SPIRVEntry.h @@ -1086,7 +1086,6 @@ _SPIRV_OP(NamedBarrierInitialize) _SPIRV_OP(MemoryNamedBarrier) _SPIRV_OP(GetKernelMaxNumSubgroups) _SPIRV_OP(GetKernelLocalSizeForSubgroupCount) -_SPIRV_OP(SizeOf) #undef _SPIRV_OP } // namespace SPIRV diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index b9968ef770..7ab9358af0 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -1540,6 +1540,16 @@ class SPIRVTranspose : public SPIRVInstruction { SPIRVId Matrix; }; +class SPIRVSizeOfInstBase : public SPIRVInstTemplateBase { +protected: + SPIRVWord getRequiredSPIRVVersion() const override { + return static_cast(VersionNumber::SPIRV_1_1); + } +}; + +typedef SPIRVInstTemplate + SPIRVSizeOf; + class SPIRVUnary : public SPIRVInstTemplateBase { protected: void validate() const override { diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index a31342dc30..aa21bf4ed2 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -291,6 +291,7 @@ _SPIRV_OP(ImageSparseTexelsResident, 316) _SPIRV_OP(NoLine, 317) _SPIRV_OP(AtomicFlagTestAndSet, 318) _SPIRV_OP(AtomicFlagClear, 319) +_SPIRV_OP(SizeOf, 321) _SPIRV_OP(TypePipeStorage, 322) _SPIRV_OP(ConstantPipeStorage, 323) _SPIRV_OP(CreatePipeFromPipeStorage, 324) diff --git a/test/OpSizeOf.spvasm b/test/OpSizeOf.spvasm new file mode 100644 index 0000000000..0006afae78 --- /dev/null +++ b/test/OpSizeOf.spvasm @@ -0,0 +1,33 @@ +; REQUIRES: spirv-as +; RUN: spirv-as --target-env spv1.1 -o %t.spv %s +; TODO: reenable spirv-val when OpSizeOf is supported. +; R/U/N: spirv-val %t.spv +; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s + OpCapability Addresses + OpCapability Kernel + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %f "testSizeOf" + OpName %p "p" + %void = OpTypeVoid + %bool = OpTypeBool + %i32 = OpTypeInt 32 0 + %struct = OpTypeStruct %i32 %i32 +%_ptr_CrossWorkgroup_bool = OpTypePointer CrossWorkgroup %bool +%_ptr_CrossWorkgroup_i32 = OpTypePointer CrossWorkgroup %i32 +%_ptr_CrossWorkgroup_struct = OpTypePointer CrossWorkgroup %struct + %fnTy = OpTypeFunction %void %_ptr_CrossWorkgroup_i32 + + %f = OpFunction %void None %fnTy + %p = OpFunctionParameter %_ptr_CrossWorkgroup_i32 + %10 = OpLabel + +; CHECK: store i32 1, ptr addrspace(1) %p + %11 = OpSizeOf %i32 %_ptr_CrossWorkgroup_bool + OpStore %p %11 + +; CHECK: store i32 8, ptr addrspace(1) %p + %12 = OpSizeOf %i32 %_ptr_CrossWorkgroup_struct + OpStore %p %12 + + OpReturn + OpFunctionEnd