https://github.com/Keenuts updated 
https://github.com/llvm/llvm-project/pull/152537

From d90b78fb28be3c444fcc0d8113350264759080c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brio...@google.com>
Date: Wed, 6 Aug 2025 18:16:58 +0200
Subject: [PATCH 1/3] [HLSL] Rewrite semantics parsing

This is the first PR to implement the semantics proposal:
https://github.com/llvm/wg-hlsl/blob/main/proposals/0031-semantics.md

This PR focuses on the changes required to handle user semantics, but
tried to be almost NFC.
What changes is the error messages as the semantics case is not kept
when reporting error messages.

You might notice the SV_GroupIndex semantic is not properly validated as
are others. This is an existing behavior that we'll need to fix, but
wanted to keep this separated from this rewrite to stay as-close as an
NFC as possible.

The next PR will add support on the different kinds of I/O we can have
using semantics (input, inout param, structs).
---
 clang/include/clang/AST/Attr.h                |  34 ++++++
 clang/include/clang/Basic/Attr.td             |  66 +++++-----
 .../clang/Basic/DiagnosticFrontendKinds.td    |   4 +
 .../clang/Basic/DiagnosticParseKinds.td       |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |   5 +
 clang/include/clang/Parse/Parser.h            |   8 ++
 clang/include/clang/Sema/SemaHLSL.h           |  25 +++-
 clang/lib/Basic/Attributes.cpp                |   7 +-
 clang/lib/CodeGen/CGHLSLRuntime.cpp           |  76 +++++++++---
 clang/lib/CodeGen/CGHLSLRuntime.h             |  24 +++-
 clang/lib/Parse/ParseHLSL.cpp                 |  68 +++++++++--
 clang/lib/Sema/SemaDeclAttr.cpp               |  18 +--
 clang/lib/Sema/SemaHLSL.cpp                   | 113 +++++++++++++-----
 .../semantics/DispatchThreadID-noindex.hlsl   |   8 ++
 .../semantics/SV_GroupID-noindex.hlsl         |   9 ++
 .../semantics/SV_GroupThreadID-noindex.hlsl   |   8 ++
 .../CodeGenHLSL/semantics/SV_Position.ps.hlsl |   4 +-
 clang/test/CodeGenHLSL/semantics/missing.hlsl |   7 ++
 clang/test/ParserHLSL/semantic_parsing.hlsl   |  38 +++++-
 clang/test/SemaHLSL/Semantics/groupindex.hlsl |  12 +-
 .../Semantics/invalid_entry_parameter.hlsl    |  32 ++---
 .../SemaHLSL/Semantics/position.ps.size.hlsl  |   4 +-
 .../test/SemaHLSL/Semantics/position.vs.hlsl  |   2 +-
 clang/utils/TableGen/ClangAttrEmitter.cpp     |   9 +-
 24 files changed, 438 insertions(+), 148 deletions(-)
 create mode 100644 
clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
 create mode 100644 clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
 create mode 100644 
clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
 create mode 100644 clang/test/CodeGenHLSL/semantics/missing.hlsl

diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index 994f236337b99..fe388b9fa045e 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -232,6 +232,40 @@ class HLSLAnnotationAttr : public InheritableAttr {
   }
 };
 
+class HLSLSemanticAttr : public HLSLAnnotationAttr {
+  unsigned SemanticIndex = 0;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned SemanticIndexable : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned SemanticExplicitIndex : 1;
+
+protected:
+  HLSLSemanticAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+                   attr::Kind AK, bool IsLateParsed,
+                   bool InheritEvenIfAlreadyPresent, bool SemanticIndexable)
+      : HLSLAnnotationAttr(Context, CommonInfo, AK, IsLateParsed,
+                           InheritEvenIfAlreadyPresent) {
+    this->SemanticIndexable = SemanticIndexable;
+    this->SemanticExplicitIndex = false;
+  }
+
+public:
+  bool isSemanticIndexable() const { return SemanticIndexable; }
+
+  void setSemanticIndex(unsigned SemanticIndex) {
+    this->SemanticIndex = SemanticIndex;
+    this->SemanticExplicitIndex = true;
+  }
+
+  unsigned getSemanticIndex() const { return SemanticIndex; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() >= attr::FirstHLSLSemanticAttr &&
+           A->getKind() <= attr::LastHLSLSemanticAttr;
+  }
+};
+
 /// A parameter attribute which changes the argument-passing ABI rule
 /// for the parameter.
 class ParameterABIAttr : public InheritableParamAttr {
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index e672d857b9a97..fdf6e3a2a926b 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -779,6 +779,16 @@ class DeclOrStmtAttr : InheritableAttr;
 /// An attribute class for HLSL Annotations.
 class HLSLAnnotationAttr : InheritableAttr;
 
+class HLSLSemanticAttr<bit Indexable> : HLSLAnnotationAttr {
+  bit SemanticIndexable = Indexable;
+  int SemanticIndex = 0;
+  bit SemanticExplicitIndex = 0;
+
+  let Spellings = [];
+  let Subjects = SubjectList<[ParmVar, Field, Function]>;
+  let LangOpts = [HLSL];
+}
+
 /// A target-specific attribute.  This class is meant to be used as a mixin
 /// with InheritableAttr or Attr depending on the attribute's needs.
 class TargetSpecificAttr<TargetSpec target> {
@@ -4889,27 +4899,6 @@ def HLSLNumThreads: InheritableAttr {
   let Documentation = [NumThreadsDocs];
 }
 
-def HLSLSV_GroupThreadID: HLSLAnnotationAttr {
-  let Spellings = [HLSLAnnotation<"sv_groupthreadid">];
-  let Subjects = SubjectList<[ParmVar, Field]>;
-  let LangOpts = [HLSL];
-  let Documentation = [HLSLSV_GroupThreadIDDocs];
-}
-
-def HLSLSV_GroupID: HLSLAnnotationAttr {
-  let Spellings = [HLSLAnnotation<"sv_groupid">];
-  let Subjects = SubjectList<[ParmVar, Field]>;
-  let LangOpts = [HLSL];
-  let Documentation = [HLSLSV_GroupIDDocs];
-}
-
-def HLSLSV_GroupIndex: HLSLAnnotationAttr {
-  let Spellings = [HLSLAnnotation<"sv_groupindex">];
-  let Subjects = SubjectList<[ParmVar, GlobalVar]>;
-  let LangOpts = [HLSL];
-  let Documentation = [HLSLSV_GroupIndexDocs];
-}
-
 def HLSLVkBinding : InheritableAttr {
   let Spellings = [CXX11<"vk", "binding">];
   let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar], ErrorDiag>;
@@ -4968,13 +4957,35 @@ def HLSLResourceBinding: InheritableAttr {
   }];
 }
 
