llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Jonathan Zakharov (jzakharovnv)

<details>
<summary>Changes</summary>

- **[HLSL][SPIRV] Implement vk::builtin attribute**
- **[HLSL][SPIRV] Implement vk::builtin attribute**
- **[HLSL][SPIRV] Implement vk::builtin(PointSize) validation and CodeGen**


---

Patch is 30.45 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/231275.diff


21 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+8) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+33) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+7) 
- (modified) clang/include/clang/Sema/SemaHLSL.h (+1) 
- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+29) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) 
- (modified) clang/lib/Sema/SemaHLSL.cpp (+106-2) 
- (added) clang/test/AST/HLSL/vk-builtin-attr.hlsl (+29) 
- (added) clang/test/CodeGenHLSL/vk-builtin-point-size-return.hlsl (+18) 
- (added) clang/test/CodeGenHLSL/vk-builtin-point-size.hlsl (+33) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test 
(+1) 
- (added) 
clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-control.hlsl 
(+15) 
- (added) 
clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-field.hlsl (+18) 
- (added) 
clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-param.hlsl (+11) 
- (added) 
clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-return.hlsl 
(+14) 
- (added) clang/test/SemaHLSL/vk-builtin-attr-non-spirv.hlsl (+16) 
- (added) clang/test/SemaHLSL/vk-builtin-attr.hlsl (+67) 
- (added) clang/test/SemaHLSL/vk-builtin-point-size-inout-pixel.hlsl (+14) 
- (added) clang/test/SemaHLSL/vk-builtin-point-size-inout-vertex.hlsl (+14) 
- (added) clang/test/SemaHLSL/vk-builtin-point-size-invalid.hlsl (+12) 
- (added) clang/test/SemaHLSL/vk-builtin-point-size.hlsl (+12) 


``````````diff
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index b41c1c78ddd99..91af26ecaaa80 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -5462,6 +5462,14 @@ def HLSLVkLocation : HLSLAnnotationAttr {
   let Documentation = [HLSLVkLocationDocs];
 }
 
+def HLSLVkBuiltIn : HLSLAnnotationAttr, TargetSpecificAttr<TargetSPIRV> {
+  let Spellings = [CXX11<"vk", "builtin">];
+  let Args = [StringArgument<"BuiltIn">];
+  let Subjects = SubjectList<[ParmVar, Field, Function], ErrorDiag>;
+  let LangOpts = [HLSL];
+  let Documentation = [HLSLVkBuiltInDocs];
+}
+
 // `row_major` / `column_major` are HLSL keywords that select the in-memory
 // layout of a matrix-typed declaration.
 def HLSLRowMajor : TypeAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index e8ce3c3dea7f3..6a3d4a1ce01cf 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -9741,6 +9741,39 @@ This attribute maps to the `Location` SPIR-V decoration.
   }];
 }
 
