Author: Sarah Spall
Date: 2026-03-09T19:17:12-07:00
New Revision: 24bf26c057553c58e576a7cb7df89a22d2fe6961

URL: 
https://github.com/llvm/llvm-project/commit/24bf26c057553c58e576a7cb7df89a22d2fe6961
DIFF: 
https://github.com/llvm/llvm-project/commit/24bf26c057553c58e576a7cb7df89a22d2fe6961.diff

LOG: [HLSL] Add support for groupshared args (#181886)

Add support for groupshared args to HLSL.
Some support for template errors and warnings still needs to be added in
a follow up (tracked by #182535)
Closes #174472

Added: 
    clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl
    clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
    clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl
    clang/test/CodeGenHLSL/groupsharedArgs/Scalartest.hlsl
    clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
    clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
    clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/AST/ASTContext.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/lib/Sema/SemaModule.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Sema/SemaType.cpp
    clang/test/SemaHLSL/group_shared.hlsl
    clang/test/SemaHLSL/group_shared_202x.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0e6b3f51a5231..32d980eeb294d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13557,6 +13557,13 @@ def err_hlsl_rootsignature_entry: Error<
 def err_hlsl_operator_unsupported : Error<
   "the '%select{&|*|->}0' operator is unsupported in HLSL">;
 
+def warn_hlsl_groupshared_202x : Warning<
+  "support for groupshared parameter annotation not added until HLSL 202x">,
+  InGroup<HLSLAvailability>;
+def warn_hlsl_groupshared_inout : Warning<
+  "passing groupshared variable to a parameter annotated with inout. "
+  "See 'groupshared' parameter annotation added in 202x">,
+  InGroup<HLSLAvailability>;
 def err_hlsl_param_qualifier_mismatch :
   Error<"conflicting parameter qualifier %0 on parameter %1">;
 def err_hlsl_vector_compound_assignment_truncation : Error<

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index d9e9ae062e8d7..d8d2fc23974c2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8055,6 +8055,8 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) 
const {
 }
 
 QualType ASTContext::getAdjustedParameterType(QualType T) const {
+  if (getLangOpts().HLSL && T.getAddressSpace() == LangAS::hlsl_groupshared)
+    return getLValueReferenceType(T);
   if (getLangOpts().HLSL && T->isConstantArrayType())
     return getArrayParameterType(T);
   if (T->isArrayType() || T->isFunctionType())

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 53650e2083e44..b5e8e9ba62c21 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15862,7 +15862,11 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
SourceLocation StartLoc,
       // WebAssembly allows reference types as parameters. Funcref in 
particular
       // lives in a 
diff erent address space.
       !(T->isFunctionPointerType() &&
-        T.getAddressSpace() == LangAS::wasm_funcref)) {
+        T.getAddressSpace() == LangAS::wasm_funcref) &&
+      // HLSL allows function arguments to be qualified with an address space
+      // if the groupshared annotation is used.
+      !(getLangOpts().HLSL &&
+        T.getAddressSpace() == LangAS::hlsl_groupshared)) {
     Diag(NameLoc, diag::err_arg_with_address_space);
     New->setInvalidDecl();
   }

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1b7f41061061d..fba07876eb093 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7293,6 +7293,19 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 
const ParsedAttr &AL,
     return;
   }
 
+  if (S.getLangOpts().HLSL && isa<FunctionDecl>(D) &&
+      AL.getKind() == ParsedAttr::AT_NoInline) {
+    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+      for (const ParmVarDecl *PVD : FD->parameters()) {
+        if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
+          S.Diag(AL.getLoc(), diag::err_hlsl_attr_incompatible)
+              << "'noinline'" << "'groupshared' parameter";
+          return;
+        }
+      }
+    }
+  }
+
   // Check if argument population must delayed to after template instantiation.
   bool MustDelayArgs = MustDelayAttributeArguments(AL);
 

diff  --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 8cb684fd5ae3b..8fc3464ed3e0c 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -943,6 +943,18 @@ static bool checkExportedDecl(Sema &S, Decl *D, 
SourceLocation BlockStart) {
       D->setInvalidDecl();
       return false;
     }