-def HLSLSV_Position : HLSLAnnotationAttr {
-  let Spellings = [HLSLAnnotation<"sv_position">];
-  let Subjects = SubjectList<[ParmVar, Field]>;
+def HLSLUnparsedSemantic : HLSLAnnotationAttr {
+  let Spellings = [];
+  let Args = [DefaultIntArgument<"Index", 0>,
+              DefaultBoolArgument<"ExplicitIndex", 0>];
+  let Subjects = SubjectList<[ParmVar, Field, Function]>;
   let LangOpts = [HLSL];
+  let Documentation = [InternalOnly];
+}
+
+def HLSLSV_Position : HLSLSemanticAttr</* Indexable= */ 1> {
   let Documentation = [HLSLSV_PositionDocs];
 }
 
+def HLSLSV_GroupThreadID : HLSLSemanticAttr</* Indexable= */ 0> {
+  let Documentation = [HLSLSV_GroupThreadIDDocs];
+}
+
+def HLSLSV_GroupID : HLSLSemanticAttr</* Indexable= */ 0> {
+  let Documentation = [HLSLSV_GroupIDDocs];
+}
+
+def HLSLSV_GroupIndex : HLSLSemanticAttr</* Indexable= */ 0> {
+  let Documentation = [HLSLSV_GroupIndexDocs];
+}
+
+def HLSLSV_DispatchThreadID : HLSLSemanticAttr</* Indexable= */ 0> {
+  let Documentation = [HLSLSV_DispatchThreadIDDocs];
+}
+
 def HLSLPackOffset: HLSLAnnotationAttr {
   let Spellings = [HLSLAnnotation<"packoffset">];
   let LangOpts = [HLSL];
@@ -4987,13 +4998,6 @@ def HLSLPackOffset: HLSLAnnotationAttr {
   }];
 }
 
-def HLSLSV_DispatchThreadID: HLSLAnnotationAttr {
-  let Spellings = [HLSLAnnotation<"sv_dispatchthreadid">];
-  let Subjects = SubjectList<[ParmVar, Field]>;
-  let LangOpts = [HLSL];
-  let Documentation = [HLSLSV_DispatchThreadIDDocs];
-}
-
 def HLSLShader : InheritableAttr {
   let Spellings = [Microsoft<"shader">];
   let Subjects = SubjectList<[HLSLEntry]>;
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 15447558cf952..2fd2ae434d7c5 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -400,6 +400,10 @@ def warn_hlsl_langstd_minimal :
           "recommend using %1 instead">,
   InGroup<HLSLDXCCompat>;
 
+def err_hlsl_semantic_missing : Error<"semantic annotations must be present "
+                                      "for all input and outputs of an entry "
+                                      "function or patch constant function">;
+
 // ClangIR frontend errors
 def err_cir_to_cir_transform_failed : Error<
     "CIR-to-CIR transformation failed">, DefaultFatal;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index bc7a6e231d93c..968a7c5b0dc8e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1860,9 +1860,8 @@ def note_max_tokens_total_override : Note<"total token 
limit set here">;
 
 def err_expected_semantic_identifier : Error<
   "expected HLSL Semantic identifier">;
-def err_invalid_declaration_in_hlsl_buffer : Error<
-  "invalid declaration inside %select{tbuffer|cbuffer}0">;
-def err_unknown_hlsl_semantic : Error<"unknown HLSL semantic %0">;
+def err_invalid_declaration_in_hlsl_buffer
+    : Error<"invalid declaration inside %select{tbuffer|cbuffer}0">;
 def err_hlsl_separate_attr_arg_and_number : Error<"wrong argument format for 
hlsl attribute, use %0 instead">;
 def ext_hlsl_access_specifiers : ExtWarn<
   "access specifiers are a clang HLSL extension">,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 711efbe727892..1a4ebc11119a5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13121,6 +13121,11 @@ def err_hlsl_duplicate_parameter_modifier : 
Error<"duplicate parameter modifier
 def err_hlsl_missing_semantic_annotation : Error<
   "semantic annotations must be present for all parameters of an entry "
   "function or patch constant function">;
+def err_hlsl_unknown_semantic : Error<"unknown HLSL semantic %0">;
+def err_hlsl_semantic_output_not_supported
+    : Error<"semantic %0 does not support output">;
+def err_hlsl_semantic_indexing_not_supported
+    : Error<"semantic %0 does not allow indexing">;
 def err_hlsl_init_priority_unsupported : Error<
   "initializer priorities are not supported in HLSL">;
 
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index a9a87fb586fc2..30edd303e1824 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -5188,6 +5188,14 @@ class Parser : public CodeCompletionHandler {
       ParseHLSLAnnotations(Attrs, EndLoc);
   }
 
+  struct ParsedSemantic {
+    StringRef Name = "";
+    unsigned Index = 0;
+    bool Explicit = false;
+  };
+
+  ParsedSemantic ParseHLSLSemantic();
+
   void ParseHLSLAnnotations(ParsedAttributes &Attrs,
                             SourceLocation *EndLoc = nullptr,
                             bool CouldBeBitField = false);
diff --git a/clang/include/clang/Sema/SemaHLSL.h 
b/clang/include/clang/Sema/SemaHLSL.h
index 5cbe1b658f5cd..9aa0812b07314 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -17,6 +17,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Sema/SemaBase.h"
 #include "llvm/ADT/SmallVector.h"
@@ -129,6 +130,7 @@ class SemaHLSL : public SemaBase {
   bool ActOnUninitializedVarDecl(VarDecl *D);
   void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
   void CheckEntryPoint(FunctionDecl *FD);
+  bool isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D);
   void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
                                const HLSLAnnotationAttr *AnnotationAttr);
   void DiagnoseAttrStageMismatch(
@@ -166,16 +168,31 @@ class SemaHLSL : public SemaBase {
   void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
   void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL);
   void handleVkBindingAttr(Decl *D, const ParsedAttr &AL);
-  void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
-  void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL);
-  void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL);
-  void handleSV_PositionAttr(Decl *D, const ParsedAttr &AL);
   void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
   void handleShaderAttr(Decl *D, const ParsedAttr &AL);
   void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
   void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);
   bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL);
 
+  template <typename T>
+  T *createSemanticAttr(const ParsedAttr &AL,
+                        std::optional<unsigned> Location) {
+    T *Attr = ::new (getASTContext()) T(getASTContext(), AL);
+    if (Attr->isSemanticIndexable())
+      Attr->setSemanticIndex(Location ? *Location : 0);
+    else if (Location.has_value()) {
+      Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported)
+          << Attr->getAttrName()->getName();
+      return nullptr;
+    }
+
+    return Attr;
+  }
+
+  void diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL,
+                                  std::optional<unsigned> Index);
+  void handleSemanticAttr(Decl *D, const ParsedAttr &AL);
+
   void handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL);
 
   bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 81b186f844b8a..5878a4e3f83a4 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -189,7 +189,12 @@ AttributeCommonInfo::Kind
 AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
                                    const IdentifierInfo *ScopeName,
                                    Syntax SyntaxUsed) {
-  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
+  AttributeCommonInfo::Kind Kind =
+      ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
+  if (SyntaxUsed == AS_HLSLAnnotation &&
+      Kind == AttributeCommonInfo::Kind::UnknownAttribute)
+    return AttributeCommonInfo::Kind::AT_HLSLUnparsedSemantic;
+  return Kind;
 }
 
 AttributeCommonInfo::AttrArgsInfo
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index d27f3781c69a3..886bf2ccf3fdf 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -23,6 +23,7 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
@@ -552,47 +553,82 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> 
&B, llvm::Module &M,
   return B.CreateLoad(Ty, GV);
 }
 
-llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
-                                              const ParmVarDecl &D,
-                                              llvm::Type *Ty) {
-  assert(D.hasAttrs() && "Entry parameter missing annotation attribute!");
-  if (D.hasAttr<HLSLSV_GroupIndexAttr>()) {
+llvm::Value *
+CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
+                                      const clang::DeclaratorDecl *Decl,
+                                      SemanticInfo &ActiveSemantic) {
+  if (HLSLSV_GroupIndexAttr *S =
+          dyn_cast<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) {
     llvm::Function *GroupIndex =
         CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
     return B.CreateCall(FunctionCallee(GroupIndex));
   }
-  if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
+
+  if (HLSLSV_DispatchThreadIDAttr *S =
+          dyn_cast<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) {
     llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
     llvm::Function *ThreadIDIntrinsic =
         llvm::Intrinsic::isOverloaded(IntrinID)
             ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty})
             : CGM.getIntrinsic(IntrinID);
-    return buildVectorInput(B, ThreadIDIntrinsic, Ty);
+    return buildVectorInput(B, ThreadIDIntrinsic, Type);
   }
-  if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) {
+
+  if (HLSLSV_GroupThreadIDAttr *S =
+          dyn_cast<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) {
     llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
     llvm::Function *GroupThreadIDIntrinsic =
         llvm::Intrinsic::isOverloaded(IntrinID)
             ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty})
             : CGM.getIntrinsic(IntrinID);
-    return buildVectorInput(B, GroupThreadIDIntrinsic, Ty);
+    return buildVectorInput(B, GroupThreadIDIntrinsic, Type);
   }
-  if (D.hasAttr<HLSLSV_GroupIDAttr>()) {
+
+  if (HLSLSV_GroupIDAttr *S =
+          dyn_cast<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) {
     llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
     llvm::Function *GroupIDIntrinsic =
         llvm::Intrinsic::isOverloaded(IntrinID)
             ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty})
             : CGM.getIntrinsic(IntrinID);
-    return buildVectorInput(B, GroupIDIntrinsic, Ty);
+    return buildVectorInput(B, GroupIDIntrinsic, Type);
   }
-  if (D.hasAttr<HLSLSV_PositionAttr>()) {
-    if (getArch() == llvm::Triple::spirv)
-      return createSPIRVBuiltinLoad(B, CGM.getModule(), Ty, "sv_position",
-                                    /* BuiltIn::Position */ 0);
-    llvm_unreachable("SV_Position semantic not implemented for this target.");
+
+  if (HLSLSV_PositionAttr *S =
+          dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) {
+    if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
+      return createSPIRVBuiltinLoad(B, CGM.getModule(), Type,
+                                    S->getAttrName()->getName(),
+                                    /* BuiltIn::FragCoord */ 15);
   }
-  assert(false && "Unhandled parameter attribute");
-  return nullptr;
+
+  llvm_unreachable("non-handled system semantic. FIXME.");
+}
+
+llvm::Value *
+CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
+                                        const clang::DeclaratorDecl *Decl,
+                                        SemanticInfo &ActiveSemantic) {
+
+  if (!ActiveSemantic.Semantic) {
+    ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>();
+    if (!ActiveSemantic.Semantic) {
+      CGM.getDiags().Report(Decl->getInnerLocStart(),
+                            diag::err_hlsl_semantic_missing);
+      return nullptr;
+    }
+    ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+  }
+
+  return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic);
+}
+
+llvm::Value *
+CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
+                                  const clang::DeclaratorDecl *Decl,
+                                  SemanticInfo &ActiveSemantic) {
+  assert(!Type->isStructTy());
+  return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic);
 }
 
 void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
@@ -637,8 +673,10 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl 
*FD,
       Args.emplace_back(PoisonValue::get(Param.getType()));
       continue;
     }
+
     const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset);
-    Args.push_back(emitInputSemantic(B, *PD, Param.getType()));
+    SemanticInfo ActiveSemantic = {nullptr, 0};
+    Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic));
   }
 
   CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 0582be3d99ec4..25d4c65426b0d 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -21,6 +21,8 @@
 #include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsSPIRV.h"
 
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/HLSLRuntime.h"
 
@@ -137,8 +139,26 @@ class CGHLSLRuntime {
 protected:
   CodeGenModule &CGM;
 
-  llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D,
-                                 llvm::Type *Ty);
+  void collectInputSemantic(llvm::IRBuilder<> &B, const DeclaratorDecl *D,
+                            llvm::Type *Type,
+                            SmallVectorImpl<llvm::Value *> &Inputs);
+
+  struct SemanticInfo {
+    clang::HLSLSemanticAttr *Semantic;
+    uint32_t Index;
+  };
+
+  llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
+                                      const clang::DeclaratorDecl *Decl,
+                                      SemanticInfo &ActiveSemantic);
+
+  llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
+                                        const clang::DeclaratorDecl *Decl,
+                                        SemanticInfo &ActiveSemantic);
+
+  llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
+                                  const clang::DeclaratorDecl *Decl,
+                                  SemanticInfo &ActiveSemantic);
 
 public:
   CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index f243b0cb95eae..2affaa09d61c5 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -118,6 +118,47 @@ static void fixSeparateAttrArgAndNumber(StringRef ArgStr, 
SourceLocation ArgLoc,
   Slot = new (Ctx) IdentifierLoc(ArgLoc, PP.getIdentifierInfo(FixedArg));
 }
 
+Parser::ParsedSemantic Parser::ParseHLSLSemantic() {
+  assert(Tok.is(tok::identifier) && "Not a HLSL Annotation");
+
+  // Semantic pattern: [A-Za-z_]([A-Za-z_0-9]*[A-Za-z_])?[0-9]*
+  // The first part is the semantic name, the second is the optional
+  // semantic index. The semantic index is the number at the end of
+  // the semantic, including leading zeroes. Digits located before
+  // the last letter are part of the semantic name.
+  bool Invalid = false;
+  SmallString<256> Buffer;
+  Buffer.resize(Tok.getLength() + 1);
+  StringRef Identifier = PP.getSpelling(Tok, Buffer);
+  if (Invalid) {
+    Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);
+    return {};
+  }
+
+  assert(Identifier.size() > 0);
+  unsigned I = Identifier.size();
+  for (; I > 0 && isDigit(Identifier[I - 1]); --I)
+    continue;
+
+  // ParseHLSLSemantic being called on an indentifier, the first
+  // character cannot be a digit. This error should be handled by
+  // the caller. We can assert here.
+  StringRef SemanticName = Identifier.take_front(I);
+  assert(SemanticName.size() > 0);
+
+  unsigned Index = 0;
+  bool Explicit = false;
+  if (I != Identifier.size()) {
+    Explicit = true;
+    [[maybe_unused]] bool Failure =
+        Identifier.substr(I).getAsInteger(10, Index);
+    // Given the logic above, this should never fail.
+    assert(!Failure);
+  }
+
+  return {SemanticName, Index, Explicit};
+}
+
 void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
                                   SourceLocation *EndLoc,
                                   bool CouldBeBitField) {
@@ -141,11 +182,15 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
     return;
   }
 
