Skip to content

Commit 4e560b7

Browse files
MrSidimsvmaksimo
authored andcommitted
Implement SPV_INTEL_hw_thread_queries extension
The extension adds BuiltIn decorations to query maximum number of H/W threads per a sub-device (tile), a sub-device ID and a H/W thread ID within the sub-device. These instructions combined can be used to calculate a unique H/W thread on which the code is being launched. Spec: #4747 Some info about Intel multi-tile cards: https://github.com/intel/llvm/blob/sycl/sycl/doc/MultiTileCardWithLevelZero.md Signed-off-by: Dmitry Sidorov <dmitry.sidorov@intel.com> Original commit: KhronosGroup/SPIRV-LLVM-Translator@ddb1c7a
1 parent 60291f5 commit 4e560b7

File tree

10 files changed

+148
-1
lines changed

10 files changed

+148
-1
lines changed

llvm-spirv/include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ EXT(SPV_INTEL_runtime_aligned)
4646
EXT(SPV_INTEL_arithmetic_fence)
4747
EXT(SPV_INTEL_bfloat16_conversion)
4848
EXT(SPV_INTEL_joint_matrix)
49+
EXT(SPV_INTEL_hw_thread_queries)

llvm-spirv/lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
9292
<< "BuiltinKind = " << BuiltinKind << '\n');
9393

9494
if (BuiltinKind != SPIRVBuiltinVariableKind::BuiltInMax) {
95+
if (static_cast<uint32_t>(BuiltinKind) >=
96+
internal::BuiltInSubDeviceIDINTEL &&
97+
static_cast<uint32_t>(BuiltinKind) <=
98+
internal::BuiltInMaxHWThreadIDPerSubDeviceINTEL)
99+
return;
100+
95101
visitCallSPIRVBuiltin(&CI, BuiltinKind);
96102
return;
97103
}

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,19 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
15391539
spv::BuiltIn Builtin = spv::BuiltInPosition;
15401540
if (!GV->hasName() || !getSPIRVBuiltin(GV->getName().str(), Builtin))
15411541
return BVar;
1542+
if (static_cast<uint32_t>(Builtin) >= internal::BuiltInSubDeviceIDINTEL &&
1543+
static_cast<uint32_t>(Builtin) <=
1544+
internal::BuiltInMaxHWThreadIDPerSubDeviceINTEL) {
1545+
if (!BM->isAllowedToUseExtension(
1546+
ExtensionID::SPV_INTEL_hw_thread_queries)) {
1547+
std::string ErrorStr = "Intel HW thread queries must be enabled by "
1548+
"SPV_INTEL_hw_thread_queries extension.\n"
1549+
"LLVM value that is being translated:\n";
1550+
getErrorLog().checkError(false, SPIRVEC_InvalidModule, V, ErrorStr);
1551+
}
1552+
BM->addExtension(ExtensionID::SPV_INTEL_hw_thread_queries);
1553+
}
1554+
15421555
BVar->setBuiltin(Builtin);
15431556
return BVar;
15441557
}

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,12 @@ template <> inline void SPIRVMap<BuiltIn, SPIRVCapVec>::init() {
491491
ADD_VEC_INIT(BuiltInSubgroupLtMask, {CapabilityGroupNonUniformBallot});
492492
ADD_VEC_INIT(BuiltInVertexIndex, {CapabilityShader});
493493
ADD_VEC_INIT(BuiltInInstanceIndex, {CapabilityShader});
494+
ADD_VEC_INIT(internal::BuiltInSubDeviceIDINTEL,
495+
{internal::CapabilityHWThreadQueryINTEL});
496+
ADD_VEC_INIT(internal::BuiltInHWThreadIDINTEL,
497+
{internal::CapabilityHWThreadQueryINTEL});
498+
ADD_VEC_INIT(internal::BuiltInMaxHWThreadIDPerSubDeviceINTEL,
499+
{internal::CapabilityHWThreadQueryINTEL});
494500
}
495501