+
+    if (isa<FunctionDecl>(D)) {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      for (const ParmVarDecl *PVD : FD->parameters()) {
+        if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
+          S.Diag(D->getBeginLoc(), diag::err_hlsl_attr_incompatible)
+              << "'export'" << "'groupshared' parameter";
+          D->setInvalidDecl();
+          return false;
+        }
+      }
+    }
   }
 
   //  C++20 [module.interface]p3:

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6cada8eff0107..f8ea462549136 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7474,8 +7474,13 @@ void Sema::AddOverloadCandidate(
       QualType ParamType = Proto->getParamType(ArgIdx);
       auto ParamABI = Proto->getExtParameterInfo(ArgIdx).getABI();
       if (ParamABI == ParameterABI::HLSLOut ||
-          ParamABI == ParameterABI::HLSLInOut)
+          ParamABI == ParameterABI::HLSLInOut) {
         ParamType = ParamType.getNonReferenceType();
+        if (ParamABI == ParameterABI::HLSLInOut &&
+            Args[ArgIdx]->getType().getAddressSpace() ==
+                LangAS::hlsl_groupshared)
+          Diag(Args[ArgIdx]->getBeginLoc(), diag::warn_hlsl_groupshared_inout);
+      }
       Candidate.Conversions[ConvIdx] = TryCopyInitialization(
           *this, Args[ArgIdx], ParamType, SuppressUserConversions,
           /*InOverloadResolution=*/true,

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e74c41517ecbf..972981d7c11fb 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -788,6 +788,18 @@ static void instantiateDependentHLSLParamModifierAttr(
   ParmVarDecl *NewParm = cast<ParmVarDecl>(New);
   NewParm->addAttr(Attr->clone(S.getASTContext()));
 
+  // If this is groupshared don't change the type because it will assert
+  // below. In this case we might have already produced an error but we
+  // must produce one here again because of all the ways templates can
+  // be used.
+  if (const auto *RT = NewParm->getType()->getAs<LValueReferenceType>()) {
+    if (RT->getPointeeType().getAddressSpace() == LangAS::hlsl_groupshared) {
+      S.Diag(Attr->getLoc(), diag::err_hlsl_attr_incompatible)
+          << Attr << "'groupshared'";
+      return;
+    }
+  }
+
   const Type *OldParmTy = cast<ParmVarDecl>(Old)->getType().getTypePtr();
   if (OldParmTy->isDependentType() && Attr->isAnyOut())
     NewParm->setType(S.HLSL().getInoutParameterType(NewParm->getType()));

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 6406ee06e757b..2187f7c16eba5 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9099,11 +9099,24 @@ static void processTypeAttrs(TypeProcessingState 
&state, QualType &type,
     case ParsedAttr::AT_OpenCLLocalAddressSpace:
     case ParsedAttr::AT_OpenCLConstantAddressSpace:
     case ParsedAttr::AT_OpenCLGenericAddressSpace:
-    case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
     case ParsedAttr::AT_AddressSpace:
       HandleAddressSpaceTypeAttribute(type, attr, state);
       attr.setUsedAsTypeAttr();
       break;
+    case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
+      HandleAddressSpaceTypeAttribute(type, attr, state);
+      if (state.getDeclarator().getContext() == DeclaratorContext::Prototype) {
+        if (state.getSema().getLangOpts().getHLSLVersion() <
+            LangOptions::HLSL_202x)
+          state.getSema().Diag(attr.getLoc(), 
diag::warn_hlsl_groupshared_202x);
+
+        // Note: we don't check for the usage of HLSLParamModifiers 
in/out/inout
+        // here because the check in the AT_HLSLParamModifier case is 
sufficient
+        // regardless of the order of groupshared or in/out/inout specified in
+        // the parameter. And checking there produces a better error message.
+      }
+      attr.setUsedAsTypeAttr();
+      break;
     OBJC_POINTER_TYPE_ATTRS_CASELIST:
       if (!handleObjCPointerTypeAttr(state, attr, type))
         distributeObjCPointerTypeAttr(state, attr, type);
@@ -9192,6 +9205,12 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
 
     case ParsedAttr::AT_HLSLParamModifier: {
       HandleHLSLParamModifierAttr(state, type, attr, state.getSema());
+      if (attrs.hasAttribute(ParsedAttr::AT_HLSLGroupSharedAddressSpace)) {
+        state.getSema().Diag(attr.getLoc(), diag::err_hlsl_attr_incompatible)
+            << attr << "'groupshared'";
+        attr.setInvalid();
+        return;
+      }
       attr.setUsedAsTypeAttr();
       break;
     }

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl
new file mode 100644
index 0000000000000..4989275e6ee6d
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.0-compute -std=hlsl202x -emit-llvm -disable-llvm-passes 
-hlsl-entry main -o - %s | FileCheck %s
+
+groupshared float4 SharedArr[64];
+
+// CHECK-LABEL: define hidden void @_Z2fnRA64_U3AS3Dv4_ff(ptr addrspace(3) 
noundef align 16 dereferenceable(1024) %Arr, float noundef nofpclass(nan inf) 
%F)
+// CHECK: [[ArrAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: [[FAddr:%.*]] = alloca float, align 4
+// CHECK: store ptr addrspace(3) %Arr, ptr [[ArrAddr]], align 4
+// CHECK: store float %F, ptr [[FAddr]], align 4
+// CHECK: [[A:%.*]] = load float, ptr [[FAddr]], align 4
+// CHECK: [[Splat:%.*]] = insertelement <1 x float> poison, float [[A]], i64 0
+// CHECK: [[B:%.*]] = shufflevector <1 x float> [[Splat]], <1 x float> poison, 
<4 x i32> zeroinitializer
+// CHECK: [[C:%.*]] = load ptr addrspace(3), ptr [[ArrAddr]], align 4, !align 
!3
+// CHECK: [[ArrIdx:%.*]] = getelementptr inbounds [64 x <4 x float>], ptr 
addrspace(3) [[C]], i32 0, i32 5
+// CHECK: store <4 x float> [[B]], ptr addrspace(3) [[ArrIdx]], align 16
+// CHECK: ret void
+void fn(groupshared float4 Arr[64], float F) {
+  Arr[5] = F.xxxx;
+}
+
+[numthreads(4,1,1)]
+void main() {
+  fn(SharedArr, 6.0);
+}

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
new file mode 100644
index 0000000000000..584ffeeaa646a
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-compute -std=hlsl202x -emit-llvm -disable-llvm-passes 
-hlsl-entry main -o - %s | FileCheck %s
+
+groupshared float4x4 SharedData;
+
+// CHECK-LABEL: define hidden void @_Z3fn1RU3AS3u11matrix_typeILm4ELm4EfE(ptr 
addrspace(3) noundef align 4 dereferenceable(64) %Sh)
+// CHECK: [[ShAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: store ptr addrspace(3) %Sh, ptr [[ShAddr]], align 4
+// CHECK: [[A:%.*]] = load ptr addrspace(3), ptr [[ShAddr]], align 4
+// CHECK: [[B:%.*]] = getelementptr <16 x float>, ptr addrspace(3) [[A]], i32 
0, i32 4
+// CHECK: store float 5.000000e+00, ptr addrspace(3) [[B]], align 4
+// CHECK: ret void
+void fn1(groupshared float4x4 Sh) {
+  Sh[0][1] = 5.0;
+}
+
+[numthreads(4,1,1)]
+void main(uint3 TID : SV_GroupThreadID) {
+  fn1(SharedData);
+}

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl
new file mode 100644
index 0000000000000..5576eed5b5043
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.0-compute -std=hlsl202x -emit-llvm -disable-llvm-passes 
-hlsl-entry main -o - %s | FileCheck %s
+
+// Verify we are calling the correct overloads
+void fn(groupshared float4 Arr[2]);
+void fn(inout float4 Arr[2]);
+
+void fn2(groupshared int4 Shared);
+void fn2(int4 Local);
+
+[numthreads(4,1,1)]
+void main() {
+  float4 Local[2] = {1.0.xxxx, 2.0.xxxx};
+// CHECK: call void @_Z2fnA2_Dv4_f
+  fn(Local);
+
+// CHECK: call void @_Z3fn2Dv4_i
+  fn2(11.xxxx);
+}
+
+// CHECK-LABEL: define hidden void @_Z2fnA2_Dv4_f(ptr noalias noundef align 16 
%Arr)
+void fn(inout float4 Arr[2]) {
+  Arr[1] = 5.0.xxxx;
+}
+
+// CHECK-LABEL: define hidden void @_Z3fn2Dv4_i(<4 x i32> noundef %Local) #0 {
+void fn2(int4 Local) {
+  int X = Local.y;
+}
+
+// CHECK-LABEL: define hidden void @_Z2fnRA2_U3AS3Dv4_f(ptr addrspace(3) 
noundef align 16 dereferenceable(32) %Arr)
+void fn(groupshared float4 Arr[2]) {
+  Arr[1] = 7.0.xxxx;
+}
+
+// CHECK-LABEL: define hidden void @_Z3fn2RU3AS3Dv4_i(ptr addrspace(3) noundef 
align 16 dereferenceable(16) %Shared)
+void fn2(groupshared int4 Shared) {
+  Shared.x = 10;
+}

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/Scalartest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/Scalartest.hlsl
new file mode 100644
index 0000000000000..02303e449dd76
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/Scalartest.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -finclude-default-header -fnative-half-type 
-fnative-int16-type -triple dxil-pc-shadermodel6.2-compute -std=hlsl202x 
-emit-llvm -disable-llvm-passes -hlsl-entry main -o - %s | FileCheck %s
+
+groupshared uint16_t SharedData;
+
+// CHECK-LABEL: define hidden void @_Z3fn1RU3AS3t(ptr addrspace(3) noundef 
align 2 dereferenceable(2) %Sh)
+// CHECK: [[ShAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: store ptr addrspace(3) %Sh, ptr [[ShAddr]], align 4
+// CHECK: [[A:%.*]] = load ptr addrspace(3), ptr [[ShAddr]], align 4
+// CHECK: store i16 5, ptr addrspace(3) [[A]], align 2
+// CHECK: ret void
+void fn1(groupshared uint16_t Sh) {
+  Sh = 5;
+}
+
+[numthreads(4, 1, 1)]
+void main(uint3 TID : SV_GroupThreadID) {
+  fn1(SharedData);
+}

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
new file mode 100644
index 0000000000000..863a6f14d445b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-compute -std=hlsl202x -emit-llvm -disable-llvm-passes 
-hlsl-entry main -o - %s | FileCheck %s
+
+// In the case the template type is specified the groupshared attribute is 
preserved in the type
+// CHECK-LABEL: define linkonce_odr hidden void @_Z4tfooIU3AS3Dv4_iEvT_S2_(ptr 
addrspace(3) noundef align 16 dereferenceable(16) %a, ptr addrspace(3) noundef 
align 16 dereferenceable(16) %b)
+// CHECK: [[AAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: [[BAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: store ptr addrspace(3) %a, ptr [[AAddr]], align 4
+// CHECK: store ptr addrspace(3) %b, ptr [[BAddr]], align 4
+// CHECK: [[C:%.*]] = load ptr addrspace(3), ptr [[BAddr]], align 4
+// CHECK: [[D:%.*]] = load <4 x i32>, ptr addrspace(3) [[C]], align 16
+// CHECK: [[E:%.*]] = load ptr addrspace(3), ptr [[AAddr]], align 4
+// CHECK: store <4 x i32> [[D]], ptr addrspace(3) [[E]], align 16
+// CHECK: ret void
+
+// In the case the template type is deduced the deduction is done on the non 
cv-qualified type (the address space is removed)
+// So the non groupshared version of the function is deduced
+// CHECK-LABEL: define linkonce_odr hidden void @_Z4tfooIDv4_iEvT_S1_(<4 x 
i32> noundef %a, <4 x i32> noundef %b)
+// CHECK: [[AAddr:%.*]] = alloca <4 x i32>, align 16
+// CHECK: [[BAddr:%.*]] = alloca <4 x i32>, align 16
+// CHECK: store <4 x i32> %a, ptr [[AAddr]], align 16
+// CHECK: store <4 x i32> %b, ptr [[BAddr]], align 16
+// CHECK: [[C:%.*]] = load <4 x i32>, ptr [[BAddr]], align 16
+// CHECK: store <4 x i32> [[C]], ptr [[AAddr]], align 16
+// CHECK: ret void
+template<typename T>
+void tfoo(T a, T b) {
+  a = b;
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void 
@_Z5tfoo2IDv4_iEvRU3AS3T_S3_(ptr addrspace(3) noundef align 16 
dereferenceable(16) %a, ptr addrspace(3) noundef align 16 dereferenceable(16) 
%b)
+// CHECK: [[AAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: [[BAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: store ptr addrspace(3) %a, ptr [[AAddr]], align 4
+// CHECK: store ptr addrspace(3) %b, ptr [[BAddr]], align 4
+// CHECK: [[Z:%.*]] = load ptr addrspace(3), ptr [[BAddr]], align 4
+// CHECK: [[Y:%.*]] = load <4 x i32>, ptr addrspace(3) [[Z]], align 16
+// CHECK: [[X:%.*]] = load ptr addrspace(3), ptr [[AAddr]], align 4
+// CHECK: store <4 x i32> [[Y]], ptr addrspace(3) [[X]], align 16
+// CHECK: ret void
+template<typename T>
+void tfoo2(groupshared T a, groupshared T b) {
+  a = b;
+}
+
+using ISF = groupshared int4;
+ISF SharedData1;
+ISF SharedData2;
+
+[numthreads(4, 1, 1)]
+void main(uint3 TID : SV_GroupThreadID) {
+  tfoo<ISF>(SharedData1, SharedData2);
+  tfoo(SharedData1, SharedData2);
+
+  tfoo2(SharedData1, SharedData2);
+}

diff  --git a/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl
new file mode 100644
index 0000000000000..e61f8d2cdf43b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-compute -std=hlsl202x -emit-llvm -disable-llvm-passes 
-hlsl-entry main -o - %s | FileCheck %s
+
+groupshared float4 SharedData;
+
+// CHECK-LABEL: define hidden void @_Z3fn1RU3AS3Dv4_f(ptr addrspace(3) noundef 
align 16 dereferenceable(16) %Sh)
+// CHECK: [[ShAddr:%.*]] = alloca ptr addrspace(3), align 4
+// CHECK: [[Tmp:%.*]] = alloca <1 x float>, align 4
+// CHECK: store ptr addrspace(3) %Sh, ptr [[ShAddr]], align 4
+// CHECK: store <1 x float> splat (float 5.000000e+00), ptr [[Tmp]], align 4
+// CHECK: [[A:%.*]] = load <1 x float>, ptr [[Tmp]], align 4
+// CHECK: [[B:%.*]] = shufflevector <1 x float> [[A]], <1 x float> poison, <4 
x i32> zeroinitializer
+// CHECK: [[C:%.*]] = load ptr addrspace(3), ptr [[ShAddr]], align 4
+// CHECK: store <4 x float> [[B]], ptr addrspace(3) [[C]], align 16
+// CHECK: ret void
+void fn1(groupshared float4 Sh) {
+  Sh = 5.0.xxxx;
+}
+
+[numthreads(4, 1, 1)]
+void main(uint3 TID : SV_GroupThreadID) {
+  fn1(SharedData);
+}