+def HLSLVkBuiltInDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+Some Vulkan built-in variables have no equivalent in native HLSL, so no
+system-value semantic can express them. The `[[vk::builtin]]` attribute marks a
+stage input/output variable as a SPIR-V built-in variable, identified by name.
+Allowed on function parameters, function returns, and struct fields. This
+attribute has no effect when used outside of an entrypoint parameter/parameter
+field/return value.
+
+The attribute is only available when targeting SPIR-V. For any other target it
+is ignored with an "unknown attribute ignored" warning.
+
+The attribute takes a single string literal argument naming the built-in.
+Currently supported built-ins:
+
+* `PointSize`: the GLSL equivalent is `gl_PointSize`. Must be of floating-point
+  type. Can be used as a vertex shader output, a hull or domain shader control
+  point input or output, a geometry shader input or output, a pixel shader
+  input, or a mesh shader output.
+
+A declaration annotated with `[[vk::builtin]]` does not take part in
+`vk::location` assignment, and cannot also be annotated with 
`[[vk::location]]`.
+
+```c++
+struct VSOutput {
+  [[vk::location(0)]] float4 color : COLOR;
+  [[vk::builtin("PointSize")]] float size : PSIZE;
+};
+```
+  }];
+}
+
 def HLSLMatrixLayoutDocs : Documentation {
   let Category = DocCatVariable;
   let Heading = "row_major, column_major";
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cc87f556d50dc..12b66e5462c6e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13788,6 +13788,13 @@ def err_hlsl_semantic_unsupported_iotype_for_stage
 def err_hlsl_semantic_partial_explicit_indexing
     : Error<"partial explicit stage input location assignment via "
             "vk::location(X) unsupported">;
+def err_hlsl_vk_builtin_unsupported_value
+    : Error<"'%0' is not a supported value for the 'vk::builtin' attribute; "
+            "supported values are: %1">;
+def err_hlsl_vk_builtin_wrong_type
+    : Error<"'%0' builtin must be of type %1">;
+def err_hlsl_vk_builtin_wrong_stage
+    : Error<"'%0' builtin cannot be used as %1 shader %2">;
 
 def warn_hlsl_user_defined_type_missing_member: Warning<"binding type 
'%select{t|u|b|s|c}0' only applies to types containing %select{SRV 
resources|UAV resources|constant buffer resources|sampler state|numeric 
types}0">, InGroup<LegacyConstantRegisterBinding>;
 def err_hlsl_binding_type_mismatch: Error<"binding type '%select{t|u|b|s|c}0' 
only applies to %select{SRV resources|UAV resources|constant buffer 
resources|sampler state|numeric variables in the global scope}0">;
diff --git a/clang/include/clang/Sema/SemaHLSL.h 
b/clang/include/clang/Sema/SemaHLSL.h
index 3d62f47dfde69..160e3854d5e92 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -186,6 +186,7 @@ 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 handleVkBuiltInAttr(Decl *D, const ParsedAttr &AL);
   void handleVkLocationAttr(Decl *D, const ParsedAttr &AL);
   void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
   void handleShaderAttr(Decl *D, const ParsedAttr &AL);
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index f770981935952..8b3c5fbf42c3d 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -36,6 +36,7 @@
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Frontend/HLSL/HLSLResource.h"
 #include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
 #include "llvm/IR/Constants.h"
@@ -1570,6 +1571,18 @@ static void createSPIRVBuiltinStore(IRBuilder<> &B, 
llvm::Module &M,
   B.CreateStore(Source, GV);
 }
 
+// Maps a [[vk::builtin(...)]] name to its SPIR-V spec `BuiltIn` decoration.
+// Deliberately not creating dependency on llvm::SPIRV::BuiltIn in front end.
+// Sema's handleVkBuiltInAttr only allows names handled here to reach CodeGen.
+static unsigned getSPIRVVkBuiltinID(StringRef BuiltIn) {
+  unsigned ID = llvm::StringSwitch<unsigned>(BuiltIn)
+                    .Case("PointSize", /* BuiltIn::PointSize */ 1)
+                    .Default(-1);
+  assert(ID != static_cast<unsigned>(-1) &&
+         "Sema should only allow builtin names implemented here");
+  return ID;
+}
+
 void CGHLSLRuntime::emitSystemSemanticStore(
     IRBuilder<> &B, llvm::Value *Source, const clang::DeclaratorDecl *Decl,
     HLSLAppliedSemanticAttr *Semantic,
@@ -1618,6 +1631,14 @@ llvm::Value *CGHLSLRuntime::handleScalarSemanticLoad(
     const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic,
     SemanticSignatures &Signature) {
 
+  // [[vk::builtin(...)]] takes precedence over the recognized-semantic
+  // dispatch, so without this check they'd always be treated as an arbitrary
+  // user semantic. The attribute is only ever attached when targeting SPIR-V.
+  if (const auto *BuiltInAttr = Decl->getAttr<HLSLVkBuiltInAttr>())
+    return createSPIRVBuiltinLoad(
+        B, CGM.getModule(), Type, Semantic->getAttrName()->getName(),
+        getSPIRVVkBuiltinID(BuiltInAttr->getBuiltIn()));
+
   std::optional<unsigned> Index = Semantic->getSemanticIndex();
   llvm::dxbc::PSV::SemanticKind SemanticKind =
       llvm::hlsl::getSemanticKind(Semantic->getAttrName()->getName());
@@ -1640,6 +1661,14 @@ void 
CGHLSLRuntime::handleScalarSemanticStore(IRBuilder<> &B,
                                               const clang::DeclaratorDecl 
*Decl,
                                               HLSLAppliedSemanticAttr 
*Semantic,
                                               SemanticSignatures &Signature) {
+  // See the matching comment in `handleScalarSemanticLoad`
+  if (const auto *BuiltInAttr = Decl->getAttr<HLSLVkBuiltInAttr>()) {
+    createSPIRVBuiltinStore(B, CGM.getModule(), Source,
+                            Semantic->getAttrName()->getName(),
+                            getSPIRVVkBuiltinID(BuiltInAttr->getBuiltIn()));
+    return;
+  }
+
   std::optional<unsigned> Index = Semantic->getSemanticIndex();
   llvm::dxbc::PSV::SemanticKind SemanticKind =
       llvm::hlsl::getSemanticKind(Semantic->getAttrName()->getName());
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 9e76c640fd339..b2bd95f11a659 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8299,6 +8299,9 @@ ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr 
&AL,
   case ParsedAttr::AT_HLSLVkExtBuiltinOutput:
     S.HLSL().handleVkExtBuiltinOutputAttr(D, AL);
     break;
+  case ParsedAttr::AT_HLSLVkBuiltIn:
+    S.HLSL().handleVkBuiltInAttr(D, AL);
+    break;
   case ParsedAttr::AT_HLSLVkPushConstant:
     S.HLSL().handleVkPushConstantAttr(D, AL);
     break;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4fe7ed151e918..0a8c3d9ee79c6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -46,6 +46,7 @@
 #include "llvm/Support/DXILABI.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include <algorithm>
 #include <cmath>
@@ -983,8 +984,13 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
 }
 
 static bool isVkPipelineBuiltin(const ASTContext &AstContext, FunctionDecl *FD,
+                                const DeclaratorDecl *D,
                                 HLSLAppliedSemanticAttr *Semantic,
                                 bool IsInput) {
+  // Explicitly annotated built-ins skip location assignment
+  if (D->hasAttr<HLSLVkBuiltInAttr>())
+    return true;
+
   if (AstContext.getTargetInfo().getTriple().getOS() != llvm::Triple::Vulkan)
     return false;
 
@@ -1009,6 +1015,46 @@ static bool isVkPipelineBuiltin(const ASTContext 
&AstContext, FunctionDecl *FD,
   }
 }
 
+static void validateVkBuiltinUsage(Sema &S, FunctionDecl *FD,
+                                   const DeclaratorDecl *D,
+                                   const HLSLVkBuiltInAttr *Attr,
+                                   IOType CurrentIOType) {
+  const ASTContext &AstContext = S.getASTContext();
+  if (AstContext.getTargetInfo().getTriple().getOS() != llvm::Triple::Vulkan)
+    return;
+
+  StringRef BuiltIn = Attr->getBuiltIn();
+
+  QualType T =
+      (D == FD ? FD->getReturnType() : D->getType()).getNonReferenceType();
+  const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>();
+  assert(ShaderAttr && "Entry point has no shader attribute");
+  llvm::Triple::EnvironmentType Stage = ShaderAttr->getType();
+  bool IsIn = any(CurrentIOType & IOType::In);
+  bool IsOut = any(CurrentIOType & IOType::Out);
+
+  if (BuiltIn == "PointSize") {
+    if (!T->isFloatingType())
+      S.Diag(Attr->getLocation(), diag::err_hlsl_vk_builtin_wrong_type)
+          << BuiltIn << S.getASTContext().FloatTy;
+
+    bool LegalStage = (Stage == llvm::Triple::Vertex && IsOut) ||
+                      Stage == llvm::Triple::Hull ||
+                      Stage == llvm::Triple::Domain ||
+                      Stage == llvm::Triple::Geometry ||
+                      (Stage == llvm::Triple::Pixel && IsIn) ||
+                      (Stage == llvm::Triple::Mesh && IsOut);
+    if (!LegalStage) {
+      StringRef IOTypeName = (IsIn && IsOut) ? "inputs and outputs"
+                             : IsIn          ? "inputs"
+                                             : "outputs";
+      S.Diag(Attr->getLocation(), diag::err_hlsl_vk_builtin_wrong_stage)
+          << BuiltIn << llvm::Triple::getEnvironmentTypeName(Stage)
+          << IOTypeName;
+    }
+  }
+}
+
 bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD,
                                                DeclaratorDecl *OutputDecl,
                                                DeclaratorDecl *D,
@@ -1048,8 +1094,14 @@ bool 
SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD,
 
   unsigned Location = ActiveSemantic.Index.value_or(0);
 
-  if (!isVkPipelineBuiltin(getASTContext(), FD, A,
-                           any(SC.CurrentIOType & IOType::In))) {
+  bool IsBuiltin = isVkPipelineBuiltin(getASTContext(), FD, D, A,
+                                       any(SC.CurrentIOType & IOType::In));
+  if (IsBuiltin) {
+    if (const auto *BuiltInAttr = D->getAttr<HLSLVkBuiltInAttr>())
+      validateVkBuiltinUsage(SemaRef, FD, D, BuiltInAttr, SC.CurrentIOType);
+  }
+
+  if (!IsBuiltin) {
     bool HasVkLocation = false;
     if (auto *A = D->getAttr<HLSLVkLocationAttr>()) {
       HasVkLocation = true;
@@ -2157,10 +2209,62 @@ void SemaHLSL::handleVkLocationAttr(Decl *D, const 
ParsedAttr &AL) {
   if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Location))
     return;
 
+<<<<<<< HEAD
+  // vk::builtin and vk::location mutually exclusive
+=======
+  // `vk::builtin` and `vk::location` are mutually exclusive. Diagnose but
+  // still attach: DXC accumulates diagnostics rather than short-circuiting
+  // (a single decl can simultaneously violate this, a builtin's required
+  // type, and its legal stage), so later checks must still be able to see
+  // this attribute rather than silently never running.
+>>>>>>> 9ecd11ae9b5d ([HLSL][SPIRV] Implement vk::builtin attribute)
+  if (const auto *BuiltIn = D->getAttr<HLSLVkBuiltInAttr>()) {
+    Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+        << AL << BuiltIn
+        << (AL.isRegularKeywordAttribute() ||
+            BuiltIn->isRegularKeywordAttribute());
+    Diag(BuiltIn->getLocation(), diag::note_conflicting_attribute);
+  }
+
   D->addAttr(::new (getASTContext())
                  HLSLVkLocationAttr(getASTContext(), AL, Location));
 }
 
+void SemaHLSL::handleVkBuiltInAttr(Decl *D, const ParsedAttr &AL) {
+  StringRef BuiltIn;
+  SourceLocation ArgLoc;
+  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, BuiltIn, &ArgLoc))
+    return;
+
+  static constexpr StringRef SupportedBuiltIns[] = {
+      "PointSize", // TODO: uncomment build-ins as they're fully implemented
+                   // "HelperInvocation", "BaseVertex", "BaseInstance",
+                   // "DrawIndex", "DeviceIndex", "ViewportMaskNV",
+  };
+  if (!llvm::is_contained(SupportedBuiltIns, BuiltIn)) {
+    std::string Quoted;
+    llvm::raw_string_ostream OS(Quoted);
+    llvm::interleaveComma(SupportedBuiltIns, OS,
+                          [&](StringRef S) { OS << "'" << S << "'"; });
+    Diag(ArgLoc, diag::err_hlsl_vk_builtin_unsupported_value)
+        << BuiltIn << Quoted;
+    return;
+  }
+
+  // `vk::builtin` and `vk::location` are mutually exclusive. Diagnose but
+  // still attach -- see the matching comment in handleVkLocationAttr.
+  if (const auto *Location = D->getAttr<HLSLVkLocationAttr>()) {
+    Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+        << AL << Location
+        << (AL.isRegularKeywordAttribute() ||
+            Location->isRegularKeywordAttribute());
+    Diag(Location->getLoc(), diag::note_conflicting_attribute);
+  }
+
+  D->addAttr(::new (getASTContext())
+                 HLSLVkBuiltInAttr(getASTContext(), AL, BuiltIn));
+}
+
 void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
   uint32_t IndexValue(0), ExplicitIndex(0);
   if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), IndexValue) ||
