diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 4d7c3eb23..66793e25d 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 5f360ede4..7b10d181b 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 b9968ef77..7ab9358af 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 a31342dc3..aa21bf4ed 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 000000000..0006afae7 --- /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