diff  --git a/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
new file mode 100644
index 0000000000000..83b4454c07c1e
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -std=hlsl202x -fnative-half-type -fnative-int16-type 
-verify -Wconversion %s
+
+groupshared uint16_t SharedData;
+
+void fn1(groupshared half Sh) {
+// expected-note@-1{{candidate function not viable: cannot bind reference in 
generic address space to object in address space 'groupshared' in 1st argument}}
+  Sh = 5;
+}
+
+template<typename T>
+void fnT(T A, T B) {
+// expected-note@-1{{candidate function template not viable: cannot bind 
reference in generic address space to object in address space 'groupshared' in 
1st argument}}
+  A = B;
+}
+
+template<typename T>
+void fnT2(groupshared T A, groupshared T B) {
+// expected-note@-1{{candidate function template not viable: cannot bind 
reference in generic address space to object in address space 'groupshared' in 
1st argument}}
+  A = B;
+}
+
+void fn2() {
+  fn1((half)SharedData);
+  // expected-error@-1{{no matching function for call to 'fn1'}}
+  // not sure why someone would do this but want to make sure templates do 
something sane
+  fnT<groupshared half>((half)SharedData, (half)SharedData);
+  // expected-error@-1{{no matching function for call to 'fnT'}}
+
+  fnT2<half>((half)SharedData, (half)SharedData);
+  // expected-error@-1{{no matching function for call to 'fnT2'}}
+}