496502
template <> inline void SPIRVMap<MemorySemanticsMask, SPIRVCapVec>::init() {

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ inline bool isValid(spv::FunctionParameterAttribute V) {
174174
}
175175

176176
inline bool isValid(spv::BuiltIn V) {
177-
switch (V) {
177+
switch (static_cast<uint32_t>(V)) {
178178
case BuiltInPosition:
179179
case BuiltInPointSize:
180180
case BuiltInClipDistance:
@@ -273,6 +273,9 @@ inline bool isValid(spv::BuiltIn V) {
273273
case BuiltInSMCountNV:
274274
case BuiltInWarpIDNV:
275275
case BuiltInSMIDNV:
276+
case internal::BuiltInSubDeviceIDINTEL:
277+
case internal::BuiltInHWThreadIDINTEL:
278+
case internal::BuiltInMaxHWThreadIDPerSubDeviceINTEL:
276279
return true;
277280
default:
278281
return false;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ template <> inline void SPIRVMap<BuiltIn, std::string>::init() {
306306
add(BuiltInWarpIDNV, "BuiltInWarpIDNV");
307307
add(BuiltInSMIDNV, "BuiltInSMIDNV");
308308
add(BuiltInMax, "BuiltInMax");
309+
add(internal::BuiltInSubDeviceIDINTEL, "BuiltInSubDeviceIDINTEL");
310+
add(internal::BuiltInHWThreadIDINTEL, "BuiltInHWThreadIDINTEL");
311+
add(internal::BuiltInMaxHWThreadIDPerSubDeviceINTEL,
312+
"BuiltInMaxHWThreadIDPerSubDeviceINTEL");
309313
}
310314
SPIRV_DEF_NAMEMAP(BuiltIn, SPIRVBuiltInNameMap)
311315

@@ -582,6 +586,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
582586
add(internal::CapabilityFPArithmeticFenceINTEL, "FPArithmeticFenceINTEL");
583587
add(internal::CapabilityBfloat16ConversionINTEL, "Bfloat16ConversionINTEL");
584588
add(internal::CapabilityJointMatrixINTEL, "JointMatrixINTEL");
589+
add(internal::CapabilityHWThreadQueryINTEL, "HWThreadQueryINTEL");
585590
}
586591
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
587592

llvm-spirv/lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum InternalCapability {
7676
ICapTokenTypeINTEL = 6112,
7777
ICapBfloat16ConversionINTEL = 6115,
7878
ICapabilityJointMatrixINTEL = 6118,
79+
ICapabilityHWThreadQueryINTEL = 6134,
7980
ICapFPArithmeticFenceINTEL = 6144
8081
};
8182

@@ -98,12 +99,23 @@ constexpr LinkageType LinkageTypeInternal =
9899

99100
enum InternalJointMatrixLayout { RowMajor, ColumnMajor, PackedA, PackedB };
100101

102+
enum InternalBuiltIn {
103+
IBuiltInSubDeviceIDINTEL = 6135,
104+
IBuiltInHWThreadIDINTEL = 6136,
105+
IBuiltInMaxHWThreadIDPerSubDeviceINTEL = 6137
106+
};
107+
101108
#define _SPIRV_OP(x, y) constexpr x x##y = static_cast<x>(I##x##y);
102109
_SPIRV_OP(Capability, JointMatrixINTEL)
103110
_SPIRV_OP(Op, TypeJointMatrixINTEL)
104111
_SPIRV_OP(Op, JointMatrixLoadINTEL)
105112
_SPIRV_OP(Op, JointMatrixStoreINTEL)
106113
_SPIRV_OP(Op, JointMatrixMadINTEL)
114+
115+
_SPIRV_OP(Capability, HWThreadQueryINTEL)
116+
_SPIRV_OP(BuiltIn, SubDeviceIDINTEL)
117+
_SPIRV_OP(BuiltIn, HWThreadIDINTEL)
118+
_SPIRV_OP(BuiltIn, MaxHWThreadIDPerSubDeviceINTEL)
107119
#undef _SPIRV_OP
108120

109121
constexpr Op OpForward = static_cast<Op>(IOpForward);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; Test for SPV_INTEL_hw_thread_queries feature
2+
; SPIR-V friendly LLVM IR to SPIR-V translation and vice versa
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_hw_thread_queries -o %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
6+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
7+
8+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
9+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
10+
; RUN: llvm-spirv -r --spirv-target-env=SPV-IR %t.spv -o %t.rev.bc
11+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
12+
13+
; CHECK-SPIRV: Capability HWThreadQueryINTEL
14+
; CHECK-SPIRV: Extension "SPV_INTEL_hw_thread_queries"
15+
; CHECK-SPIRV: Decorate [[#Id1:]] BuiltIn 6135
16+
; CHECK-SPIRV: Decorate [[#Id2:]] BuiltIn 6136
17+
; CHECK-SPIRV: Decorate [[#Id3:]] BuiltIn 6137
18+
; CHECK-SPIRV: Variable [[#]] [[#Id1]]
19+
; CHECK-SPIRV: Variable [[#]] [[#Id2]]
20+
; CHECK-SPIRV: Variable [[#]] [[#Id3]]
21+
22+
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"
23+
target triple = "spir-unknown-unknown"
24+
25+
; Function Attrs: nounwind readnone
26+
define spir_kernel void @foo() {
27+
entry:
28+
%0 = call spir_func i32 @_Z31__spirv_BuiltInSubDeviceIDINTELv() #1
29+
%1 = call spir_func i32 @_Z30__spirv_BuiltInHWThreadIDINTELv() #1
30+
%2 = call spir_func i32 @_Z45__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTELv() #1
31+
; CHECK-LLVM: call spir_func i32 @_Z31__spirv_BuiltInSubDeviceIDINTELv() #1
32+
; CHECK-LLVM: call spir_func i32 @_Z30__spirv_BuiltInHWThreadIDINTELv() #1
33+
; CHECK-LLVM: call spir_func i32 @_Z45__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTELv() #1
34+
ret void
35+
}
36+
37+
declare dso_local spir_func i32 @_Z31__spirv_BuiltInSubDeviceIDINTELv()
38+
39+
declare dso_local spir_func i32 @_Z30__spirv_BuiltInHWThreadIDINTELv()
40+
41+
declare dso_local spir_func i32 @_Z45__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTELv()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; Test for SPV_INTEL_hw_thread_queries feature
2+
; SPIR-V friendly LLVM IR to SPIR-V translation and vice versa
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_hw_thread_queries -o %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
6+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
7+
8+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
9+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
10+
; RUN: llvm-spirv -r --spirv-target-env=SPV-IR %t.spv -o %t.rev.bc
11+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
12+
13+
; CHECK-SPIRV: Capability HWThreadQueryINTEL
14+
; CHECK-SPIRV: Extension "SPV_INTEL_hw_thread_queries"
15+
; CHECK-SPIRV: Decorate [[#Id1:]] BuiltIn 6135
16+
; CHECK-SPIRV: Decorate [[#Id2:]] BuiltIn 6136
17+
; CHECK-SPIRV: Decorate [[#Id3:]] BuiltIn 6137
18+
; CHECK-SPIRV: Variable [[#]] [[#Id1]]
19+
; CHECK-SPIRV: Variable [[#]] [[#Id2]]
20+
; CHECK-SPIRV: Variable [[#]] [[#Id3]]
21+
22+
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"
23+
target triple = "spir-unknown-unknown"
24+
25+
@__spirv_BuiltInSubDeviceIDINTEL = external addrspace(1) global i32
26+
@__spirv_BuiltInHWThreadIDINTEL = external addrspace(1) global i32
27+
@__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTEL = external addrspace(1) global i32
28+
29+
; Function Attrs: nounwind readnone
30+
define spir_kernel void @foo() {
31+
entry:
32+
%0 = load i32, i32 addrspace(4)* addrspacecast (i32 addrspace(1)* @__spirv_BuiltInSubDeviceIDINTEL to i32 addrspace(4)*), align 4
33+
%1 = load i32, i32 addrspace(4)* addrspacecast (i32 addrspace(1)* @__spirv_BuiltInHWThreadIDINTEL to i32 addrspace(4)*), align 4
34+
%2 = load i32, i32 addrspace(4)* addrspacecast (i32 addrspace(1)* @__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTEL to i32 addrspace(4)*), align 4
35+
; CHECK-LLVM: call spir_func i32 @_Z31__spirv_BuiltInSubDeviceIDINTELv() #1
36+
; CHECK-LLVM: call spir_func i32 @_Z30__spirv_BuiltInHWThreadIDINTELv() #1
37+
; CHECK-LLVM: call spir_func i32 @_Z45__spirv_BuiltInMaxHWThreadIDPerSubDeviceINTELv() #1
38+
ret void
39+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; Negative test for SPV_INTEL_hw_thread_queries feature
2+
; Check for errors in case if the extension is not enabled, but the appropriate
3+
; SPV-IR patter is found
4+
; RUN: llvm-as %s -o %t.bc
5+
; RUN: not llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s
6+
7+
; CHECK: InvalidModule: Invalid SPIR-V module: Intel HW thread queries must be enabled by SPV_INTEL_hw_thread_queries extension.
8+
; CHECK: LLVM value that is being translated:
9+
; CHECK: @__spirv_BuiltInSubDeviceIDINTEL = external addrspace(1) global i32
10+
11+
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"
12+
target triple = "spir-unknown-unknown"
13+
14+
@__spirv_BuiltInSubDeviceIDINTEL = external addrspace(1) global i32
15+
16+
; Function Attrs: nounwind readnone
17+
define spir_kernel void @foo() {
18+
entry:
19+
%0 = load i32, i32 addrspace(4)* addrspacecast (i32 addrspace(1)* @__spirv_BuiltInSubDeviceIDINTEL to i32 addrspace(4)*), align 4
20+
ret void
21+
}

0 commit comments

Comments
 (0)