[clang] 7e04c0a - [HLSL] Add groupshare address space.

Xiang Li via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 20 09:29:14 PDT 2022


Author: Xiang Li
Date: 2022-10-20T09:29:09-07:00
New Revision: 7e04c0ad632527df0a4c4d34a6ac6ec6a3888dfe

URL: https://github.com/llvm/llvm-project/commit/7e04c0ad632527df0a4c4d34a6ac6ec6a3888dfe
DIFF: https://github.com/llvm/llvm-project/commit/7e04c0ad632527df0a4c4d34a6ac6ec6a3888dfe.diff

LOG: [HLSL] Add groupshare address space.

Added keyword, LangAS and TypeAttrbute for groupshared.

Tanslate it to LangAS with asHLSLLangAS.

Make sure it translated into address space 3 for DirectX target.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D135060

Added: 
    clang/test/AST/HLSL/group_shared.hlsl
    clang/test/CodeGenHLSL/group_shared.hlsl
    clang/test/ParserHLSL/group_shared.hlsl
    clang/test/ParserHLSL/group_shared_202x.hlsl
    clang/test/SemaHLSL/group_shared.hlsl
    clang/test/SemaHLSL/group_shared_202x.hlsl

Modified: 
    clang/include/clang/Basic/AddressSpaces.h
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Basic/TokenKinds.def
    clang/include/clang/Parse/Parser.h
    clang/include/clang/Sema/ParsedAttr.h
    clang/lib/AST/ASTContext.cpp
    clang/lib/AST/TypePrinter.cpp
    clang/lib/Basic/Targets/AMDGPU.cpp
    clang/lib/Basic/Targets/DirectX.h
    clang/lib/Basic/Targets/NVPTX.h
    clang/lib/Basic/Targets/SPIR.h
    clang/lib/Basic/Targets/TCE.h
    clang/lib/Basic/Targets/X86.h
    clang/lib/Parse/ParseDecl.cpp
    clang/lib/Parse/ParseExprCXX.cpp
    clang/lib/Parse/ParseTentative.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/SemaType.cpp
    clang/test/Parser/opencl-cxx-keywords.cl
    clang/test/SemaOpenCL/address-spaces.cl
    clang/test/SemaOpenCL/invalid-kernel.cl
    clang/test/SemaTemplate/address_space-dependent.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index 99bb67fd26d1..2f2c5d5826bc 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -56,6 +56,9 @@ enum class LangAS : unsigned {
   ptr32_uptr,
   ptr64,
 
+  // HLSL specific address spaces.
+  hlsl_groupshared,
+
   // This denotes the count of language-specific address spaces and also
   // the offset added to the target-specific address spaces, which are usually
   // specified by address space attributes __attribute__(address_space(n))).

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 58ac67e92588..16cf932c3760 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4065,6 +4065,12 @@ def HLSLResource : InheritableAttr {
   let Documentation = [InternalOnly];
 }
 
+def HLSLGroupSharedAddressSpace : TypeAttr {
+  let Spellings = [Keyword<"groupshared">];
+  let Subjects = SubjectList<[Var]>;
+  let Documentation = [HLSLGroupSharedAddressSpaceDocs];
+}
+
 def RandomizeLayout : InheritableAttr {
   let Spellings = [GCC<"randomize_layout">];
   let Subjects = SubjectList<[Record]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 484052f4db8a..3b441e757fae 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -6633,6 +6633,22 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo
   }];
 }
 
+def HLSLGroupSharedAddressSpaceDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+HLSL enables threads of a compute shader to exchange values via shared memory.
+HLSL provides barrier primitives such as GroupMemoryBarrierWithGroupSync,
+and so on to ensure the correct ordering of reads and writes to shared memory
+in the shader and to avoid data races.
+Here's an example to declare a groupshared variable.
+.. code-block:: c++
+
+  groupshared GSData data[5*5*1];
+
+The full documentation is available here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-syntax#group-shared
+  }];
+}
+
 def AnnotateTypeDocs : Documentation {
   let Category = DocCatType;
   let Heading = "annotate_type";

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1ef1f23e8c87..0396d6fae26a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10301,8 +10301,8 @@ def err_reference_pipe_type : Error <
 def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
 def err_opencl_kernel_attr :
   Error<"attribute %0 can only be applied to an OpenCL kernel function">;
-def err_opencl_return_value_with_address_space : Error<
-  "return value cannot be qualified with address space">;
+def err_return_value_with_address_space : Error<
+  "return type cannot be qualified with address space">;
 def err_opencl_constant_no_init : Error<
   "variable in constant address space must be initialized">;
 def err_opencl_atomic_init: Error<

diff  --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index dbff0412a045..96feae991ccb 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -616,6 +616,7 @@ KEYWORD(__noinline__                , KEYCUDA)
 // HLSL keywords.
 KEYWORD(cbuffer                     , KEYHLSL)
 KEYWORD(tbuffer                     , KEYHLSL)
+KEYWORD(groupshared                 , KEYHLSL)
 
 // OpenMP Type Traits
 UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d70f36daa891..ed92dbee5549 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2933,6 +2933,8 @@ class Parser : public CodeCompletionHandler {
   void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
   void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
   void ParseCUDAFunctionAttributes(ParsedAttributes &attrs);
+  bool isHLSLQualifier(const Token &Tok) const;
+  void ParseHLSLQualifiers(ParsedAttributes &Attrs);
 
   VersionTuple ParseVersionTuple(SourceRange &Range);
   void ParseAvailabilityAttribute(IdentifierInfo &Availability,

diff  --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 8ed89d3f1059..9ec0ea0d1981 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -712,6 +712,17 @@ class ParsedAttr final
     }
   }
 
+  /// If this is an HLSL address space attribute, returns its representation
+  /// in LangAS, otherwise returns default address space.
+  LangAS asHLSLLangAS() const {
+    switch (getParsedKind()) {
+    case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
+      return LangAS::hlsl_groupshared;
+    default:
+      return LangAS::Default;
+    }
+  }
+
   AttributeCommonInfo::Kind getKind() const {
     return AttributeCommonInfo::Kind(Info.AttrKind);
   }

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 9130bf3bb957..3716a76a85a2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -949,7 +949,8 @@ static const LangASMap *getAddressSpaceMap(const TargetInfo &T,
         0,  // sycl_private
         10, // ptr32_sptr
         11, // ptr32_uptr
-        12  // ptr64
+        12, // ptr64
+        13, // hlsl_groupshared
     };
     return &FakeAddrSpaceMap;
   } else {

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d0a7ce761ee9..463db3332adf 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1740,6 +1740,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
   case attr::OpenCLLocalAddressSpace:
   case attr::OpenCLConstantAddressSpace:
   case attr::OpenCLGenericAddressSpace:
+  case attr::HLSLGroupSharedAddressSpace:
     // FIXME: Update printAttributedBefore to print these once we generate
     // AttributedType nodes for them.
     break;
@@ -2235,6 +2236,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
     return "__uptr __ptr32";
   case LangAS::ptr64:
     return "__ptr64";
+  case LangAS::hlsl_groupshared:
+    return "groupshared";
   default:
     return std::to_string(toTargetAddressSpace(AS));
   }

diff  --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp
index 1c42bbec837c..cf16c320580a 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -55,7 +55,8 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
     Private,  // sycl_private
     Generic,  // ptr32_sptr
     Generic,  // ptr32_uptr
-    Generic   // ptr64
+    Generic,  // ptr64
+    Generic,  // hlsl_groupshared
 };
 
 const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
@@ -71,14 +72,15 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
     Constant, // cuda_constant
     Local,    // cuda_shared
     // SYCL address space values for this map are dummy
-    Generic,  // sycl_global
-    Generic,  // sycl_global_device
-    Generic,  // sycl_global_host
-    Generic,  // sycl_local
-    Generic,  // sycl_private
-    Generic,  // ptr32_sptr
-    Generic,  // ptr32_uptr
-    Generic   // ptr64
+    Generic, // sycl_global
+    Generic, // sycl_global_device
+    Generic, // sycl_global_host
+    Generic, // sycl_local
+    Generic, // sycl_private
+    Generic, // ptr32_sptr
+    Generic, // ptr32_uptr
+    Generic, // ptr64
+    Generic, // hlsl_groupshared
 
 };
 } // namespace targets

