diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index a772054960..b07d4a9a89 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..c3cd903ae0 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'}} }