Skip to content

Commit 951a284

Browse files
authored
[HLSL] Implement SV_GroupThreadId semantic (#117781)
Support HLSL SV_GroupThreadId attribute. For `directx` target, translate it into `dx.thread.id.in.group` in clang codeGen and lower `dx.thread.id.in.group` to `dx.op.threadIdInGroup` in LLVM DirectX backend. For `spir-v` target, translate it into `spv.thread.id.in.group` in clang codeGen and lower `spv.thread.id.in.group` to a `LocalInvocationId` builtin variable in LLVM SPIR-V backend. Fixes: #70122
1 parent 968e3b6 commit 951a284

File tree

15 files changed

+241
-23
lines changed

15 files changed

+241
-23
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4651,6 +4651,13 @@ def HLSLNumThreads: InheritableAttr {
46514651
let Documentation = [NumThreadsDocs];
46524652
}
46534653

4654+
def HLSLSV_GroupThreadID: HLSLAnnotationAttr {
4655+
let Spellings = [HLSLAnnotation<"SV_GroupThreadID">];
4656+
let Subjects = SubjectList<[ParmVar, Field]>;
4657+
let LangOpts = [HLSL];
4658+
let Documentation = [HLSLSV_GroupThreadIDDocs];
4659+
}
4660+
46544661
def HLSLSV_GroupID: HLSLAnnotationAttr {
46554662
let Spellings = [HLSLAnnotation<"SV_GroupID">];
46564663
let Subjects = SubjectList<[ParmVar, Field]>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7941,6 +7941,17 @@ randomized.
79417941
}];
79427942
}
79437943

7944+
def HLSLSV_GroupThreadIDDocs : Documentation {
7945+
let Category = DocCatFunction;
7946+
let Content = [{
7947+
The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which
7948+
individual thread within a thread group is executing in. This attribute is
7949+
only supported in compute shaders.
7950+
7951+
The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid
7952+
}];
7953+
}
7954+
79447955
def HLSLSV_GroupIDDocs : Documentation {
79457956
let Category = DocCatFunction;
79467957
let Content = [{

clang/include/clang/Sema/SemaHLSL.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class SemaHLSL : public SemaBase {
119119
void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL);
120120
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
121121
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
122+
void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL);
122123
void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL);
123124
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
124125
void handleShaderAttr(Decl *D, const ParsedAttr &AL);

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
389389
CGM.getIntrinsic(getThreadIdIntrinsic());
390390
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
391391
}
392+
if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) {
393+
llvm::Function *GroupThreadIDIntrinsic =
394+
CGM.getIntrinsic(getGroupThreadIdIntrinsic());
395+
return buildVectorInput(B, GroupThreadIDIntrinsic, Ty);
396+
}
392397
if (D.hasAttr<HLSLSV_GroupIDAttr>()) {
393398
llvm::Function *GroupIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_group_id);
394399
return buildVectorInput(B, GroupIDIntrinsic, Ty);

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class CGHLSLRuntime {
8686
GENERATE_HLSL_INTRINSIC_FUNCTION(Step, step)
8787
GENERATE_HLSL_INTRINSIC_FUNCTION(Radians, radians)
8888
GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id)
89+
GENERATE_HLSL_INTRINSIC_FUNCTION(GroupThreadId, thread_id_in_group)
8990
GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot)
9091
GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
9192
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)

clang/lib/Parse/ParseHLSL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
280280
case ParsedAttr::UnknownAttribute:
281281
Diag(Loc, diag::err_unknown_hlsl_semantic) << II;
282282
return;
283+
case ParsedAttr::AT_HLSLSV_GroupThreadID:
283284
case ParsedAttr::AT_HLSLSV_GroupID:
284285
case ParsedAttr::AT_HLSLSV_GroupIndex:
285286
case ParsedAttr::AT_HLSLSV_DispatchThreadID:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7114,6 +7114,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
71147114
case ParsedAttr::AT_HLSLWaveSize:
71157115
S.HLSL().handleWaveSizeAttr(D, AL);
71167116
break;
7117+
case ParsedAttr::AT_HLSLSV_GroupThreadID:
7118+
S.HLSL().handleSV_GroupThreadIDAttr(D, AL);
7119+
break;
71177120
case ParsedAttr::AT_HLSLSV_GroupID:
71187121
S.HLSL().handleSV_GroupIDAttr(D, AL);
71197122
break;

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ void SemaHLSL::CheckSemanticAnnotation(
434434
switch (AnnotationAttr->getKind()) {
435435
case attr::HLSLSV_DispatchThreadID:
436436
case attr::HLSLSV_GroupIndex:
437+
case attr::HLSLSV_GroupThreadID:
437438
case attr::HLSLSV_GroupID:
438439
if (ST == llvm::Triple::Compute)
439440
return;
@@ -787,6 +788,15 @@ void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) {
787788
HLSLSV_DispatchThreadIDAttr(getASTContext(), AL));
788789
}
789790