diff  --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 785104373e0a..548accf5f349 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -40,7 +40,8 @@ static const unsigned DirectXAddrSpaceMap[] = {
     0, // sycl_private
     0, // ptr32_sptr
     0, // ptr32_uptr
-    0  // ptr64
+    0, // ptr64
+    3, // hlsl_groupshared
 };
 
 class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {

diff  --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 7909bd07843e..69e399901c5c 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -42,7 +42,8 @@ static const unsigned NVPTXAddrSpaceMap[] = {
     0, // sycl_private
     0, // ptr32_sptr
     0, // ptr32_uptr
-    0  // ptr64
+    0, // ptr64
+    0, // hlsl_groupshared
 };
 
 /// The DWARF address class. Taken from

diff  --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 08c49f018ac7..655e9d60f4a1 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -42,7 +42,8 @@ static const unsigned SPIRDefIsPrivMap[] = {
     0, // sycl_private
     0, // ptr32_sptr
     0, // ptr32_uptr
-    0  // ptr64
+    0, // ptr64
+    0, // hlsl_groupshared
 };
 
 // Used by both the SPIR and SPIR-V targets.
@@ -71,7 +72,8 @@ static const unsigned SPIRDefIsGenMap[] = {
     0, // sycl_private
     0, // ptr32_sptr
     0, // ptr32_uptr
-    0  // ptr64
+    0, // ptr64
+    0, // hlsl_groupshared
 };
 
 // Base class for SPIR and SPIR-V target info.

diff  --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index 251b4d4b56f7..fbd0c30de3eb 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -50,6 +50,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
     0, // ptr32_sptr
     0, // ptr32_uptr
     0, // ptr64
+    0, // hlsl_groupshared
 };
 
 class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {

diff  --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 1feb32e66f78..cb1c186a4ad5 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -43,7 +43,8 @@ static const unsigned X86AddrSpaceMap[] = {
     0,   // sycl_private
     270, // ptr32_sptr
     271, // ptr32_uptr
-    272  // ptr64
+    272, // ptr64
+    0,   // hlsl_groupshared
 };
 
 // X86 target abstract base class; x86-32 and x86-64 are very close, so

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index e15a6ffa8d68..fd3589846a3d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -914,6 +914,17 @@ void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {
                ParsedAttr::AS_Keyword);
 }
 