+  ParsedAttr::Kind AttrKind =
+      ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
+  Parser::ParsedSemantic Semantic;
+  if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic)
+    Semantic = ParseHLSLSemantic();
+
   SourceLocation Loc = ConsumeToken();
   if (EndLoc)
     *EndLoc = Tok.getLocation();
-  ParsedAttr::Kind AttrKind =
-      ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
 
   ArgsVector ArgExprs;
   switch (AttrKind) {
@@ -282,14 +327,17 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
       return;
     }
   } break;
-  case ParsedAttr::UnknownAttribute:
-    Diag(Loc, diag::err_unknown_hlsl_semantic) << II;
-    return;
-  case ParsedAttr::AT_HLSLSV_GroupThreadID:
-  case ParsedAttr::AT_HLSLSV_GroupID:
-  case ParsedAttr::AT_HLSLSV_GroupIndex:
-  case ParsedAttr::AT_HLSLSV_DispatchThreadID:
-  case ParsedAttr::AT_HLSLSV_Position:
+  case ParsedAttr::AT_HLSLUnparsedSemantic: {
+    ASTContext &Ctx = Actions.getASTContext();
+    ArgExprs.push_back(IntegerLiteral::Create(
+        Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.IntTy), Semantic.Index), 
Ctx.IntTy,
+        SourceLocation()));
+    ArgExprs.push_back(IntegerLiteral::Create(
+        Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.BoolTy, SourceLocation()));
+    II = PP.getIdentifierInfo(Semantic.Name.upper());
+    break;
+  }
+  case ParsedAttr::UnknownAttribute: // FIXME: maybe this is obsolete?
     break;
   default:
     llvm_unreachable("invalid HLSL Annotation");
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index cb2c132cca978..44906456f3371 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7465,9 +7465,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 
const ParsedAttr &AL,
   case ParsedAttr::AT_HLSLWaveSize:
     S.HLSL().handleWaveSizeAttr(D, AL);
     break;
-  case ParsedAttr::AT_HLSLSV_Position:
-    S.HLSL().handleSV_PositionAttr(D, AL);
-    break;
   case ParsedAttr::AT_HLSLVkExtBuiltinInput:
     S.HLSL().handleVkExtBuiltinInputAttr(D, AL);
     break;
@@ -7477,21 +7474,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 
const ParsedAttr &AL,
   case ParsedAttr::AT_HLSLVkBinding:
     S.HLSL().handleVkBindingAttr(D, AL);
     break;
-  case ParsedAttr::AT_HLSLSV_GroupThreadID:
-    S.HLSL().handleSV_GroupThreadIDAttr(D, AL);
-    break;
-  case ParsedAttr::AT_HLSLSV_GroupID:
-    S.HLSL().handleSV_GroupIDAttr(D, AL);
-    break;
-  case ParsedAttr::AT_HLSLSV_GroupIndex:
-    handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);
-    break;
   case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
     handleSimpleAttribute<HLSLGroupSharedAddressSpaceAttr>(S, D, AL);
     break;
-  case ParsedAttr::AT_HLSLSV_DispatchThreadID:
-    S.HLSL().handleSV_DispatchThreadIDAttr(D, AL);
-    break;
   case ParsedAttr::AT_HLSLPackOffset:
     S.HLSL().handlePackOffsetAttr(D, AL);
     break;
@@ -7504,6 +7489,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 
const ParsedAttr &AL,
   case ParsedAttr::AT_HLSLParamModifier:
     S.HLSL().handleParamModifierAttr(D, AL);
     break;
+  case ParsedAttr::AT_HLSLUnparsedSemantic:
+    S.HLSL().handleSemanticAttr(D, AL);
+    break;
 
   case ParsedAttr::AT_AbiTag:
     handleAbiTagAttr(S, D, AL);
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index fb8f131d1e11b..b597f983b5d24 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -771,6 +771,26 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
   }
 }
 
+bool SemaHLSL::isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D) {
+  const auto *AnnotationAttr = D->getAttr<HLSLAnnotationAttr>();
+  if (AnnotationAttr) {
+    CheckSemanticAnnotation(FD, D, AnnotationAttr);
+    return true;
+  }
+
+  const Type *T = D->getType()->getUnqualifiedDesugaredType();
+  const RecordType *RT = dyn_cast<RecordType>(T);
+  if (!RT)
+    return false;
+
+  const RecordDecl *RD = RT->getDecl();
+  for (FieldDecl *Field : RD->fields()) {
+    if (!isSemanticValid(FD, Field))
+      return false;
+  }
+  return true;
+}
+
 void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
   const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>();
   assert(ShaderAttr && "Entry point has no shader attribute");
