From a11d65d6a2ec31d15a9db6935b48907f5f3ece75 Mon Sep 17 00:00:00 2001 From: jgstarIntel Date: Thu, 29 Jun 2023 11:59:08 -0400 Subject: [PATCH] Implement support for SPV_KHR_shader_clock (#2026) Link to the spec: https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_shader_clock.asciidoc Original commit: https://github.com/KhronosGroup/SPIRV-LLVM-Translator/commit/e4dfa92 --- llvm-spirv/include/LLVMSPIRVExtensions.inc | 1 + .../lib/SPIRV/libSPIRV/SPIRVInstruction.h | 38 ++++++++++++++- .../lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 1 + .../KHR/SPV_KHR_shader_clock/shader_clock.ll | 46 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 llvm-spirv/test/extensions/KHR/SPV_KHR_shader_clock/shader_clock.ll diff --git a/llvm-spirv/include/LLVMSPIRVExtensions.inc b/llvm-spirv/include/LLVMSPIRVExtensions.inc index 0e5669b691b70..05a10d4d7c781 100644 --- a/llvm-spirv/include/LLVMSPIRVExtensions.inc +++ b/llvm-spirv/include/LLVMSPIRVExtensions.inc @@ -13,6 +13,7 @@ EXT(SPV_KHR_expect_assume) EXT(SPV_KHR_uniform_group_instructions) EXT(SPV_KHR_subgroup_rotate) EXT(SPV_KHR_non_semantic_info) +EXT(SPV_KHR_shader_clock) EXT(SPV_INTEL_subgroups) EXT(SPV_INTEL_media_block_io) EXT(SPV_INTEL_device_side_avc_motion_estimation) diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h index f935c25eac313..d403cc930c2f3 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -3678,6 +3678,42 @@ class SPIRVTensorFloat32RoundingINTELInstBase : public SPIRVUnaryInst { typedef SPIRVTensorFloat32RoundingINTELInstBase SPIRV##x; _SPIRV_OP(RoundFToTF32INTEL) #undef _SPIRV_OP -} // namespace SPIRV +template class SPIRVReadClockKHRInstBase : public SPIRVUnaryInst { +protected: + SPIRVCapVec getRequiredCapability() const override { + return getVec(CapabilityShaderClockKHR); + } + + std::optional getRequiredExtension() const override { + return ExtensionID::SPV_KHR_shader_clock; + } + + void validate() const override { + SPIRVUnaryInst::validate(); + + SPIRVType *ResCompTy = this->getType(); + SPIRVWord ResCompCount = 1; + if (ResCompTy->isTypeVector()) { + ResCompCount = ResCompTy->getVectorComponentCount(); + ResCompTy = ResCompTy->getVectorComponentType(); + } + auto InstName = OpCodeNameMap::map(OC); + SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog(); + + // check for either 64 bit int type or two element vector of 32 bit int + // types. + SPVErrLog.checkError( + ResCompTy->isTypeInt(64) || + (ResCompCount == 2 && ResCompTy->isTypeInt(32)), + SPIRVEC_InvalidInstruction, + InstName + "\nResult value must be a scalar of integer" + " 64-bit type or two element vector of 32-bit type\n"); + } +}; +#define _SPIRV_OP(x, ...) typedef SPIRVReadClockKHRInstBase SPIRV##x; +_SPIRV_OP(ReadClockKHR) +#undef _SPIRV_OP + +} // namespace SPIRV #endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index 94197e7bb0400..a6961fcb0baf3 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -335,6 +335,7 @@ _SPIRV_OP(SUDotKHR, 4452) _SPIRV_OP(SDotAccSatKHR, 4453) _SPIRV_OP(UDotAccSatKHR, 4454) _SPIRV_OP(SUDotAccSatKHR, 4455) +_SPIRV_OP(ReadClockKHR, 5056) _SPIRV_OP(SubgroupShuffleINTEL, 5571) _SPIRV_OP(SubgroupShuffleDownINTEL, 5572) _SPIRV_OP(SubgroupShuffleUpINTEL, 5573) diff --git a/llvm-spirv/test/extensions/KHR/SPV_KHR_shader_clock/shader_clock.ll b/llvm-spirv/test/extensions/KHR/SPV_KHR_shader_clock/shader_clock.ll new file mode 100644 index 0000000000000..4ccfceb2fb7fe --- /dev/null +++ b/llvm-spirv/test/extensions/KHR/SPV_KHR_shader_clock/shader_clock.ll @@ -0,0 +1,46 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_KHR_shader_clock +; RUN: llvm-spirv %t.spv -o %t.spt --to-text +; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.spv -o %t.rev.bc -r -emit-opaque-pointers --spirv-target-env=SPV-IR +; RUN: llvm-dis %t.rev.bc -o %t.rev.ll +; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM + +; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR +; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension: +; CHECK-ERROR-NEXT: SPV_KHR_shader_clock + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64-unknown-unknown" + +; CHECK-SPIRV: Capability ShaderClockKHR +; CHECK-SPIRV: Extension "SPV_KHR_shader_clock" +; CHECK-SPIRV: TypeInt [[#I32Ty:]] 32 +; CHECK-SPIRV: TypeInt [[#I64Ty:]] 64 +; CHECK-SPIRV: TypeVector [[#I32v2Ty:]] [[#I32Ty]] 2 + +; CHECK-SPIRV: FunctionParameter [[#I32Ty]] [[I32ValId:.*]] + +; CHECK-SPIRV: ReadClockKHR [[#I32v2Ty]] [[#]] [[I32ValId]] +; CHECK-SPIRV: ReadClockKHR [[#I64Ty]] [[#]] [[I32ValId]] + +; CHECK-LLVM: call spir_func <2 x i32> @_Z20__spirv_ReadClockKHR +; CHECK-LLVM: call spir_func i64 @_Z20__spirv_ReadClockKHR + +define spir_func void @_Z7read_types(i32 %a) { + %1 = tail call spir_func <2 x i32> @_Z20__spirv_ReadClockKHRIDv2_jET_j(i32 %a) + %2 = tail call spir_func i64 @_Z20__spirv_ReadClockKHRImET_j(i32 %a) + ret void +} + +declare spir_func <2 x i32> @_Z20__spirv_ReadClockKHRIDv2_jET_j(i32) + +declare spir_func i64 @_Z20__spirv_ReadClockKHRImET_j(i32) + +!opencl.spir.version = !{!0} +!spirv.Source = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, i32 2} +!1 = !{i32 4, i32 100000} +!2 = !{!"clang version 16.0.0"}