+bool Parser::isHLSLQualifier(const Token &Tok) const {
+  return Tok.is(tok::kw_groupshared);
+}
+
+void Parser::ParseHLSLQualifiers(ParsedAttributes &Attrs) {
+  IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+  SourceLocation AttrNameLoc = ConsumeToken();
+  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+               ParsedAttr::AS_Keyword);
+}
+
 void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
   // Treat these like attributes, even though they're type specifiers.
   while (true) {
@@ -4329,6 +4340,11 @@ void Parser::ParseDeclarationSpecifiers(
       ParseOpenCLQualifiers(DS.getAttributes());
       break;
 
+    case tok::kw_groupshared:
+      // NOTE: ParseHLSLQualifiers will consume the qualifier token.
+      ParseHLSLQualifiers(DS.getAttributes());
+      continue;
+
     case tok::less:
       // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
       // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
@@ -5352,6 +5368,8 @@ bool Parser::isTypeSpecifierQualifier() {
   case tok::kw___read_only:
   case tok::kw___read_write:
   case tok::kw___write_only:
+
+  case tok::kw_groupshared:
     return true;
 
   case tok::kw_private:
@@ -5594,6 +5612,7 @@ bool Parser::isDeclarationSpecifier(
 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
 #include "clang/Basic/OpenCLImageTypes.def"
 
+  case tok::kw_groupshared:
     return true;
 
   case tok::kw_private:
@@ -5821,6 +5840,11 @@ void Parser::ParseTypeQualifierListOpt(
       ParseOpenCLQualifiers(DS.getAttributes());
       break;
 
+    case tok::kw_groupshared:
+      // NOTE: ParseHLSLQualifiers will consume the qualifier token.
+      ParseHLSLQualifiers(DS.getAttributes());
+      continue;
+
     case tok::kw___unaligned:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,
                                  getLangOpts());

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e77e6a1f2f7c..e34bd8d7bca4 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1474,7 +1474,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                          tok::kw_constexpr, tok::kw_consteval, tok::kw_static,
                          tok::kw___private, tok::kw___global, tok::kw___local,
                          tok::kw___constant, tok::kw___generic,
-                         tok::kw_requires, tok::kw_noexcept) ||
+                         tok::kw_groupshared, tok::kw_requires,
+                         tok::kw_noexcept) ||
              (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
     if (!getLangOpts().CPlusPlus2b)
       // It's common to forget that one needs '()' before 'mutable', an

diff  --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 90b281862d09..ca1602e63843 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1423,6 +1423,9 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
     // OpenCL pipe
   case tok::kw_pipe:
 
+    // HLSL address space qualifiers
+  case tok::kw_groupshared:
+
     // GNU
   case tok::kw_restrict:
   case tok::kw__Complex:

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 33be49c7bde9..3f555a31d9d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10103,8 +10103,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     // type declaration will generate a compilation error.
     LangAS AddressSpace = NewFD->getReturnType().getAddressSpace();
     if (AddressSpace != LangAS::Default) {
-      Diag(NewFD->getLocation(),
-           diag::err_opencl_return_value_with_address_space);
+      Diag(NewFD->getLocation(), diag::err_return_value_with_address_space);
       NewFD->setInvalidDecl();
     }
   }
@@ -10129,6 +10128,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
           NewFD->addAttr(Attr);
       }
     }
