Skip to content

Commit 7be7837

Browse files
frasercrmckjsji
authored andcommitted
Relax operand constraints on max_work_group_size metadata (#2711)
This allows `max_work_group_size` metadata to behave like `reqd_work_group_size` and `work_group_size_hint` in that it may have between 1 and 3 operands. Missing dimensions are filled in with 1s. Original commit: KhronosGroup/SPIRV-LLVM-Translator@c38378cd5d814ed
1 parent 576d201 commit 7be7837

File tree

2 files changed

+75
-42
lines changed

2 files changed

+75
-42
lines changed

llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -129,32 +129,28 @@ void PreprocessMetadataBase::visit(Module *M) {
129129
// of ExecutionMode instructions.
130130

131131
// !{void (i32 addrspace(1)*)* @kernel, i32 17, i32 X, i32 Y, i32 Z}
132-
if (MDNode *WGSize = Kernel.getMetadata(kSPIR2MD::WGSize)) {
133-
assert(WGSize->getNumOperands() >= 1 && WGSize->getNumOperands() <= 3 &&
134-
"reqd_work_group_size does not have between 1 and 3 operands.");
135-
SmallVector<unsigned, 3> DecodedVals = decodeMDNode(WGSize);
136-
EM.addOp()
137-
.add(&Kernel)
138-
.add(spv::ExecutionModeLocalSize)
139-
.add(DecodedVals[0])
140-
.add(DecodedVals.size() >= 2 ? DecodedVals[1] : 1)
141-
.add(DecodedVals.size() == 3 ? DecodedVals[2] : 1)
142-
.done();
143-
}
144-
145132
// !{void (i32 addrspace(1)*)* @kernel, i32 18, i32 X, i32 Y, i32 Z}
146-
if (MDNode *WGSizeHint = Kernel.getMetadata(kSPIR2MD::WGSizeHint)) {
147-
assert(WGSizeHint->getNumOperands() >= 1 &&
148-
WGSizeHint->getNumOperands() <= 3 &&
149-
"work_group_size_hint does not have between 1 and 3 operands.");
150-
SmallVector<unsigned, 3> DecodedVals = decodeMDNode(WGSizeHint);
151-
EM.addOp()
152-
.add(&Kernel)
153-
.add(spv::ExecutionModeLocalSizeHint)
154-
.add(DecodedVals[0])
155-
.add(DecodedVals.size() >= 2 ? DecodedVals[1] : 1)
156-
.add(DecodedVals.size() == 3 ? DecodedVals[2] : 1)
157-
.done();
133+
// !{void (i32 addrspace(1)*)* @kernel, i32 max_work_group_size, i32 X,
134+
// i32 Y, i32 Z}
135+
std::pair<unsigned, const char *> WGSizeMDs[3] = {
136+
{spv::ExecutionModeLocalSize, kSPIR2MD::WGSize},
137+
{spv::ExecutionModeLocalSizeHint, kSPIR2MD::WGSizeHint},
138+
{spv::ExecutionModeMaxWorkgroupSizeINTEL, kSPIR2MD::MaxWGSize},
139+
};
140+
141+
for (auto &[ExMode, MDName] : WGSizeMDs) {
142+
if (MDNode *WGMD = Kernel.getMetadata(MDName)) {
143+
assert(WGMD->getNumOperands() >= 1 && WGMD->getNumOperands() <= 3 &&
144+
"work-group metadata does not have between 1 and 3 operands.");
145+
SmallVector<unsigned, 3> DecodedVals = decodeMDNode(WGMD);
146+
EM.addOp()
147+
.add(&Kernel)
148+
.add(ExMode)
149+
.add(DecodedVals[0])
150+
.add(DecodedVals.size() >= 2 ? DecodedVals[1] : 1)
151+
.add(DecodedVals.size() == 3 ? DecodedVals[2] : 1)
152+
.done();
153+
}
158154
}
159155

160156
// !{void (i32 addrspace(1)*)* @kernel, i32 30, i32 hint}
@@ -184,23 +180,6 @@ void PreprocessMetadataBase::visit(Module *M) {
184180
.done();
185181
}
186182

187-
// !{void (i32 addrspace(1)*)* @kernel, i32 max_work_group_size, i32 X,
188-
// i32 Y, i32 Z}
189-
if (MDNode *MaxWorkgroupSizeINTEL =
190-
Kernel.getMetadata(kSPIR2MD::MaxWGSize)) {
191-
assert(MaxWorkgroupSizeINTEL->getNumOperands() == 3 &&
192-
"max_work_group_size does not have 3 operands.");
193-
SmallVector<unsigned, 3> DecodedVals =
194-
decodeMDNode(MaxWorkgroupSizeINTEL);
195-
EM.addOp()
196-
.add(&Kernel)
197-
.add(spv::ExecutionModeMaxWorkgroupSizeINTEL)
198-
.add(DecodedVals[0])
199-
.add(DecodedVals[1])
200-
.add(DecodedVals[2])
201-
.done();
202-
}
203-
204183
// !{void (i32 addrspace(1)*)* @kernel, i32 no_global_work_offset}
205184
if (Kernel.getMetadata(kSPIR2MD::NoGlobalOffset)) {
206185
EM.addOp().add(&Kernel).add(spv::ExecutionModeNoGlobalOffsetINTEL).done();
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_kernel_attributes -o %t.spv
3+
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
4+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
8+
9+
; RUN: llvm-spirv -spirv-text -r %t.spt -o %t.rev.bc
10+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
11+
12+
; CHECK-SPIRV: Capability KernelAttributesINTEL
13+
; CHECK-SPIRV: Extension "SPV_INTEL_kernel_attributes"
14+
; CHECK-SPIRV: EntryPoint {{.*}} [[DIM1:[0-9]+]] "Dim1"
15+
; CHECK-SPIRV: EntryPoint {{.*}} [[DIM2:[0-9]+]] "Dim2"
16+
; CHECK-SPIRV: EntryPoint {{.*}} [[DIM3:[0-9]+]] "Dim3"
17+
; CHECK-SPIRV: ExecutionMode [[DIM1]] 5893 4 1 1
18+
; CHECK-SPIRV: ExecutionMode [[DIM2]] 5893 8 4 1
19+
; CHECK-SPIRV: ExecutionMode [[DIM3]] 5893 16 8 4
20+
; CHECK-SPIRV: Function {{.*}} [[DIM1]] {{.*}}
21+
; CHECK-SPIRV: Function {{.*}} [[DIM2]] {{.*}}
22+
; CHECK-SPIRV: Function {{.*}} [[DIM3]] {{.*}}
23+
24+
; CHECK-LLVM: define spir_kernel void @Dim1()
25+
; CHECK-LLVM-SAME: !max_work_group_size ![[MAXWG1:[0-9]+]]
26+
27+
; CHECK-LLVM: define spir_kernel void @Dim2()
28+
; CHECK-LLVM-SAME: !max_work_group_size ![[MAXWG2:[0-9]+]]
29+
30+
; CHECK-LLVM: define spir_kernel void @Dim3()
31+
; CHECK-LLVM-SAME: !max_work_group_size ![[MAXWG3:[0-9]+]]
32+
33+
; CHECK-LLVM: ![[MAXWG1]] = !{i32 4, i32 1, i32 1}
34+
; CHECK-LLVM: ![[MAXWG2]] = !{i32 8, i32 4, i32 1}
35+
; CHECK-LLVM: ![[MAXWG3]] = !{i32 16, i32 8, i32 4}
36+
37+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
38+
target triple = "spir64-unknown-linux"
39+
40+
define spir_kernel void @Dim1() !max_work_group_size !0 {
41+
ret void
42+
}
43+
44+
define spir_kernel void @Dim2() !max_work_group_size !1 {
45+
ret void
46+
}
47+
48+
define spir_kernel void @Dim3() !max_work_group_size !2 {
49+
ret void
50+
}
51+
52+
!0 = !{i32 4}
53+
!1 = !{i32 8, i32 4}
54+
!2 = !{i32 16, i32 8, i32 4}

0 commit comments

Comments
 (0)