@@ -832,11 +852,7 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
   }
 
   for (ParmVarDecl *Param : FD->parameters()) {
-    if (const auto *AnnotationAttr = Param->getAttr<HLSLAnnotationAttr>()) {
-      CheckSemanticAnnotation(FD, Param, AnnotationAttr);
-    } else {
-      // FIXME: Handle struct parameters where annotations are on struct 
fields.
-      // See: https://github.com/llvm/llvm-project/issues/57875
+    if (!isSemanticValid(FD, Param)) {
       Diag(FD->getLocation(), diag::err_hlsl_missing_semantic_annotation);
       Diag(Param->getLocation(), diag::note_previous_decl) << Param;
       FD->setInvalidDecl();
@@ -1548,18 +1564,8 @@ bool SemaHLSL::diagnoseInputIDType(QualType T, const 
ParsedAttr &AL) {
   return true;
 }
 
-void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) {
-  auto *VD = cast<ValueDecl>(D);
-  if (!diagnoseInputIDType(VD->getType(), AL))
-    return;
-
-  D->addAttr(::new (getASTContext())
-                 HLSLSV_DispatchThreadIDAttr(getASTContext(), AL));
-}
-
 bool SemaHLSL::diagnosePositionType(QualType T, const ParsedAttr &AL) {
   const auto *VT = T->getAs<VectorType>();
-
   if (!T->hasFloatingRepresentation() || (VT && VT->getNumElements() > 4)) {
     Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
         << AL << "float/float1/float2/float3/float4";
@@ -1569,29 +1575,70 @@ bool SemaHLSL::diagnosePositionType(QualType T, const 
ParsedAttr &AL) {
   return true;
 }
 
-void SemaHLSL::handleSV_PositionAttr(Decl *D, const ParsedAttr &AL) {
-  auto *VD = cast<ValueDecl>(D);
-  if (!diagnosePositionType(VD->getType(), AL))
-    return;
-
-  D->addAttr(::new (getASTContext()) HLSLSV_PositionAttr(getASTContext(), AL));
-}
+void SemaHLSL::diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL,
+                                          std::optional<unsigned> Index) {
+  StringRef SemanticName = AL.getAttrName()->getName();
 
-void SemaHLSL::handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL) {
   auto *VD = cast<ValueDecl>(D);
-  if (!diagnoseInputIDType(VD->getType(), AL))
-    return;
-
-  D->addAttr(::new (getASTContext())
-                 HLSLSV_GroupThreadIDAttr(getASTContext(), AL));
-}
+  QualType ValueType = VD->getType();
+  if (auto *FD = dyn_cast<FunctionDecl>(D))
+    ValueType = FD->getReturnType();
+
+  bool IsOutput = false;
+  if (HLSLParamModifierAttr *MA = D->getAttr<HLSLParamModifierAttr>()) {
+    if (MA->isOut()) {
+      IsOutput = true;
+      ValueType = cast<ReferenceType>(ValueType)->getPointeeType();
+    }
+  }
 
-void SemaHLSL::handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL) {
-  auto *VD = cast<ValueDecl>(D);
-  if (!diagnoseInputIDType(VD->getType(), AL))
+  Attr *Attribute = nullptr;
+  if (SemanticName == "SV_DISPATCHTHREADID") {
+    diagnoseInputIDType(ValueType, AL);
+    if (IsOutput)
+      Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
+    Attribute = createSemanticAttr<HLSLSV_DispatchThreadIDAttr>(AL, Index);
+  } else if (SemanticName == "SV_GROUPINDEX") {
+    if (IsOutput)
+      Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
+    Attribute = createSemanticAttr<HLSLSV_GroupIndexAttr>(AL, Index);
+  } else if (SemanticName == "SV_GROUPTHREADID") {
+    diagnoseInputIDType(ValueType, AL);
+    if (IsOutput)
+      Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
+    Attribute = createSemanticAttr<HLSLSV_GroupThreadIDAttr>(AL, Index);
+  } else if (SemanticName == "SV_GROUPID") {
+    diagnoseInputIDType(ValueType, AL);
+    if (IsOutput)
+      Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
+    Attribute = createSemanticAttr<HLSLSV_GroupIDAttr>(AL, Index);
+  } else if (SemanticName == "SV_POSITION") {
+    const auto *VT = ValueType->getAs<VectorType>();
+    if (!ValueType->hasFloatingRepresentation() ||
+        (VT && VT->getNumElements() > 4))
+      Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
+          << AL << "float/float1/float2/float3/float4";
+    Attribute = createSemanticAttr<HLSLSV_PositionAttr>(AL, Index);
+  } else
+    Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL;
+
+  if (!Attribute)
     return;
+  D->addAttr(Attribute);
+}
 
-  D->addAttr(::new (getASTContext()) HLSLSV_GroupIDAttr(getASTContext(), AL));
+void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
+  uint32_t IndexValue, ExplicitIndex;
+  SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), IndexValue);
+  SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(1), ExplicitIndex);
+  assert(IndexValue > 0 ? ExplicitIndex : true);
+  std::optional<unsigned> Index =
+      ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
+
+  if (AL.getAttrName()->getName().starts_with("SV_"))
+    diagnoseSystemSemanticAttr(D, AL, Index);
+  else
+    Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL;
 }
 
 void SemaHLSL::handlePackOffsetAttr(Decl *D, const ParsedAttr &AL) {
diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
new file mode 100644
index 0000000000000..c75efff82a852
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(uint Idx : SV_DispatchThreadID1) {
+  // expected-error@-1 {{semantic SV_DISPATCHTHREADID does not allow indexing}}
+}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
new file mode 100644
index 0000000000000..d18ab9f5d0ff7
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(uint Idx : SV_GroupID1) {
+  // expected-error@-1 {{semantic SV_GROUPID does not allow indexing}}
+}
+
diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
new file mode 100644
index 0000000000000..55b1f349dd943
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s -verify 
-verify-ignore-unexpected=note,error
+
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(uint Idx : SV_GroupThreadID1) {
+  // expected-error@-1 {{semantic SV_GROUPTHREADID does not allow indexing}}
+}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
index bdba38e028edd..af13eb3ea6af5 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-pixel -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
 
-// CHECK: @sv_position = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
+// CHECK: @SV_POSITION = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
 
 // CHECK: define void @main() {{.*}} {
 float4 main(float4 p : SV_Position) {
-  // CHECK: %[[#P:]] = load <4 x float>, ptr addrspace(7) @sv_position, align 
16
+  // CHECK: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_POSITION, align 
16
   // CHECK: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> 
%[[#P]])
   return p;
 }
diff --git a/clang/test/CodeGenHLSL/semantics/missing.hlsl 
b/clang/test/CodeGenHLSL/semantics/missing.hlsl
new file mode 100644
index 0000000000000..3ba725e49c2c0
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/missing.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm 
-disable-llvm-passes -o - -hlsl-entry main %s -verify 
-verify-ignore-unexpected=note
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm 
-disable-llvm-passes -o - -hlsl-entry main %s -verify 
-verify-ignore-unexpected=note
+
+[numthreads(1,1,1)]
+void main(unsigned GI) {
+  // expected-error@-1 {{semantic annotations must be present for all 
parameters of an entry function or patch constant function}}
+}
diff --git a/clang/test/ParserHLSL/semantic_parsing.hlsl 
b/clang/test/ParserHLSL/semantic_parsing.hlsl
index 34df1805c5a95..cfc693a2dd28f 100644
--- a/clang/test/ParserHLSL/semantic_parsing.hlsl
+++ b/clang/test/ParserHLSL/semantic_parsing.hlsl
@@ -1,7 +1,41 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o 
- %s -verify
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s 
-verify
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-compute -x hlsl -o - %s 
-verify
 
 // expected-error@+1 {{expected HLSL Semantic identifier}}
 void Entry(int GI : ) { }
 
-// expected-error@+1 {{unknown HLSL semantic 'SV_IWantAPony'}}
+// expected-error@+1 {{unknown HLSL semantic 'SV_IWANTAPONY'}}
 void Pony(int GI : SV_IWantAPony) { }
+
+// expected-error@+3 {{expected HLSL Semantic identifier}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+void SuperPony(int GI : 0) { }
+
+// expected-error@+1 {{unknown HLSL semantic '_'}}
+void MegaPony(int GI : _) { }
+
+// expected-error@+1 {{unknown HLSL semantic 'A0A'}}
+void CoolPony(int GI : A0A0) { }
+
+// expected-error@+1 {{unknown HLSL semantic 'A_'}}
+void NicePony(int GI : A_0) { }
+
+// expected-error@+1 {{unknown HLSL semantic 'A'}}
+void CutePony(int GI : A00) { }
+
+// expected-error@+3 {{unknown HLSL semantic 'A'}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+void DoublePony(int GI : A00 B) { }
+
+// expected-error@+1 {{unknown HLSL semantic 'é'}}
+void BigPony(int GI : é) { }
+
+// expected-error@+2 {{unexpected character <U+1F60A>}}
+// expected-error@+1 {{expected HLSL Semantic identifier}}
+void UTFPony(int GI : 😊) { }
+
+// expected-error@+2 {{character <U+1F60A> not allowed in an identifier}}
+// expected-error@+1 {{unknown HLSL semantic 'PONYWITHA😊'}}
+void SmilingPony(int GI : PonyWithA😊) { }
diff --git a/clang/test/SemaHLSL/Semantics/groupindex.hlsl 
b/clang/test/SemaHLSL/Semantics/groupindex.hlsl
index a33e060c82906..8acdee8e85989 100644
--- a/clang/test/SemaHLSL/Semantics/groupindex.hlsl
+++ b/clang/test/SemaHLSL/Semantics/groupindex.hlsl
@@ -4,26 +4,26 @@
 [shader("compute")][numthreads(32,1,1)]
 void compute(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'pixel' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'pixel' 
shaders}}
 [shader("pixel")]
 void pixel(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'vertex' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'vertex' 
shaders}}
 [shader("vertex")]
 void vertex(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'geometry' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'geometry' 
shaders}}
 [shader("geometry")]
 void geometry(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'domain' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'domain' 
shaders}}
 [shader("domain")]
 void domain(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 
'amplification' shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 
'amplification' shaders}}
 [shader("amplification")][numthreads(32,1,1)]
 void amplification(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'mesh' 
shaders}}
 [shader("mesh")][numthreads(32,1,1)]
 void mesh(int GI : SV_GroupIndex) {}
