https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/181886

>From 7ef759df97b3035569c72feb000c4fa18a583041 Mon Sep 17 00:00:00 2001
From: Sarah Spall <[email protected]>
Date: Tue, 17 Feb 2026 10:53:18 -0800
Subject: [PATCH 1/2] groupshared arg support mostly

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  7 ++
 clang/lib/AST/ASTContext.cpp                  |  2 +
 clang/lib/Sema/SemaDecl.cpp                   |  6 +-
 clang/lib/Sema/SemaDeclAttr.cpp               | 13 ++++
 clang/lib/Sema/SemaModule.cpp                 | 12 +++
 clang/lib/Sema/SemaOverload.cpp               |  7 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 12 +++
 clang/lib/Sema/SemaType.cpp                   | 21 +++++-
 .../CodeGenHLSL/groupsharedArgs/ArrTest.hlsl  | 24 ++++++
 .../groupsharedArgs/MatrixTest.hlsl           | 20 +++++
 .../groupsharedArgs/Overloads.hlsl            | 38 ++++++++++
 .../groupsharedArgs/Scalartest.hlsl           | 18 +++++
 .../groupsharedArgs/TemplateTest.hlsl         | 38 ++++++++++
 .../groupsharedArgs/VectorTest.hlsl           | 22 ++++++
 .../groupsharedArgs/ExplicitCast.hlsl         | 13 ++++
 .../groupsharedArgs/ExportNoInlineTest.hlsl   | 19 +++++
 .../Language/groupsharedArgs/InOut.hlsl       | 74 +++++++++++++++++++
 .../groupsharedArgs/NotGroupSharedTest.hlsl   | 13 ++++
 .../groupsharedArgs/Pre202xWarning.hlsl       | 13 ++++
 .../Language/groupsharedArgs/ScalarTest.hlsl  | 13 ++++
 clang/test/SemaHLSL/group_shared.hlsl         | 11 +--
 clang/test/SemaHLSL/group_shared_202x.hlsl    |  3 -
 22 files changed, 384 insertions(+), 15 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/Scalartest.hlsl
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
 create mode 100644 clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl
 create mode 100644 
clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
 create mode 100644 
clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
 create mode 100644 clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl
 create mode 100644 
clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl
 create mode 100644 
clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
 create mode 100644 clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 85a023435ba23..377abf8d2c2ae 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13438,6 +13438,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 3f63420cae91e..43f3a4278fc39 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7949,6 +7949,8 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) 
const {
 }
 
 QualType ASTContext::getAdjustedParameterType(QualType T) const {
+  if (getLangOpts().HLSL && T.getAddressSpace() != LangAS::Default)
+    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 4dfde4bf8cedf..32adfe393464d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15841,7 +15841,11 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
SourceLocation StartLoc,
       // WebAssembly allows reference types as parameters. Funcref in 
particular
       // lives in a different 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 5dbff18fff7a9..64fd8811136e8 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7262,6 +7262,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 81edf966de9e7..a80609d8db119 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7357,8 +7357,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..780aa766118fa 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()));
 
+  // we might have already produced an error
+  // just don't change the type here because it will assert
+  // also need to produce an error 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 a6d4b989cae3d..62aab39ab268d 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8955,11 +8955,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);
@@ -9044,6 +9057,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..b33e2f2d71185
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
@@ -0,0 +1,20 @@
+// 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:%.*]] = load <16 x float>, ptr addrspace(3) [[A]], align 4
+// CHECK: [[Matins:%.*]] = insertelement <16 x float> [[B]], float 
5.000000e+00, i32 4
+// CHECK: store <16 x float> [[Matins]], ptr addrspace(3) [[A]], 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..6989abadf4ca9
--- /dev/null
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
@@ -0,0 +1,38 @@
+// 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;
+}
+
+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);
+}
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..86e24f2aee550
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
@@ -0,0 +1,13 @@
+// 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;
+}
+
+void fn2() {
+  fn1((half)SharedData);
+  // expected-error@-1{{no matching function for call to 'fn1'}}
+}
diff --git 
a/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
new file mode 100644
index 0000000000000..bdac2dc37ca20
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
@@ -0,0 +1,19 @@
+// 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(T A, T B) {
+  A = B;
+}
+
+//export template void fn3<groupshared uint3>(groupshared uint3 A, groupshared 
uint3 B);
+// //expected-error@-1{{'export' 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..bf57b4b786260
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/InOut.hlsl
@@ -0,0 +1,74 @@
+// 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;
+}
+
+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..4929f7bdce51a
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/NotGroupSharedTest.hlsl
@@ -0,0 +1,13 @@
+// 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;
+}
+
+[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'}}
+}
diff --git a/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
new file mode 100644
index 0000000000000..ba9cee2611dcf
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
@@ -0,0 +1,13 @@
+// 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;
+}
+
+void fn2() {
+  fn1(SharedData);
+}
diff --git a/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
new file mode 100644
index 0000000000000..b9f093c7cc825
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
@@ -0,0 +1,13 @@
+// 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;
+}
+
+void fn2() {
+  fn1(SharedData);
+  // expected-error@-1{{no matching function for call to 'fn1'}}
+}
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
 