diff  --git 
a/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
new file mode 100644
index 0000000000000..c120adb4a4fbc
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -std=hlsl202x -verify -Wconversion %s
+
+export void fn1(groupshared uint Sh) {
+// expected-error@-1{{'export' attribute is not compatible with 'groupshared' 
parameter attribute}}
+  Sh = 5;
+}
+
+__attribute__((noinline)) void fn2(groupshared uint Sh) {
+// expected-error@-1{{'noinline' attribute is not compatible with 
'groupshared' parameter attribute}}
+  Sh = 6;
+}
+
+template<typename T>
+void fn3(groupshared T A, groupshared T B) {
+  A = B;
+}
+
+export template void fn3<uint>(groupshared uint A, groupshared uint B);
+template __attribute__((noinline)) void fn3<float>(groupshared float A, 
groupshared float B);
+// expected-error@-1{{'noinline' attribute is not compatible with 
'groupshared' parameter attribute}}

diff  --git a/clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl
new file mode 100644
index 0000000000000..e8ab07b7d3a77
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -std=hlsl202x -verify -Wconversion %s
+
+groupshared uint SharedData;
+
+void fn1(inout uint Sh) {
+  Sh = 5;
+}
+
+void fn2(inout groupshared uint Sh);
+// expected-error@-1{{'inout' attribute is not compatible with 'groupshared' 
attribute}}
+void fn3(in groupshared uint Sh);
+// expected-error@-1{{'in' attribute is not compatible with 'groupshared' 
attribute}}
+void fn4(out groupshared uint Sh);
+// expected-error@-1{{'out' attribute is not compatible with 'groupshared' 
attribute}}
+void fn5(groupshared inout uint Sh);
+// expected-error@-1{{'inout' attribute is not compatible with 'groupshared' 
attribute}}
+void fn6(groupshared in uint Sh);
+// expected-error@-1{{'in' attribute is not compatible with 'groupshared' 
attribute}}
+void fn7(groupshared out uint Sh);
+// expected-error@-1{{'out' attribute is not compatible with 'groupshared' 
attribute}}
+
+
+template<typename T>
+void fn8(inout T A);
+// expected-note@-1{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'inout' attribute is not compatible with 'groupshared' 
attribute}}
+
+template void fn8<groupshared uint>(inout groupshared uint A);
+// expected-error@-1{{'inout' attribute is not compatible with 'groupshared' 
attribute}}
+// expected-error@-2{{explicit instantiation of 'fn8' does not refer to a 
function template, variable template, member function, member class, or static 
data member}}
+
+template<typename T>
+void fn9(out T A);
+// expected-note@-1{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'out' attribute is not compatible with 'groupshared' 
attribute}}
+
+template void fn9<groupshared uint>(out groupshared uint A);
+// expected-error@-1{{'out' attribute is not compatible with 'groupshared' 
attribute}}
+// expected-error@-2{{explicit instantiation of 'fn9' does not refer to a 
function template, variable template, member function, member class, or static 
data member}}
+
+template<typename T>
+void fn10(in T A);
+// expected-note@-1{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'in' attribute is not compatible with 'groupshared' 
attribute}}
+
+template void fn10<groupshared uint>(in groupshared uint A);
+// expected-error@-1{{'in' attribute is not compatible with 'groupshared' 
attribute}}
+// expected-error@-2{{explicit instantiation of 'fn10' does not refer to a 
function template, variable template, member function, member class, or static 
data member}}
+
+// expected-note@+2{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'inout' attribute is not compatible with 'groupshared' 
attribute}}
+template<typename T>
+void fn11(inout T A, inout T B) {
+  A = B;
+}
+// expected-note@+2{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'out' attribute is not compatible with 'groupshared' 
attribute}}
+template<typename T>
+void fn12(out T A, out T B) {
+  A = B;
+}
+
+// expected-note@+2{{candidate template ignored: substitution failure [with T 
= groupshared uint]: 'in' attribute is not compatible with 'groupshared' 
attribute}}
+template<typename T>
+void fn13(in T A, in T B) {
+  A = B;
+}
+
+template<typename T>
+T fn14(inout groupshared T A) {
+// expected-error@-1{{'inout' attribute is not compatible with 'groupshared' 
attribute}}
+  return A;
+}
+template<typename T>
+T fn15(in groupshared T A) {
+// expected-error@-1{{'in' attribute is not compatible with 'groupshared' 
attribute}}
+  return A;
+}
+template<typename T>
+T fn16(out groupshared T A) {
+// expected-error@-1{{'out' attribute is not compatible with 'groupshared' 
attribute}}
+  return A;
+}
+
+void fn0() {
+  fn1(SharedData);
+// expected-warning@-1{{passing groupshared variable to a parameter annotated 
with inout. See 'groupshared' parameter annotation added in 202x}}
+
+  fn11<groupshared uint>(SharedData, SharedData);
+// expected-error@-1{{no matching function for call to 'fn11'}}
+  fn12<groupshared uint>(SharedData, SharedData);
+// expected-error@-1{{no matching function for call to 'fn12'}}
+  fn13<groupshared uint>(SharedData, SharedData);
+// expected-error@-1{{no matching function for call to 'fn13'}}
+}