diff --git a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl 
b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
index 1bb4ee5182d62..18bae5ee322df 100644
--- a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
+++ b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -x hlsl -ast-dump -verify -o - %s
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_DispatchThreadID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_DISPATCHTHREADID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
 void CSMain(float ID : SV_DispatchThreadID) {
 
 }
@@ -11,71 +11,71 @@ struct ST {
   float b;
 };
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_DispatchThreadID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_DISPATCHTHREADID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
 void CSMain2(ST ID : SV_DispatchThreadID) {
 
 }
 
 void foo() {
-// expected-warning@+1 {{'SV_DispatchThreadID' attribute only applies to 
parameters and non-static data members}}
+// expected-warning@+1 {{'SV_DISPATCHTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
   uint V : SV_DispatchThreadID;
 
 }
 
 struct ST2 {
-// expected-warning@+1 {{'SV_DispatchThreadID' attribute only applies to 
parameters and non-static data members}}
+// expected-warning@+1 {{'SV_DISPATCHTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
     static uint X : SV_DispatchThreadID;
     uint s : SV_DispatchThreadID;
 };
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GroupID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GROUPID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain_GID(float ID : SV_GroupID) {
 }
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GroupID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GROUPID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain2_GID(ST GID : SV_GroupID) {
 
 }
 
 void foo_GID() {
-// expected-warning@+1 {{'SV_GroupID' attribute only applies to parameters and 
non-static data members}}
+// expected-warning@+1 {{'SV_GROUPID' attribute only applies to parameters, 
non-static data members, and functions}}
   uint GIS : SV_GroupID;
 }
 
 struct ST2_GID {
-// expected-warning@+1 {{'SV_GroupID' attribute only applies to parameters and 
non-static data members}}
+// expected-warning@+1 {{'SV_GROUPID' attribute only applies to parameters, 
non-static data members, and functions}}
     static uint GID : SV_GroupID;
     uint s_gid : SV_GroupID;
 };
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GROUPTHREADID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain_GThreadID(float ID : SV_GroupThreadID) {
 }
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GROUPTHREADID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain2_GThreadID(ST GID : SV_GroupThreadID) {
 
 }
 
 void foo_GThreadID() {
-// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to 
parameters and non-static data members}}
+// expected-warning@+1 {{'SV_GROUPTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
   uint GThreadIS : SV_GroupThreadID;
 }
 
 struct ST2_GThreadID {
-// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to 
parameters and non-static data members}}
+// expected-warning@+1 {{'SV_GROUPTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
     static uint GThreadID : SV_GroupThreadID;
     uint s_gthreadid : SV_GroupThreadID;
 };
 
 
 [shader("vertex")]
-// expected-error@+4 {{attribute 'SV_GroupIndex' is unsupported in 'vertex' 
shaders, requires compute}}
-// expected-error@+3 {{attribute 'SV_DispatchThreadID' is unsupported in 
'vertex' shaders, requires compute}}
-// expected-error@+2 {{attribute 'SV_GroupID' is unsupported in 'vertex' 
shaders, requires compute}}
-// expected-error@+1 {{attribute 'SV_GroupThreadID' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+4 {{attribute 'SV_GROUPINDEX' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+3 {{attribute 'SV_DISPATCHTHREADID' is unsupported in 
'vertex' shaders, requires compute}}
+// expected-error@+2 {{attribute 'SV_GROUPID' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+1 {{attribute 'SV_GROUPTHREADID' is unsupported in 'vertex' 
shaders, requires compute}}
 void vs_main(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : 
SV_GroupID, uint GThreadID : SV_GroupThreadID) {}
diff --git a/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl 
b/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
index 124d401a9990c..b57ce4e325ca2 100644
--- a/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -o - %s -verify -verify-ignore-unexpected
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library  -x hlsl 
-finclude-default-header -o - %s -verify -verify-ignore-unexpected
 
-// expected-error@+1 {{attribute 'SV_Position' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
+// expected-error@+1 {{attribute 'SV_POSITION' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
 void main(vector<float, 5> a : SV_Position) {
 }
 
-// expected-error@+1 {{attribute 'SV_Position' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
+// expected-error@+1 {{attribute 'SV_POSITION' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
 void main(int2 a : SV_Position) {
 }
diff --git a/clang/test/SemaHLSL/Semantics/position.vs.hlsl 
b/clang/test/SemaHLSL/Semantics/position.vs.hlsl
index 19f781fa3757c..e5e8da2484d93 100644
--- a/clang/test/SemaHLSL/Semantics/position.vs.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.vs.hlsl
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-vertex -x hlsl 
-finclude-default-header -o - %s -verify
 
-// expected-error@+1 {{attribute 'SV_Position' is unsupported in 'vertex' 
shaders, requires pixel}}
+// expected-error@+1 {{attribute 'SV_POSITION' is unsupported in 'vertex' 
shaders, requires pixel}}
 float4 main(float4 a : SV_Position) {
   return a;
 }
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index d63e79a5f5155..c4193110bee01 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2725,12 +2725,15 @@ static void emitAttributes(const RecordKeeper &Records, 
raw_ostream &OS,
     assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
     std::string SuperName;
     bool Inheritable = false;
+    bool HLSLSemantic = false;
     for (const Record *R : reverse(Supers)) {
       if (R->getName() != "TargetSpecificAttr" &&
           R->getName() != "DeclOrTypeAttr" && SuperName.empty())
         SuperName = R->getName().str();
       if (R->getName() == "InheritableAttr")
         Inheritable = true;
+      if (R->getName() == "HLSLSemanticAttr")
+        HLSLSemantic = true;
     }
 
     if (Header)
@@ -3054,6 +3057,9 @@ static void emitAttributes(const RecordKeeper &Records, 
raw_ostream &OS,
            << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
                                                               : "false");
       }
+      if (HLSLSemantic) {
+        OS << ", " << (R.getValueAsBit("SemanticIndexable") ? "true" : 
"false");
+      }
       OS << ")\n";
 
       for (auto const &ai : Args) {
@@ -3270,7 +3276,8 @@ static const AttrClassDescriptor AttrClassDescriptors[] = 
{
     {"INHERITABLE_PARAM_ATTR", "InheritableParamAttr"},
     {"INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr"},
     {"PARAMETER_ABI_ATTR", "ParameterABIAttr"},
-    {"HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"}};
+    {"HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"},
+    {"HLSL_SEMANTIC_ATTR", "HLSLSemanticAttr"}};
 
 static void emitDefaultDefine(raw_ostream &OS, StringRef name,
                               const char *superName) {

From 5097f3424eafdd43d4b797552b4f6bf7b217476d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brio...@google.com>
Date: Tue, 9 Sep 2025 13:50:07 +0200
Subject: [PATCH 2/3] formatting

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index c4193110bee01..e76e2db3774ed 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3057,9 +3057,8 @@ static void emitAttributes(const RecordKeeper &Records, 
raw_ostream &OS,
            << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
                                                               : "false");
       }