>From b507cd7ee3bdf167d44120c0f44450aa42978e6a Mon Sep 17 00:00:00 2001
From: Sarah Spall <[email protected]>
Date: Fri, 20 Feb 2026 08:50:16 -0800
Subject: [PATCH 2/2] self review

---
 clang/lib/AST/ASTContext.cpp                             | 2 +-
 clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl   | 5 ++---
 .../SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl  | 9 +++++++++
 .../Language/groupsharedArgs/ExportNoInlineTest.hlsl     | 3 ---
 .../Language/groupsharedArgs/Pre202xWarning.hlsl         | 9 +++++++++
 .../SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl    | 9 +++++++++
 6 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 43f3a4278fc39..eb6e028989ad5 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7949,7 +7949,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) 
const {
 }
 
 QualType ASTContext::getAdjustedParameterType(QualType T) const {
-  if (getLangOpts().HLSL && T.getAddressSpace() != LangAS::Default)
+  if (getLangOpts().HLSL && T.getAddressSpace() == LangAS::hlsl_groupshared)
     return getLValueReferenceType(T);
   if (getLangOpts().HLSL && T->isConstantArrayType())
     return getArrayParameterType(T);
diff --git a/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl 
b/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
index b33e2f2d71185..584ffeeaa646a 100644
--- a/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
+++ b/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl
@@ -6,9 +6,8 @@ groupshared float4x4 SharedData;
 // 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:%.*]] = load <16 x float>, ptr addrspace(3) [[A]], align 4
-// CHECK: [[Matins:%.*]] = insertelement <16 x float> [[B]], float 
5.000000e+00, i32 4
-// CHECK: store <16 x float> [[Matins]], ptr addrspace(3) [[A]], 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;
diff --git a/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
index 86e24f2aee550..bd125f8eb639b 100644
--- a/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExplicitCast.hlsl
@@ -7,7 +7,16 @@ void fn1(groupshared half Sh) {
   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;
+}
+
 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'}}
 }
diff --git 
a/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
index bdac2dc37ca20..d29638b7f3c25 100644
--- a/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ExportNoInlineTest.hlsl
@@ -14,6 +14,3 @@ template<typename T>
 void fn3(T A, T B) {
   A = B;
 }
-
-//export template void fn3<groupshared uint3>(groupshared uint3 A, groupshared 
uint3 B);
-// //expected-error@-1{{'export' attribute is not compatible with 
'groupshared' parameter attribute}}
diff --git a/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
index ba9cee2611dcf..24b2bdd3dbe76 100644
--- a/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/Pre202xWarning.hlsl
@@ -8,6 +8,15 @@ void fn1(groupshared uint Sh) {
   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);
 }
diff --git a/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl 
b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
index b9f093c7cc825..7597004f62eeb 100644
--- a/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
+++ b/clang/test/SemaHLSL/Language/groupsharedArgs/ScalarTest.hlsl
@@ -7,7 +7,16 @@ void fn1(groupshared half Sh) {
   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;
+}
+
 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'}}
 }

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

Reply via email to