From c1a417eeb59db3dfc459bb1d62220cf1f5e53d77 Mon Sep 17 00:00:00 2001 From: Sarah Spall Date: Mon, 2 Mar 2026 14:36:25 -0800 Subject: [PATCH 1/2] template work --- tools/clang/lib/Sema/SemaDecl.cpp | 6 +++++- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 11 +++++++++++ .../groupsharedArgs/TemplateTest.hlsl | 12 ++++++++++++ .../SemaHLSL/v202x/groupshared/ExplicitCast.hlsl | 9 +++++++++ .../v202x/groupshared/ExportNoInlineTest.hlsl | 11 +++++++++++ .../test/SemaHLSL/v202x/groupshared/InOut.hlsl | 16 ++++++++++++++++ .../v202x/groupshared/NotGroupSharedTest.hlsl | 8 ++++++++ .../v202x/groupshared/Pre202xWarning.hlsl | 6 ++++++ .../SemaHLSL/v202x/groupshared/ScalarTest.hlsl | 8 ++++++++ 9 files changed, 86 insertions(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index a772054960..b106955148 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -10459,7 +10459,11 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, if (T.getAddressSpace() != 0) { // OpenCL allows function arguments declared to be an array of a type // to be qualified with an address space. - if (!(getLangOpts().OpenCL && T->isArrayType())) { + if (!(getLangOpts().OpenCL && T->isArrayType()) && + // HLSL allows parameters to be qualified with the groupshared + // address space. + !(getLangOpts().HLSL && T.getAddressSpace() == + hlsl::DXIL::kTGSMAddrSpace)) { Diag(NameLoc, diag::err_arg_with_address_space); New->setInvalidDecl(); } diff --git a/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index dc112ca364..571c6e49a6 100644 --- a/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -268,6 +268,17 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, continue; } + if (isa(TmplAttr)) { + // the type wasn't set properly before so we need to instantiate this type as + // a groupshared reference + ParmVarDecl *NewParm = cast(New); + NewParm->addAttr(TmplAttr->clone(getASTContext())); + NewParm->setType(Context.getAddrSpaceQualType(NewParm->getType(), + hlsl::DXIL::kTGSMAddrSpace)); + NewParm->setType(Context.getLValueReferenceType(NewParm->getType())); + continue; + } + // HLSL Change Begin - Validate post-instantiation attributes DiagnoseHLSLDeclAttr(New, TmplAttr); // HLSL Change End diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl index 48a615a196..44d74f8d71 100644 --- a/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl @@ -26,7 +26,19 @@ void fn1(groupshared Shared Sh) { Sh.Arr[1] = D; } +// CHECK-LABEL: <4 x i32> @"\01??$tfoo@V?$vector@H$03@@@@YA?AV?$vector@H$03@@AGAV0@@Z"(<4 x i32> addrspace(3)* dereferenceable(16) %a) +// CHECK: [[B:%.*]] = load <4 x i32>, <4 x i32> addrspace(3)* %a, align 4 +// CHECK: ret <4 x i32> [[B]] +template +T tfoo(groupshared T a) { + return a; +} + +groupshared int4 SharedData1; + [numthreads(4, 1, 1)] void main(uint3 TID : SV_GroupThreadID) { fn1(SharedData); + tfoo(SharedData1); + tfoo(SharedData1); } diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl index 55652e1866..68c563e9f9 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl @@ -7,7 +7,16 @@ void fn1(groupshared half Sh) { Sh = 5; } +template +T fnT(groupshared T A) { +// expected-note@-1{{candidate function [with T = half] not viable: 1st argument ('half') is in address space 0, but parameter must be in address space 3}} + return A; +} + void fn2() { fn1((half)SharedData); // expected-error@-1{{no matching function for call to 'fn1'}} + // not sure why someone would write this but make sure templates do something sane. + fnT((half)SharedData); + // expected-error@-1{{no matching function for call to 'fnT'}} } diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl index 56f8042491..177bf41bbe 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl @@ -9,3 +9,14 @@ export void fn1(groupshared uint Sh) { // expected-error@-1{{groupshared and export/noinline cannot be used together for a parameter}} Sh = 6; } + +template +void fn3(groupshared T A, groupshared T B) { + A = B; +} + +export template void fn3(groupshared uint A, groupshared uint B); +// expected-error@-1{{'template' is a reserved keyword in HLSL}} +template [noinline] void fn3(groupshared float A, groupshared float B); +// expected-error@-1{{use of undeclared identifier 'noinline'}} +// expected-error@-2{{expected unqualified-id}} \ No newline at end of file diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl index 3596b2f03f..4ac02d3f25 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl @@ -23,3 +23,19 @@ void fn8() { fn1(SharedData); // expected-warning@-1{{Passing groupshared variable to a parameter annotated with inout. See 'groupshared' parameter annotation added in 202x}} } + +template +T fn9(inout groupshared T A) { +// expected-error@-1{{'inout' and 'groupshared' cannot be used together for a parameter}} + return A; +} +template +T fn10(in groupshared T A) { +// expected-error@-1{{'in' and 'groupshared' cannot be used together for a parameter}} + return A; +} +template +T fn11(out groupshared T A) { +// expected-error@-1{{'out' and 'groupshared' cannot be used together for a parameter}} + return A; +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl index d6e8b4d4c3..93f5bb34ae 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl @@ -5,9 +5,17 @@ void fn1(groupshared half Sh) { Sh = 5; } +template +T fn2(groupshared T Sh) { +// expected-note@-1{{candidate template ignored: can't deduce a type for 'T' that would make '__attribute__((address_space(3))) T' equal 'half'}} + return Sh; +} + [numthreads(4, 1, 1)] void main(uint3 TID : SV_GroupThreadID) { half tmp = 1.0; fn1(tmp); // expected-error@-1{{no matching function for call to 'fn1'}} + fn2(tmp); + // expected-error@-1{{no matching function for call to 'fn2'}} } diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl index 1382be09a5..0c1de8466d 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl @@ -10,3 +10,9 @@ void fn1(groupshared uint Sh) { void fn2() { fn1(SharedData); } + +template +T fn3(groupshared T A) { +// expected-warning@-1{{Support for groupshared parameter annotation not added until HLSL 202x}} + return A; +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl index 58f1804a22..70f51f9c4b 100644 --- a/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl @@ -7,7 +7,15 @@ void fn1(groupshared half Sh) { Sh = 5; } +template +T fn3(groupshared T A) { +// expected-note@-1{{candidate function [with T = half] not viable: no known conversion from '__attribute__((address_space(3))) uint16_t' to '__attribute__((address_space(3))) half' for 1st argument}} + return A; +} + void fn2() { fn1(SharedData); // expected-error@-1{{no matching function for call to 'fn1'}} + fn3(SharedData); + // expected-error@-1{{no matching function for call to 'fn3'}} } From d33a50b465591969b58afa8451af303b41df61ff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Mar 2026 22:42:01 +0000 Subject: [PATCH 2/2] chore: autopublish 2026-03-02T22:42:01Z --- tools/clang/lib/Sema/SemaDecl.cpp | 8 ++++---- tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index b106955148..b07d4a9a89 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -10460,10 +10460,10 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, // OpenCL allows function arguments declared to be an array of a type // to be qualified with an address space. if (!(getLangOpts().OpenCL && T->isArrayType()) && - // HLSL allows parameters to be qualified with the groupshared - // address space. - !(getLangOpts().HLSL && T.getAddressSpace() == - hlsl::DXIL::kTGSMAddrSpace)) { + // HLSL allows parameters to be qualified with the groupshared + // address space. + !(getLangOpts().HLSL && + T.getAddressSpace() == hlsl::DXIL::kTGSMAddrSpace)) { Diag(NameLoc, diag::err_arg_with_address_space); New->setInvalidDecl(); } diff --git a/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 571c6e49a6..c3cd903ae0 100644 --- a/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -269,12 +269,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, } if (isa(TmplAttr)) { - // the type wasn't set properly before so we need to instantiate this type as - // a groupshared reference + // the type wasn't set properly before so we need to instantiate this type + // as a groupshared reference ParmVarDecl *NewParm = cast(New); NewParm->addAttr(TmplAttr->clone(getASTContext())); - NewParm->setType(Context.getAddrSpaceQualType(NewParm->getType(), - hlsl::DXIL::kTGSMAddrSpace)); + NewParm->setType(Context.getAddrSpaceQualType( + NewParm->getType(), hlsl::DXIL::kTGSMAddrSpace)); NewParm->setType(Context.getLValueReferenceType(NewParm->getType())); continue; }