diff --git a/clang/test/AST/HLSL/vk-builtin-attr.hlsl 
b/clang/test/AST/HLSL/vk-builtin-attr.hlsl
new file mode 100644
index 0000000000000..16d42a0b13637
--- /dev/null
+++ b/clang/test/AST/HLSL/vk-builtin-attr.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library 
-finclude-default-header -ast-dump -o - %s | FileCheck %s 
-check-prefixes=CHECK,SPV
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-library 
-finclude-default-header -ast-dump -o - %s | FileCheck %s 
-check-prefixes=CHECK,DXIL
+
+// vk::builtin only exists when targeting SPIR-V.
+
+// CHECK: CXXRecordDecl {{.*}} struct S definition
+// CHECK: FieldDecl {{.*}} a 'float'
+// SPV-NEXT: HLSLVkBuiltInAttr {{.*}} "PointSize"
+// DXIL-NOT: HLSLVkBuiltInAttr
+// CHECK: HLSLParsedSemanticAttr {{.*}} "PSIZE"
+// CHECK: FieldDecl {{.*}} b 'float'
+// CHECK-NEXT: HLSLVkLocationAttr {{.*}} 1
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "B"
+struct S {
+  [[vk::builtin("PointSize")]] float a : PSIZE;
+  [[vk::location(1)]] float b : B;
+};
+
+// CHECK: FunctionDecl {{.*}} param 'float (float)'
+// CHECK-NEXT: ParmVarDecl {{.*}} p 'float'
+// SPV-NEXT: HLSLVkBuiltInAttr {{.*}} "PointSize"
+// DXIL-NOT: HLSLVkBuiltInAttr
+// CHECK: HLSLParsedSemanticAttr {{.*}} "PSIZE"
+float param([[vk::builtin("PointSize")]] float p : PSIZE) : A { return p; }
+
+// CHECK: FunctionDecl {{.*}} func 'float ()'
+// SPV: HLSLVkBuiltInAttr {{.*}} "PointSize"
+// DXIL-NOT: HLSLVkBuiltInAttr
+[[vk::builtin("PointSize")]] float func() : PSIZE { return 1.0f; }
diff --git a/clang/test/CodeGenHLSL/vk-builtin-point-size-return.hlsl 
b/clang/test/CodeGenHLSL/vk-builtin-point-size-return.hlsl
new file mode 100644
index 0000000000000..2e999f3226b31
--- /dev/null
+++ b/clang/test/CodeGenHLSL/vk-builtin-point-size-return.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan1.3-vertex 
-hlsl-entry main -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+
+// Same as vk-builtin-point-size.hlsl, but [[vk::builtin("PointSize")]]
+// annotates the entry point's return value (the Function subject) rather
+// than a struct field.
+
+[[vk::builtin("PointSize")]]
+[shader("vertex")]
+float main([[vk::location(0)]] float4 a : A) : PSIZE {
+  return a.x;
+}
+
+// CHECK: @PSIZE = {{.*}} addrspace(8) global float, !spirv.Decorations 
[[PSIZE_DECO:![0-9]+]]
+// CHECK: define void @main()
+// CHECK: [[PT_SIZE:%[0-9]+]] = call spir_func float @{{.*}}main{{.*}}
+// CHECK-NEXT: store float [[PT_SIZE]], ptr addrspace(8) @PSIZE
+// CHECK-DAG: [[PSIZE_DECO]] = !{[[PSIZE_OP:![0-9]+]]}
+// CHECK-DAG: [[PSIZE_OP]] = !{i32 11, i32 1}
diff --git a/clang/test/CodeGenHLSL/vk-builtin-point-size.hlsl 
b/clang/test/CodeGenHLSL/vk-builtin-point-size.hlsl
new file mode 100644
index 0000000000000..a1f42192c9b91
--- /dev/null
+++ b/clang/test/CodeGenHLSL/vk-builtin-point-size.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan1.3-vertex 
-hlsl-entry main -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.8-vertex -hlsl-entry main -emit-llvm -disable-llvm-passes 
-o - %s | FileCheck %s --check-prefix=DXIL
+
+// On SPIR-V, [[vk::builtin("PointSize")]] lowers to a BuiltIn PointSize
+// decoration instead of an ordinary Location-based user semantic. The
+// attribute doesn't exist on DXIL, so there PSIZE is an ordinary semantic.
+
+struct VSOutput {
+  float4 pos : SV_Position;
+  float4 color : COLOR;
+  [[vk::builtin("PointSize")]] float size : PSIZE;
+};
+
+[shader("vertex")]
+VSOutput main() {
+  VSOutput output = (VSOutput)0;
+  return output;
+}
+
+// CHECK: @COLOR0 = {{.*}}!spirv.Decorations ![[COLOR_MD:[0-9]+]]
+// CHECK: @PSIZE = {{.*}}addrspace(8){{.*}}!spirv.Decorations 
![[PSIZE_MD:[0-9]+]]
+// CHECK: define void @main()
+// CHECK: store float %{{.*}}, ptr addrspace(8) @PSIZE
+
+// BuiltIn decoration (11) with value 1 (PointSize), vs. COLOR0's Location 
(30).
+// CHECK: ![[COLOR_MD]] = !{![[COLOR_DEC:[0-9]+]]}
+// CHECK: ![[COLOR_DEC]] = !{i32 30,
+// CHECK: ![[PSIZE_MD]] = !{![[PSIZE_DEC:[0-9]+]]}
+// CHECK: ![[PSIZE_DEC]] = !{i32 11, i32 1}
+
+// DXIL: define void @main()
+// DXIL-NOT: PointSize
+// DXIL: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"PSIZE",
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 8f8c1aa3d3f9c..05e4e86f22f9d 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -90,6 +90,7 @@
 // CHECK-NEXT: GCCStruct (SubjectMatchRule_record)
 // CHECK-NEXT: GNUInline (SubjectMatchRule_function)
 // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable)
+// CHECK-NEXT: HLSLVkBuiltIn (SubjectMatchRule_variable_is_parameter, 
SubjectMatchRule_field, SubjectMatchRule_function)
 // CHECK-NEXT: HLSLVkLocation (SubjectMatchRule_variable_is_parameter, 
SubjectMatchRule_field, SubjectMatchRule_function)
 // CHECK-NEXT: HLSLVkPushConstant (SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: Hot (SubjectMatchRule_function)
diff --git 
a/clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-control.hlsl 
b/clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-control.hlsl
new file mode 100644
index 0000000000000..77079ae318970
--- /dev/null
+++ 
b/clang/test/SemaHLSL/Semantics/semantic.explicit-mix-vk-builtin-control.hlsl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
spirv-unknown-vulkan1.3-vertex -hlsl-entry main1 -fsyntax-only -verify 
-verify-ignore-unexpected=note %s
+
+// Control for semantic.expli...
[truncated]

``````````

</details>


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

Reply via email to