-      if (HLSLSemantic) {
+      if (HLSLSemantic)
         OS << ", " << (R.getValueAsBit("SemanticIndexable") ? "true" : 
"false");
-      }
       OS << ")\n";
 
       for (auto const &ai : Args) {

From 6abee77f33b662ff6589c63f308fc307307d0c75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brio...@google.com>
Date: Tue, 9 Sep 2025 13:49:56 +0200
Subject: [PATCH 3/3] preserve semantic name case for diagnostics

---
 clang/lib/Parse/ParseHLSL.cpp                 |  2 +-
 clang/lib/Sema/SemaHLSL.cpp                   |  6 ++--
 .../semantics/DispatchThreadID-noindex.hlsl   |  2 +-
 .../semantics/SV_GroupID-noindex.hlsl         |  2 +-
 .../semantics/SV_GroupThreadID-noindex.hlsl   |  2 +-
 .../CodeGenHLSL/semantics/SV_Position.ps.hlsl |  4 +--
 clang/test/ParserHLSL/semantic_parsing.hlsl   |  4 +--
 .../ParserHLSL/semantic_parsing_define.hlsl   |  7 ++++
 clang/test/SemaHLSL/Semantics/groupindex.hlsl | 12 +++----
 .../Semantics/invalid_entry_parameter.hlsl    | 32 +++++++++----------
 .../SemaHLSL/Semantics/position.ps.size.hlsl  |  4 +--
 .../test/SemaHLSL/Semantics/position.vs.hlsl  |  2 +-
 12 files changed, 43 insertions(+), 36 deletions(-)
 create mode 100644 clang/test/ParserHLSL/semantic_parsing_define.hlsl

diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index 2affaa09d61c5..40a0b4cd1ed86 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -334,7 +334,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
         SourceLocation()));
     ArgExprs.push_back(IntegerLiteral::Create(
         Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.BoolTy, SourceLocation()));
-    II = PP.getIdentifierInfo(Semantic.Name.upper());
+    II = PP.getIdentifierInfo(Semantic.Name);
     break;
   }
   case ParsedAttr::UnknownAttribute: // FIXME: maybe this is obsolete?
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index b597f983b5d24..e0b936db7a9cb 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -783,7 +783,7 @@ bool SemaHLSL::isSemanticValid(FunctionDecl *FD, 
DeclaratorDecl *D) {
   if (!RT)
     return false;
 
-  const RecordDecl *RD = RT->getDecl();
+  const RecordDecl *RD = RT->getOriginalDecl();
   for (FieldDecl *Field : RD->fields()) {
     if (!isSemanticValid(FD, Field))
       return false;
@@ -1577,7 +1577,7 @@ bool SemaHLSL::diagnosePositionType(QualType T, const 
ParsedAttr &AL) {
 
 void SemaHLSL::diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL,
                                           std::optional<unsigned> Index) {
-  StringRef SemanticName = AL.getAttrName()->getName();
+  std::string SemanticName = AL.getAttrName()->getName().upper();
 
   auto *VD = cast<ValueDecl>(D);
   QualType ValueType = VD->getType();
@@ -1635,7 +1635,7 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const 
ParsedAttr &AL) {
   std::optional<unsigned> Index =
       ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
 
-  if (AL.getAttrName()->getName().starts_with("SV_"))
+  if (AL.getAttrName()->getName().starts_with_insensitive("SV_"))
     diagnoseSystemSemanticAttr(D, AL, Index);
   else
     Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL;
diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
index c75efff82a852..9ed545762ec94 100644
--- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl
@@ -4,5 +4,5 @@
 [shader("compute")]
 [numthreads(8,8,1)]
 void foo(uint Idx : SV_DispatchThreadID1) {
-  // expected-error@-1 {{semantic SV_DISPATCHTHREADID does not allow indexing}}
+  // expected-error@-1 {{semantic SV_DispatchThreadID does not allow indexing}}
 }
diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
index d18ab9f5d0ff7..8fa0b07a36027 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl
@@ -4,6 +4,6 @@
 [shader("compute")]
 [numthreads(8,8,1)]
 void foo(uint Idx : SV_GroupID1) {
-  // expected-error@-1 {{semantic SV_GROUPID does not allow indexing}}
+  // expected-error@-1 {{semantic SV_GroupID does not allow indexing}}
 }
 
diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
index 55b1f349dd943..da72e85d2600e 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl
@@ -4,5 +4,5 @@
 [shader("compute")]
 [numthreads(8,8,1)]
 void foo(uint Idx : SV_GroupThreadID1) {
-  // expected-error@-1 {{semantic SV_GROUPTHREADID does not allow indexing}}
+  // expected-error@-1 {{semantic SV_GroupThreadID does not allow indexing}}
 }
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
index af13eb3ea6af5..1bba87ea07141 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-pixel -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
 
-// CHECK: @SV_POSITION = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
+// CHECK: @SV_Position = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
 
 // CHECK: define void @main() {{.*}} {
 float4 main(float4 p : SV_Position) {
-  // CHECK: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_POSITION, align 
16
+  // CHECK: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 
16
   // CHECK: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> 
%[[#P]])
   return p;
 }
diff --git a/clang/test/ParserHLSL/semantic_parsing.hlsl 
b/clang/test/ParserHLSL/semantic_parsing.hlsl
index cfc693a2dd28f..726deadb7c44c 100644
--- a/clang/test/ParserHLSL/semantic_parsing.hlsl
+++ b/clang/test/ParserHLSL/semantic_parsing.hlsl
@@ -4,7 +4,7 @@
 // expected-error@+1 {{expected HLSL Semantic identifier}}
 void Entry(int GI : ) { }
 
-// expected-error@+1 {{unknown HLSL semantic 'SV_IWANTAPONY'}}
+// expected-error@+1 {{unknown HLSL semantic 'SV_IWantAPony'}}
 void Pony(int GI : SV_IWantAPony) { }
 
 // expected-error@+3 {{expected HLSL Semantic identifier}}
@@ -37,5 +37,5 @@ void BigPony(int GI : é) { }
 void UTFPony(int GI : 😊) { }
 
 // expected-error@+2 {{character <U+1F60A> not allowed in an identifier}}
-// expected-error@+1 {{unknown HLSL semantic 'PONYWITHA😊'}}
+// expected-error@+1 {{unknown HLSL semantic 'PonyWithA😊'}}
 void SmilingPony(int GI : PonyWithA😊) { }
diff --git a/clang/test/ParserHLSL/semantic_parsing_define.hlsl 
b/clang/test/ParserHLSL/semantic_parsing_define.hlsl
new file mode 100644
index 0000000000000..b42e2e6abd3de
--- /dev/null
+++ b/clang/test/ParserHLSL/semantic_parsing_define.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s 
-verify
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-compute -x hlsl -o - %s 
-verify
+
+#define SomeDefine SV_IWantAPony
+
+// expected-error@7 {{unknown HLSL semantic 'SV_IWantAPony'}}
+void Pony(int GI : SomeDefine) { }
diff --git a/clang/test/SemaHLSL/Semantics/groupindex.hlsl 
b/clang/test/SemaHLSL/Semantics/groupindex.hlsl
index 8acdee8e85989..a33e060c82906 100644
--- a/clang/test/SemaHLSL/Semantics/groupindex.hlsl
+++ b/clang/test/SemaHLSL/Semantics/groupindex.hlsl
@@ -4,26 +4,26 @@
 [shader("compute")][numthreads(32,1,1)]
 void compute(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'pixel' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'pixel' 
shaders}}
 [shader("pixel")]
 void pixel(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'vertex' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'vertex' 
shaders}}
 [shader("vertex")]
 void vertex(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'geometry' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'geometry' 
shaders}}
 [shader("geometry")]
 void geometry(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'domain' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'domain' 
shaders}}
 [shader("domain")]
 void domain(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 
'amplification' shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 
'amplification' shaders}}
 [shader("amplification")][numthreads(32,1,1)]
 void amplification(int GI : SV_GroupIndex) {}
 