diff  --git 
a/clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl
new file mode 100644
index 0000000000000..2625b5769089b
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute 
-finclude-default-header -std=hlsl202x -fnative-half-type -fnative-int16-type 
-verify -Wconversion %s
+
+void fn1(groupshared half Sh) {
+// expected-note@-1{{candidate function not viable: cannot bind reference in 
generic address space to object in address space 'groupshared' in 1st argument}}
+  Sh = 5;
+}
+
+template<typename T>
+T fn2(groupshared T Sh) {
+// expected-note@-1{{candidate template ignored: cannot deduce a type for 'T' 
that would make 'groupshared 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/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
new file mode 100644
index 0000000000000..0fe2962c3b446
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -std=hlsl2018 -verify -Wconversion %s
+
+groupshared uint SharedData;
+
+void fn1(groupshared uint Sh) {
+// expected-warning@-1{{support for groupshared parameter annotation not added 
until HLSL 202x}}
+// expected-warning@*{{support for HLSL language version hlsl2018 is 
incomplete, recommend using hlsl202x instead}}
+  Sh = 5;
+}
+
+template<typename T>
+void fnT(T A, T B) {
+  A = B;
+}
+
+template void fnT<groupshared int>(groupshared int A, groupshared int B);
+// expected-warning@-1{{support for groupshared parameter annotation not added 
until HLSL 202x}}
+// expected-warning@-2{{support for groupshared parameter annotation not added 
until HLSL 202x}}
+
+void fn2() {
+  fn1(SharedData);
+}
+
+template<typename T>
+T fn3(groupshared T A) {
+// expected-warning@-1{{support for groupshared parameter annotation not added 
until HLSL 202x}}
+  return A;
+}