791+
void SemaHLSL::handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL) {
792+
auto *VD = cast<ValueDecl>(D);
793+
if (!diagnoseInputIDType(VD->getType(), AL))
794+
return;
795+
796+
D->addAttr(::new (getASTContext())
797+
HLSLSV_GroupThreadIDAttr(getASTContext(), AL));
798+
}
799+
790800
void SemaHLSL::handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL) {
791801
auto *VD = cast<ValueDecl>(D);
792802
if (!diagnoseInputIDType(VD->getType(), AL))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
2+
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
3+
4+
// Make sure SV_GroupThreadID translated into dx.thread.id.in.group for directx target and spv.thread.id.in.group for spirv target.
5+
6+
// CHECK: define void @foo()
7+
// CHECK: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0)
8+
// CHECK-DXIL: call void @{{.*}}foo{{.*}}(i32 %[[#ID]])
9+
// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(i32 %[[#ID]])
10+
[shader("compute")]
11+
[numthreads(8,8,1)]
12+
void foo(uint Idx : SV_GroupThreadID) {}
13+
14+
// CHECK: define void @bar()
15+
// CHECK: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0)
16+
// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
17+
// CHECK: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1)
18+
// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
19+
// CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
20+
// CHECK-SPIRV: call spir_func void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
21+
[shader("compute")]
22+
[numthreads(8,8,1)]
23+
void bar(uint2 Idx : SV_GroupThreadID) {}
24+
25+
// CHECK: define void @test()
26+
// CHECK: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0)
27+
// CHECK: %[[#ID_X_:]] = insertelement <3 x i32> poison, i32 %[[#ID_X]], i64 0
28+
// CHECK: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1)
29+
// CHECK: %[[#ID_XY:]] = insertelement <3 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
30+
// CHECK: %[[#ID_Z:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 2)
31+
// CHECK: %[[#ID_XYZ:]] = insertelement <3 x i32> %[[#ID_XY]], i32 %[[#ID_Z]], i64 2
32+
// CHECK-DXIL: call void @{{.*}}test{{.*}}(<3 x i32> %[[#ID_XYZ]])
33+
// CHECK-SPIRV: call spir_func void @{{.*}}test{{.*}}(<3 x i32> %[[#ID_XYZ]])
34+
[shader("compute")]
35+
[numthreads(8,8,1)]
36+
void test(uint3 Idx : SV_GroupThreadID) {}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -hlsl-entry CSMain -x hlsl -finclude-default-header -ast-dump -o - %s | FileCheck %s
2-
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-mesh -hlsl-entry CSMain -x hlsl -finclude-default-header -verify -o - %s
32

43
[numthreads(8,8,1)]
5-
// expected-error@+3 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' shaders, requires compute}}
6-
// expected-error@+2 {{attribute 'SV_DispatchThreadID' is unsupported in 'mesh' shaders, requires compute}}
7-
// expected-error@+1 {{attribute 'SV_GroupID' is unsupported in 'mesh' shaders, requires compute}}
8-
void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID) {
9-
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint)'
4+
void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID, uint GThreadID : SV_GroupThreadID) {
5+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint, uint)'
106
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:17 GI 'int'
117
// CHECK-NEXT: HLSLSV_GroupIndexAttr
128
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:42 ID 'uint'
139
// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr
1410
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:73 GID 'uint'
1511
// CHECK-NEXT: HLSLSV_GroupIDAttr
12+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:96 GThreadID 'uint'
13+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
1614
}

0 commit comments

Comments
 (0)