-// expected-error@+2 {{attribute 'SV_GROUPINDEX' is unsupported in 'mesh' 
shaders}}
+// expected-error@+2 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' 
shaders}}
 [shader("mesh")][numthreads(32,1,1)]
 void mesh(int GI : SV_GroupIndex) {}
diff --git a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl 
b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
index 18bae5ee322df..070075d419df1 100644
--- a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
+++ b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library 
-finclude-default-header -x hlsl -ast-dump -verify -o - %s
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_DISPATCHTHREADID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_DispatchThreadID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
 void CSMain(float ID : SV_DispatchThreadID) {
 
 }
@@ -11,71 +11,71 @@ struct ST {
   float b;
 };
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_DISPATCHTHREADID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_DispatchThreadID' only applies to a field 
or parameter of type 'uint/uint2/uint3'}}
 void CSMain2(ST ID : SV_DispatchThreadID) {
 
 }
 
 void foo() {
-// expected-warning@+1 {{'SV_DISPATCHTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
+// expected-warning@+1 {{'SV_DispatchThreadID' attribute only applies to 
parameters, non-static data members, and functions}}
   uint V : SV_DispatchThreadID;
 
 }
 
 struct ST2 {
-// expected-warning@+1 {{'SV_DISPATCHTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
+// expected-warning@+1 {{'SV_DispatchThreadID' attribute only applies to 
parameters, non-static data members, and functions}}
     static uint X : SV_DispatchThreadID;
     uint s : SV_DispatchThreadID;
 };
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GROUPID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GroupID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain_GID(float ID : SV_GroupID) {
 }
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GROUPID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GroupID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain2_GID(ST GID : SV_GroupID) {
 
 }
 
 void foo_GID() {
-// expected-warning@+1 {{'SV_GROUPID' attribute only applies to parameters, 
non-static data members, and functions}}
+// expected-warning@+1 {{'SV_GroupID' attribute only applies to parameters, 
non-static data members, and functions}}
   uint GIS : SV_GroupID;
 }
 
 struct ST2_GID {
-// expected-warning@+1 {{'SV_GROUPID' attribute only applies to parameters, 
non-static data members, and functions}}
+// expected-warning@+1 {{'SV_GroupID' attribute only applies to parameters, 
non-static data members, and functions}}
     static uint GID : SV_GroupID;
     uint s_gid : SV_GroupID;
 };
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GROUPTHREADID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain_GThreadID(float ID : SV_GroupThreadID) {
 }
 
 [numthreads(8,8,1)]
-// expected-error@+1 {{attribute 'SV_GROUPTHREADID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
+// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or 
parameter of type 'uint/uint2/uint3'}}
 void CSMain2_GThreadID(ST GID : SV_GroupThreadID) {
 
 }
 
 void foo_GThreadID() {
-// expected-warning@+1 {{'SV_GROUPTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
+// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to 
parameters, non-static data members, and functions}}
   uint GThreadIS : SV_GroupThreadID;
 }
 
 struct ST2_GThreadID {
-// expected-warning@+1 {{'SV_GROUPTHREADID' attribute only applies to 
parameters, non-static data members, and functions}}
+// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to 
parameters, non-static data members, and functions}}
     static uint GThreadID : SV_GroupThreadID;
     uint s_gthreadid : SV_GroupThreadID;
 };
 
 
 [shader("vertex")]
-// expected-error@+4 {{attribute 'SV_GROUPINDEX' is unsupported in 'vertex' 
shaders, requires compute}}
-// expected-error@+3 {{attribute 'SV_DISPATCHTHREADID' is unsupported in 
'vertex' shaders, requires compute}}
-// expected-error@+2 {{attribute 'SV_GROUPID' is unsupported in 'vertex' 
shaders, requires compute}}
-// expected-error@+1 {{attribute 'SV_GROUPTHREADID' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+4 {{attribute 'SV_GroupIndex' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+3 {{attribute 'SV_DispatchThreadID' is unsupported in 
'vertex' shaders, requires compute}}
+// expected-error@+2 {{attribute 'SV_GroupID' is unsupported in 'vertex' 
shaders, requires compute}}
+// expected-error@+1 {{attribute 'SV_GroupThreadID' is unsupported in 'vertex' 
shaders, requires compute}}
 void vs_main(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : 
SV_GroupID, uint GThreadID : SV_GroupThreadID) {}
diff --git a/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl 
b/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
index b57ce4e325ca2..124d401a9990c 100644
--- a/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.ps.size.hlsl
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl 
-finclude-default-header -o - %s -verify -verify-ignore-unexpected
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library  -x hlsl 
-finclude-default-header -o - %s -verify -verify-ignore-unexpected
 
-// expected-error@+1 {{attribute 'SV_POSITION' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
+// expected-error@+1 {{attribute 'SV_Position' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
 void main(vector<float, 5> a : SV_Position) {
 }
 
-// expected-error@+1 {{attribute 'SV_POSITION' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
+// expected-error@+1 {{attribute 'SV_Position' only applies to a field or 
parameter of type 'float/float1/float2/float3/float4'}}
 void main(int2 a : SV_Position) {
 }
diff --git a/clang/test/SemaHLSL/Semantics/position.vs.hlsl 
b/clang/test/SemaHLSL/Semantics/position.vs.hlsl
index e5e8da2484d93..19f781fa3757c 100644
--- a/clang/test/SemaHLSL/Semantics/position.vs.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.vs.hlsl
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-vertex -x hlsl 
-finclude-default-header -o - %s -verify
 
-// expected-error@+1 {{attribute 'SV_POSITION' is unsupported in 'vertex' 
shaders, requires pixel}}
+// expected-error@+1 {{attribute 'SV_Position' is unsupported in 'vertex' 
shaders, requires pixel}}
 float4 main(float4 a : SV_Position) {
   return a;
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to