diff  --git a/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
new file mode 100644
index 0000000000000..e5db9bfc7a8a6
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -std=hlsl202x -fnative-half-type -fnative-int16-type 
-verify -Wconversion %s
+
+groupshared uint16_t SharedData;
+
+void fn1(groupshared half Sh) {
+// expected-note@-1{{candidate function not viable: no known conversion from 
'groupshared uint16_t' (aka 'groupshared unsigned short') to 'groupshared half 
&' for 1st argument}}
+  Sh = 5;
+}
+
+template<typename T>
+void fnT(T A, T B) {
+// expected-note@-1{{candidate function template not viable: no known 
conversion from 'groupshared uint16_t' (aka 'groupshared unsigned short') to 
'groupshared half &' for 1st argument}}
+  A = B;
+}
+
+template<typename T>
+T fn3(groupshared T A) {
+// expected-note@-1{{candidate function template not viable: no known 
conversion from 'groupshared uint16_t' (aka 'groupshared unsigned short') to 
'groupshared half &' for 1st argument}}
+  return A;
+}
+
+void fn2() {
+  fn1(SharedData);
+  // expected-error@-1{{no matching function for call to 'fn1'}}
+  // not sure why anyone would do thats but just making sure templates are sane
+  fnT<groupshared half>(SharedData, SharedData);
+  // expected-error@-1{{no matching function for call to 'fnT'}}
+  fn3<half>(SharedData);
+  // expected-error@-1{{no matching function for call to 'fn3'}}
+}