+    // HLSL does not support specifying an address space on a function return
+    // type.
+    LangAS AddressSpace = NewFD->getReturnType().getAddressSpace();
+    if (AddressSpace != LangAS::Default) {
+      Diag(NewFD->getLocation(), diag::err_return_value_with_address_space);
+      NewFD->setInvalidDecl();
+    }
   }
 
   if (!getLangOpts().CPlusPlus) {

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f2ec96955975..2143b811668a 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -971,6 +971,18 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
 
     ExplicitResultType = FTI.hasTrailingReturnType();
 
+    if (ExplicitResultType && getLangOpts().HLSL) {
+      QualType RetTy = FTI.getTrailingReturnType().get();
+      if (!RetTy.isNull()) {
+        // HLSL does not support specifying an address space on a lambda return
+        // type.
+        LangAS AddressSpace = RetTy.getAddressSpace();
+        if (AddressSpace != LangAS::Default)
+          Diag(FTI.getTrailingReturnTypeLoc(),
+               diag::err_return_value_with_address_space);
+      }
+    }
+
     if (FTIHasNonVoidParameters(FTI)) {
       Params.reserve(FTI.NumParams);
       for (unsigned i = 0, e = FTI.NumParams; i != e; ++i)

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f49deaf80fbc..c414120e0b83 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2896,6 +2896,8 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
   if (T.isVolatileQualified() && getLangOpts().CPlusPlus20)
     Diag(Loc, diag::warn_deprecated_volatile_return) << T;
 
+  if (T.getAddressSpace() != LangAS::Default && getLangOpts().HLSL)
+    return true;
   return false;
 }
 
@@ -6773,6 +6775,8 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
     // The keyword-based type attributes imply which address space to use.
     ASIdx = S.getLangOpts().SYCLIsDevice ? Attr.asSYCLLangAS()
                                          : Attr.asOpenCLLangAS();
+    if (S.getLangOpts().HLSL)
+      ASIdx = Attr.asHLSLLangAS();
 
     if (ASIdx == LangAS::Default)
       llvm_unreachable("Invalid address space");
@@ -8386,6 +8390,7 @@ 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();

diff  --git a/clang/test/AST/HLSL/group_shared.hlsl b/clang/test/AST/HLSL/group_shared.hlsl
new file mode 100644
index 000000000000..fb8a07626c66
--- /dev/null
+++ b/clang/test/AST/HLSL/group_shared.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s
+
+//CHECK:VarDecl 0x[[A:[0-9a-f]+]] <{{.*}} col:24> col:20 used a 'groupshared float[10]'
+ groupshared float a[10];
+
+// CHECK:FunctionDecl 0x{{[0-9a-f]+}} <{{.*}}> line:[[@LINE+2]]:7 main 'void ()'
+ [numthreads(8,8,1)]
+ void main() {
+// CHECK:BinaryOperator 0x{{[0-9a-f]+}} <{{.*}}> 'groupshared float' lvalue '='
+// CHECK:ArraySubscriptExpr 0x{{[0-9a-f]+}} <col:4, col:7> 'groupshared float' lvalue
+// CHECK:ImplicitCastExpr 0x{{[0-9a-f]+}} <col:4> 'groupshared float *' <ArrayToPointerDecay>
+// CHECK:DeclRefExpr 0x{{[0-9a-f]+}} <col:4> 'groupshared float[10]' lvalue Var 0x[[A]] 'a' 'groupshared float[10]'
+// CHECK:IntegerLiteral 0x{{[0-9a-f]+}} <col:6> 'int' 0
+// CHECK:ImplicitCastExpr 0x{{[0-9a-f]+}} <col:11> 'float' <IntegralToFloating>
+// CHECK:IntegerLiteral 0x{{[0-9a-f]+}} <col:11> 'int' 1
+   a[0] = 1;
+ }
+
+
+// CHECK:HLSLNumThreadsAttr 0x{{[0-9a-f]+}} <{{.*}}> 8 8 1

diff  --git a/clang/test/CodeGenHLSL/group_shared.hlsl b/clang/test/CodeGenHLSL/group_shared.hlsl
new file mode 100644
index 000000000000..48d14b2506fb
--- /dev/null
+++ b/clang/test/CodeGenHLSL/group_shared.hlsl
@@ -0,0 +1,15 @@
+
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+// Make sure groupshared translated into address space 3.
+// CHECK:@"?a@@3PAMA" = addrspace(3) global [10 x float]
+
+ groupshared float a[10];
+
+ [numthreads(8,8,1)]
+ void main() {
+   a[0] = 1;
+ }
+

diff  --git a/clang/test/Parser/opencl-cxx-keywords.cl b/clang/test/Parser/opencl-cxx-keywords.cl
index ddc84536f20a..365187a9f1c0 100644
--- a/clang/test/Parser/opencl-cxx-keywords.cl
+++ b/clang/test/Parser/opencl-cxx-keywords.cl
@@ -49,4 +49,4 @@ private ::A i; //expected-error{{program scope variable must reside in global or
 
 void foo(private int i);
 
-private int bar(); //expected-error{{return value cannot be qualified with address space}}
+private int bar(); //expected-error{{return type cannot be qualified with address space}}

diff  --git a/clang/test/ParserHLSL/group_shared.hlsl b/clang/test/ParserHLSL/group_shared.hlsl
new file mode 100644
index 000000000000..d516f7008607
--- /dev/null
+++ b/clang/test/ParserHLSL/group_shared.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify
+extern groupshared float f;
+extern float groupshared f; // Ok, redeclaration?
+
+
+// NOTE:lambda is not enabled except for hlsl202x.
+// expected-error at +2 {{expected expression}}
+// expected-warning at +1 {{'auto' type specifier is a C++11 extension}}
+auto l = []() groupshared  {};
+
+
+// NOTE: remove this error once [[]] attribute is supported except for hlsl202x.
+// expected-error at +1 {{expected expression}}
+float groupshared [[]] i = 12;
+
+float groupshared const i2 = 12;

diff  --git a/clang/test/ParserHLSL/group_shared_202x.hlsl b/clang/test/ParserHLSL/group_shared_202x.hlsl
new file mode 100644
index 000000000000..517ed3949a13
--- /dev/null
+++ b/clang/test/ParserHLSL/group_shared_202x.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -std=hlsl202x  -o - -fsyntax-only %s -verify
+extern groupshared float f;
+extern float groupshared f; // Ok, redeclaration?
+
+// expected-error at +1 {{return type cannot be qualified with address space}}
+auto l = []() -> groupshared void {};
+// expected-error at +1 {{expected a type}}
+auto l2 = []() -> groupshared {};
+
+float groupshared [[]] i = 12;
+
+float groupshared const i2 = 12;
+
+void foo() {
+    l();
+}
+
+extern groupshared float f;
+const float cf = f;
+// expected-error at +1 {{'auto' return without trailing return type; deduced return types are a C++14 extension}}
+auto func() {
+  return f;
+}
+
+void other() {
+  // NOTE: groupshared and const are stripped off thanks to lvalue to rvalue conversions and we deduce float for the return type.
+  auto l = [&]() { return f; };
+  auto l2 = [&]() { return cf; };
+}

diff  --git a/clang/test/SemaHLSL/group_shared.hlsl b/clang/test/SemaHLSL/group_shared.hlsl
new file mode 100644
index 000000000000..67450fe533eb
--- /dev/null
+++ b/clang/test/SemaHLSL/group_shared.hlsl
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify
+
+ groupshared float a[10];
+
+ [numthreads(8,8,1)]
+ void main() {
+   a[0] = 1;
+   // expected-error at +1 {{automatic variable qualified with an address space}}
+   groupshared float b;
+ }
+
+// expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+// expected-error at +1 {{return type cannot be qualified with address space}}
+ groupshared float foo() {
+  static groupshared float foo0;
+    return 1;
+ }
+// expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+// expected-error at +1 {{return type cannot be qualified with address space}}
+  groupshared void bar() {
+    extern groupshared float bar0;
+  }
+// expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+// expected-error at +1 {{return type cannot be qualified with address space}}
+  groupshared float decl() {
+      return 1;
+  }
+
+  class C {
+      // expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+      // expected-error at +1 {{return type cannot be qualified with address space}}
+      groupshared void foo() {}
+      // expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+      // expected-error at +1 {{return type cannot be qualified with address space}}
+      groupshared void bar();
+      // expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+      // expected-error at +1 {{return type cannot be qualified with address space}}
+      friend groupshared void friend_def() {}
+      // expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+      // expected-error at +1 {{return type cannot be qualified with address space}}
+      friend groupshared void friend_decl();
+  };
+
+  struct S {
+    // expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+    // expected-error at +1 {{field may not be qualified with an address space}}
+    groupshared float f;
+    static groupshared float g;
+  };
+
+  // expected-error at +1 {{parameter may not be qualified with an address space}}
+  float foo2(groupshared float a) {
+    return a;
+  }
+
+// expected-note at +2 {{parameter may not be qualified with an address space}}
+template<typename T>
+  T tfoo(T t) {
+     return t;
+  }
+  // expected-warning at +1 {{alias declarations are a C++11 extension}}
+ using GSF = groupshared float;
+ GSF gs;
+ // expected-error at +1 {{no matching function for call to 'tfoo'}}
+ GSF gs2 = tfoo<GSF>(gs);
+
+// NOTE:This one didn't report error on the groupshared return type,
+// it is caused by return type check is after pointer check which is acceptable.
+// expected-error at +1 {{pointers are unsupported in HLSL}}
+groupshared void (*fp)();
+// expected-error at +2 {{pointers are unsupported in HLSL}}
+// expected-error at +1 {{parameter may not be qualified with an address space}}
+void (*fp2)(groupshared float);
+// NOTE: HLSL not support trailing return types.
+// expected-warning at +2 {{'auto' type specifier is a C++11 extension}}
+// expected-error at +1 {{expected function body after function declarator}}
+auto func() -> groupshared void;
+// expected-warning at +2 {{'groupshared' attribute only applies to variables}}
+// expected-error at +1 {{return type cannot be qualified with address space}}
+void groupshared f();
+
+struct S2 {
+  // Do we reject it as a function qualifier on a member function?
+  void f() groupshared;
+};
+
+// Does it impact size or alignment?
+_Static_assert(sizeof(float) == sizeof(groupshared float), "");
+_Static_assert(_Alignof(double) == _Alignof(groupshared double),"");
+
+// Does it impact type identity for templates?
+template <typename Ty>
+struct S3 {
+  static const bool value = false;
+};
+
+template <>
+struct S3<groupshared float> {
+  static const bool value = true;
+};
+_Static_assert(!S3<float>::value, "");
+_Static_assert(S3<groupshared float>::value, "");
+
+// Can you overload based on the qualifier?
+void func(float f) {}
+// expected-error at +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
new file mode 100644
index 000000000000..97b927a5976e
--- /dev/null
+++ b/clang/test/SemaHLSL/group_shared_202x.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -std=hlsl202x  -o - -fsyntax-only %s -verify
+
+// expected-error at +1 {{return type cannot be qualified with address space}}
+auto func() -> groupshared void;
+
+// expected-error at +1 {{parameter may not be qualified with an address space}}
+auto func(float groupshared) -> void;
+
+// expected-error at +1 {{parameter may not be qualified with an address space}}
+auto l = [](groupshared float ) {};
+
+// expected-error at +1 {{return type cannot be qualified with address space}}
+auto l2 = []() -> groupshared void {};
+
+struct S {
+// expected-error at +1 {{return type cannot be qualified with address space}}
+operator groupshared int() const;
+
+};

diff  --git a/clang/test/SemaOpenCL/address-spaces.cl b/clang/test/SemaOpenCL/address-spaces.cl
index 70b6d0753528..70ad89eb3ce2 100644
--- a/clang/test/SemaOpenCL/address-spaces.cl
+++ b/clang/test/SemaOpenCL/address-spaces.cl
@@ -231,12 +231,12 @@ void nested(__global int *g, __global int * __private *gg, __local int *l, __loc
 }
 #endif
 
-__private int func_return_priv(void);       //expected-error {{return value cannot be qualified with address space}}
-__global int func_return_global(void);      //expected-error {{return value cannot be qualified with address space}}
-__local int func_return_local(void);        //expected-error {{return value cannot be qualified with address space}}
-__constant int func_return_constant(void);  //expected-error {{return value cannot be qualified with address space}}
+__private int func_return_priv(void);       //expected-error {{return type cannot be qualified with address space}}
+__global int func_return_global(void);      //expected-error {{return type cannot be qualified with address space}}
+__local int func_return_local(void);        //expected-error {{return type cannot be qualified with address space}}
+__constant int func_return_constant(void);  //expected-error {{return type cannot be qualified with address space}}
 #if __OPENCL_C_VERSION__ >= 200
-__generic int func_return_generic(void);    //expected-error {{return value cannot be qualified with address space}}
+__generic int func_return_generic(void);    //expected-error {{return type cannot be qualified with address space}}
 #endif
 
 void func_multiple_addr(void) {

diff  --git a/clang/test/SemaOpenCL/invalid-kernel.cl b/clang/test/SemaOpenCL/invalid-kernel.cl
index fd9cd6def00e..723baa08603e 100644
--- a/clang/test/SemaOpenCL/invalid-kernel.cl
+++ b/clang/test/SemaOpenCL/invalid-kernel.cl
@@ -13,14 +13,14 @@ int main() { // expected-error {{function cannot be called 'main'}}
   return 0;
 }
 
-int* global x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+int* global x(int* x) { // expected-error {{return type cannot be qualified with address space}}
   return x + 1;
 }
 
-int* local x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+int* local x(int* x) { // expected-error {{return type cannot be qualified with address space}}
   return x + 1;
 }
 
-int* constant x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+int* constant x(int* x) { // expected-error {{return type cannot be qualified with address space}}
   return x + 1;
 }

diff  --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index 682ab75c7692..84b4c81143a4 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@ void neg() {
 
 template <long int I>
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388588)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
 }
 
 template <long int I>


        


More information about the cfe-commits mailing list