diff  --git a/clang/test/SemaHLSL/group_shared.hlsl 
b/clang/test/SemaHLSL/group_shared.hlsl
index 0293ddd15eeb9..4df6cf73c4fc0 100644
--- a/clang/test/SemaHLSL/group_shared.hlsl
+++ b/clang/test/SemaHLSL/group_shared.hlsl
@@ -48,12 +48,7 @@
     static groupshared float g;
   };
 
-  // expected-error@+1 {{parameter may not be qualified with an address space}}
-  float foo2(groupshared float a) {
-    return a;
-  }
-
-// expected-note@+2 {{parameter may not be qualified with an address space}}
+// expected-note@+2 {{candidate template ignored: substitution failure [with T 
= GSF]}}
 template<typename T>
   T tfoo(T t) {
      return t;
@@ -67,8 +62,7 @@ template<typename T>
 // it is caused by return type check is after pointer check which is 
acceptable.
 // expected-error@+1 {{pointers are unsupported in HLSL}}
 groupshared void (*fp)();
-// expected-error@+2 {{pointers are unsupported in HLSL}}
-// expected-error@+1 {{parameter may not be qualified with an address space}}
+// expected-error@+1 {{pointers are unsupported in HLSL}}
 void (*fp2)(groupshared float);
 // NOTE: HLSL not support trailing return types.
 // expected-warning@#func{{'auto' type specifier is a HLSL 202y extension}}
@@ -102,5 +96,4 @@ _Static_assert(S3<groupshared float>::value, "");
 
 // Can you overload based on the qualifier?
 void func(float f) {}
-// expected-error@+1 {{parameter may not be qualified with an address space}}
 void func(groupshared float f) {}

diff  --git a/clang/test/SemaHLSL/group_shared_202x.hlsl 
b/clang/test/SemaHLSL/group_shared_202x.hlsl
index 7ebc717384e94..b9e84202e637e 100644
--- a/clang/test/SemaHLSL/group_shared_202x.hlsl
+++ b/clang/test/SemaHLSL/group_shared_202x.hlsl
@@ -11,11 +11,8 @@
 // expected-error@#func {{return type cannot be qualified with address space}}
 auto func() -> groupshared void; // #func
 
-// expected-error@#func_gs {{parameter may not be qualified with an address 
space}}
 auto func(float groupshared) -> void; // #func_gs
 
-
-// expected-error@#l {{parameter may not be qualified with an address space}}
 // expected-warning@#l {{lambdas are a clang HLSL extension}}
 auto l = [](groupshared float ) {}; // #l
 


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to