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

From 3d4cce9aeda612df3da7f73d6c32a862822e14b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <[email protected]>
Date: Wed, 19 Nov 2025 16:50:50 +0100
Subject: [PATCH 1/2] [HLSL][SPIR-V] Implements SV_Position for VS/PS I/O

Current implementation for SV_Position was very basic to allow
implementing/testing some semantics. Now that semantic support
is more robust, I can move forward and implement the whole
semantic logic.

DX part is still a bit placeholder.
---
 clang/include/clang/Sema/SemaHLSL.h           | 11 ++++--
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 29 ++++++++++-----
 clang/lib/Sema/SemaHLSL.cpp                   | 37 ++++++++++++-------
 .../CodeGenHLSL/semantics/SV_Position.ps.hlsl | 20 +++++++---
 .../CodeGenHLSL/semantics/SV_Position.vs.hlsl | 26 +++++++++++++
 .../test/SemaHLSL/Semantics/position.ps.hlsl  | 14 ++-----
 .../test/SemaHLSL/Semantics/position.vs.hlsl  |  6 ---
 .../CodeGen/SPIRV/semantics/position.ps.ll    | 32 ++++++++++++++++
 .../CodeGen/SPIRV/semantics/position.vs.ll    | 31 ++++++++++++++++
 9 files changed, 159 insertions(+), 47 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
 delete mode 100644 clang/test/SemaHLSL/Semantics/position.vs.hlsl
 create mode 100644 llvm/test/CodeGen/SPIRV/semantics/position.ps.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/semantics/position.vs.ll

diff --git a/clang/include/clang/Sema/SemaHLSL.h 
b/clang/include/clang/Sema/SemaHLSL.h
index 86da323892f98..15edb7e77a22b 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -250,15 +250,20 @@ class SemaHLSL : public SemaBase {
                                                const RecordType *RT);
 
   void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
-                               const HLSLAppliedSemanticAttr *SemanticAttr);
+                               const HLSLAppliedSemanticAttr *SemanticAttr,
+                               bool IsInput);
+
   bool determineActiveSemanticOnScalar(FunctionDecl *FD,
                                        DeclaratorDecl *OutputDecl,
                                        DeclaratorDecl *D,
                                        SemanticInfo &ActiveSemantic,
-                                       llvm::StringSet<> 
&ActiveInputSemantics);
+                                       llvm::StringSet<> &ActiveSemantics,
+                                       bool IsInput);
+
   bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *OutputDecl,
                                DeclaratorDecl *D, SemanticInfo &ActiveSemantic,
-                               llvm::StringSet<> &ActiveInputSemantics);
+                               llvm::StringSet<> &ActiveSemantics,
+                               bool IsInput);
 
   void processExplicitBindingsOnDecl(VarDecl *D);
 
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 2a5f3f6895609..daaaa1d5004a9 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -731,10 +731,18 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
   }
 
   if (SemanticName == "SV_POSITION") {
-    if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
-      return createSPIRVBuiltinLoad(B, CGM.getModule(), Type,
-                                    Semantic->getAttrName()->getName(),
-                                    /* BuiltIn::FragCoord */ 15);
+    if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) {
+      if (CGM.getTarget().getTriple().isSPIRV())
+        return createSPIRVBuiltinLoad(B, CGM.getModule(), Type,
+                                      Semantic->getAttrName()->getName(),
+                                      /* BuiltIn::FragCoord */ 15);
+      if (CGM.getTarget().getTriple().isDXIL())
+        return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
+    }
+
+    if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Vertex) {
+      return emitUserSemanticLoad(B, Type, Decl, Semantic, Index);
+    }
   }
 
   llvm_unreachable("non-handled system semantic. FIXME.");
@@ -760,11 +768,14 @@ void CGHLSLRuntime::emitSystemSemanticStore(IRBuilder<> 
&B, llvm::Value *Source,
                                             std::optional<unsigned> Index) {
 
   std::string SemanticName = Semantic->getAttrName()->getName().upper();
-  if (SemanticName == "SV_POSITION")
-    createSPIRVBuiltinStore(B, CGM.getModule(), Source,
-                            Semantic->getAttrName()->getName(),
-                            /* BuiltIn::Position */ 0);
-  else
+  if (SemanticName == "SV_POSITION") {
+    if (CGM.getTarget().getTriple().isDXIL())
+      emitDXILUserSemanticStore(B, Source, Semantic, Index);
+    else if (CGM.getTarget().getTriple().isSPIRV())
+      createSPIRVBuiltinStore(B, CGM.getModule(), Source,
+                              Semantic->getAttrName()->getName(),
+                              /* BuiltIn::Position */ 0);
+  } else
     llvm_unreachable("non-handled system semantic. FIXME.");
 }
 
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index c5666941fd36a..4eac34c90e6bc 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -771,9 +771,12 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
   }
 }
 
-bool SemaHLSL::determineActiveSemanticOnScalar(
-    FunctionDecl *FD, DeclaratorDecl *OutputDecl, DeclaratorDecl *D,
-    SemanticInfo &ActiveSemantic, llvm::StringSet<> &UsedSemantics) {
+bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD,
+                                               DeclaratorDecl *OutputDecl,
+                                               DeclaratorDecl *D,
+                                               SemanticInfo &ActiveSemantic,
+                                               llvm::StringSet<> 
&UsedSemantics,
+                                               bool IsInput) {
   if (ActiveSemantic.Semantic == nullptr) {
     ActiveSemantic.Semantic = D->getAttr<HLSLParsedSemanticAttr>();
     if (ActiveSemantic.Semantic)
@@ -792,7 +795,7 @@ bool SemaHLSL::determineActiveSemanticOnScalar(
   if (!A)
     return false;
 
-  checkSemanticAnnotation(FD, D, A);
+  checkSemanticAnnotation(FD, D, A, IsInput);
   OutputDecl->addAttr(A);
 
   unsigned Location = ActiveSemantic.Index.value_or(0);
@@ -820,7 +823,8 @@ bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD,
                                        DeclaratorDecl *OutputDecl,
                                        DeclaratorDecl *D,
                                        SemanticInfo &ActiveSemantic,
-                                       llvm::StringSet<> &UsedSemantics) {
+                                       llvm::StringSet<> &UsedSemantics,
+                                       bool IsInput) {
   if (ActiveSemantic.Semantic == nullptr) {
     ActiveSemantic.Semantic = D->getAttr<HLSLParsedSemanticAttr>();
     if (ActiveSemantic.Semantic)
@@ -833,12 +837,13 @@ bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD,
   const RecordType *RT = dyn_cast<RecordType>(T);
   if (!RT)
     return determineActiveSemanticOnScalar(FD, OutputDecl, D, ActiveSemantic,
-                                           UsedSemantics);
+                                           UsedSemantics, IsInput);
 
   const RecordDecl *RD = RT->getDecl();
   for (FieldDecl *Field : RD->fields()) {
     SemanticInfo Info = ActiveSemantic;
-    if (!determineActiveSemantic(FD, OutputDecl, Field, Info, UsedSemantics)) {
+    if (!determineActiveSemantic(FD, OutputDecl, Field, Info, UsedSemantics,
+                                 IsInput)) {
       Diag(Field->getLocation(), diag::note_hlsl_semantic_used_here) << Field;
       return false;
     }
@@ -920,7 +925,7 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
 
     // FIXME: Verify output semantics in parameters.
     if (!determineActiveSemantic(FD, Param, Param, ActiveSemantic,
-                                 ActiveInputSemantics)) {
+                                 ActiveInputSemantics, /* IsInput= */ true)) {
       Diag(Param->getLocation(), diag::note_previous_decl) << Param;
       FD->setInvalidDecl();
     }
@@ -932,12 +937,13 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
   if (ActiveSemantic.Semantic)
     ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
   if (!FD->getReturnType()->isVoidType())
-    determineActiveSemantic(FD, FD, FD, ActiveSemantic, ActiveOutputSemantics);
+    determineActiveSemantic(FD, FD, FD, ActiveSemantic, ActiveOutputSemantics,
+                            /* IsInput= */ false);
 }
 
 void SemaHLSL::checkSemanticAnnotation(
     FunctionDecl *EntryPoint, const Decl *Param,
-    const HLSLAppliedSemanticAttr *SemanticAttr) {
+    const HLSLAppliedSemanticAttr *SemanticAttr, bool IsInput) {
   auto *ShaderAttr = EntryPoint->getAttr<HLSLShaderAttr>();
   assert(ShaderAttr && "Entry point has no shader attribute");
   llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
@@ -961,11 +967,14 @@ void SemaHLSL::checkSemanticAnnotation(
   }
 
   if (SemanticName == "SV_POSITION") {
-    // TODO(#143523): allow use on other shader types & output once the overall
-    // semantic logic is implemented.
-    if (ST == llvm::Triple::Pixel)
+    // SV_Position can is I/O for vertex shaders.
+    // For pixel shaders, only valid as input.
+    // Note: for SPIR-V, not backed by a builtin when used as input in a vertex
+    // shaders.
+    if (ST == llvm::Triple::Vertex || (ST == llvm::Triple::Pixel && IsInput))
       return;
-    DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Pixel});
+    DiagnoseAttrStageMismatch(SemanticAttr, ST,
+                              {llvm::Triple::Pixel, llvm::Triple::Vertex});
     return;
   }
 
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
index be30e79438831..b7d2283ea7766 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
@@ -1,11 +1,21 @@
-// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-pixel -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s 
--check-prefix=CHECK-SPIRV
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s 
--check-prefix=CHECK-DXIL
 
-// CHECK: @SV_Position = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
+// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]]
 
 // CHECK: define void @main() {{.*}} {
 float4 main(float4 p : SV_Position) : A {
-  // 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]])
-  // CHECK:            store <4 x float> %[[#R]], ptr addrspace(8) @A0, align 
16
+  // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position, 
align 16
+  // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x 
float> %[[#P]])
+  // CHECK-SPIRV:            store <4 x float> %[[#R]], ptr addrspace(8) @A0, 
align 16
+
+  // CHECK-DXIL: %SV_Position0 = call <4 x float> 
@llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+  // CHECK-DXIL:    %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> 
%SV_Position0)
+  // CHECK-DXIL:                 call void @llvm.dx.store.output.v4f32(i32 4, 
i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
   return p;
 }
+
+// CHECK-SPIRV-DAG: ![[#MD_0]] = !{![[#MD_1:]]}
+// CHECK-SPIRV-DAG: ![[#MD_1]] = !{i32 11, i32 15}
+//                                      |       `-> BuiltIn Position
+//                                      `-> SPIR-V decoration 'FragCoord'
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl 
b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
new file mode 100644
index 0000000000000..0156c0bb816c1
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.8-vertex -x hlsl 
-emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck 
--check-prefix=CHECK-DXIL %s
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex -x hlsl -emit-llvm 
-finclude-default-header -disable-llvm-passes -o - %s | FileCheck 
--check-prefix=CHECK-SPIRV  %s
+
+// CHECK-SPIRV: @SV_Position0 = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]]
+// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(8) 
global <4 x float>, !spirv.Decorations ![[#MD_2:]]
+
+// CHECK: define void @main() {{.*}} {
+float4 main(float4 p : SV_Position) : SV_Position {
+  // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position0, 
align 16
+  // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x 
float> %[[#P]])
+  // CHECK-SPIRV:            store <4 x float> %[[#R]], ptr addrspace(8) 
@SV_Position, align 16
+
+  // CHECK-DXIL: %SV_Position0 = call <4 x float> 
@llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+  // CHECK-DXIL:    %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> 
%SV_Position0)
+  // CHECK-DXIL:                 call void @llvm.dx.store.output.v4f32(i32 4, 
i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+  return p;
+}
+
+// CHECK-SPIRV-DAG: ![[#MD_0]] = !{![[#MD_1:]]}
+// CHECK-SPIRV-DAG: ![[#MD_2]] = !{![[#MD_3:]]}
+// CHECK-SPIRV-DAG: ![[#MD_1]] = !{i32 30, i32 0}
+//                                      |       `-> Location 0
+//                                      `-> SPIR-V decoration 'Location'
+// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 11, i32 0}
+//                                      |       `-> BuiltIn Position
+//                                      `-> SPIR-V decoration 'BuiltIn'
diff --git a/clang/test/SemaHLSL/Semantics/position.ps.hlsl 
b/clang/test/SemaHLSL/Semantics/position.ps.hlsl
index 2d02384821d90..47d07887911d6 100644
--- a/clang/test/SemaHLSL/Semantics/position.ps.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.ps.hlsl
@@ -1,13 +1,7 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl 
-finclude-default-header -o - %s -ast-dump | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel 
-finclude-default-header -x hlsl -verify -o - %s
+// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -finclude-default-header 
-x hlsl -verify -o - %s
 
-// FIXME(Keenuts): change output semantic to something valid for pixels shaders
-float4 main(float4 a : SV_Position2) : A {
-// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 
'float4 (float4)'
-// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 used a 
'float4':'vector<float, 4>'
-// CHECK-NEXT:  HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} <col:24> "SV_Position" 2
-// CHECK-NEXT:  HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} <col:24> "SV_Position" 
2
-
-// CHECK:       HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} <line:4:40> "A" 0
-// CHECK:       HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} <col:40> "A" 0
+float4 main(float4 a : A) : SV_Position {
+// expected-error@-1 {{attribute 'SV_Position' is unsupported in 'pixel' 
shaders, requires one of the following: pixel, vertex}}
   return a;
 }
diff --git a/clang/test/SemaHLSL/Semantics/position.vs.hlsl 
b/clang/test/SemaHLSL/Semantics/position.vs.hlsl
deleted file mode 100644
index 9d0ff285ce055..0000000000000
--- a/clang/test/SemaHLSL/Semantics/position.vs.hlsl
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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}}
-float4 main(float4 a : SV_Position) : A {
-  return a;
-}
diff --git a/llvm/test/CodeGen/SPIRV/semantics/position.ps.ll 
b/llvm/test/CodeGen/SPIRV/semantics/position.ps.ll
new file mode 100644
index 0000000000000..2c02987f73928
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/semantics/position.ps.ll
@@ -0,0 +1,32 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-vulkan-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-unknown %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK-DAG:        OpDecorate %[[#INPUT:]] BuiltIn FragCoord
+; CHECK-DAG:        OpDecorate %[[#OUTPUT:]] Location 0
+
+; CHECK-DAG:   %[[#float:]] = OpTypeFloat 32
+; CHECK-DAG:      %[[#v4:]] = OpTypeVector %[[#float]] 4
+; CHECK-DAG:   %[[#ptr_i:]] = OpTypePointer Input %[[#v4]]
+; CHECK-DAG:   %[[#ptr_o:]] = OpTypePointer Output %[[#v4]]
+
+; CHECK-DAG:      %[[#INPUT]] = OpVariable %[[#ptr_i]] Input
+; CHECK-DAG:      %[[#OUTPUT]] = OpVariable %[[#ptr_o]] Output
+
+@SV_Position = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
+@A0 = external hidden thread_local addrspace(8) global <4 x float>, 
!spirv.Decorations !2
+
+define void @main() #1 {
+entry:
+  %0 = load <4 x float>, ptr addrspace(7) @SV_Position, align 16
+  store <4 x float> %0, ptr addrspace(8) @A0, align 16
+  ret void
+
+; CHECK: %[[#TMP:]] = OpLoad %[[#v4]] %[[#INPUT]] Aligned 16
+; CHECK:              OpStore %[[#OUTPUT]] %[[#TMP]] Aligned 16
+}
+
+!0 = !{!1}
+!1 = !{i32 11, i32 15}
+!2 = !{!3}
+!3 = !{i32 30, i32 0}
+
diff --git a/llvm/test/CodeGen/SPIRV/semantics/position.vs.ll 
b/llvm/test/CodeGen/SPIRV/semantics/position.vs.ll
new file mode 100644
index 0000000000000..73165f3719a97
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/semantics/position.vs.ll
@@ -0,0 +1,31 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-vulkan-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-unknown %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK-DAG:        OpDecorate %[[#INPUT:]] Location 0
+; CHECK-DAG:        OpDecorate %[[#OUTPUT:]] BuiltIn Position
+
+; CHECK-DAG:   %[[#float:]] = OpTypeFloat 32
+; CHECK-DAG:      %[[#v4:]] = OpTypeVector %[[#float]] 4
+; CHECK-DAG:   %[[#ptr_i:]] = OpTypePointer Input %[[#v4]]
+; CHECK-DAG:   %[[#ptr_o:]] = OpTypePointer Output %[[#v4]]
+
+; CHECK-DAG:      %[[#INPUT]] = OpVariable %[[#ptr_i]] Input
+; CHECK-DAG:      %[[#OUTPUT]] = OpVariable %[[#ptr_o]] Output
+
+@SV_Position0 = external hidden thread_local addrspace(7) 
externally_initialized constant <4 x float>, !spirv.Decorations !0
+@SV_Position = external hidden thread_local addrspace(8) global <4 x float>, 
!spirv.Decorations !2
+
+define void @main() #1 {
+entry:
+  %0 = load <4 x float>, ptr addrspace(7) @SV_Position0, align 16
+  store <4 x float> %0, ptr addrspace(8) @SV_Position, align 16
+  ret void
+
+; CHECK: %[[#TMP:]] = OpLoad %[[#v4]] %[[#INPUT]] Aligned 16
+; CHECK:              OpStore %[[#OUTPUT]] %[[#TMP]] Aligned 16
+}
+
+!0 = !{!1}
+!1 = !{i32 30, i32 0}
+!2 = !{!3}
+!3 = !{i32 11, i32 0}

From f0f3c6ffc9c6f00296faef0186e49a68411af3f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <[email protected]>
Date: Fri, 21 Nov 2025 16:36:53 +0100
Subject: [PATCH 2/2] pr-feedback

---
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 18 +++++++++++----
 clang/lib/Sema/SemaHLSL.cpp                   |  6 ++---
 .../HLSL/semantic-input-struct-shadow.hlsl    | 21 +++++++++++++++++
 .../test/AST/HLSL/semantic-input-struct.hlsl  | 20 ++++++++++++++++
 clang/test/AST/HLSL/semantic-input.hlsl       |  9 ++++++++
 .../HLSL/semantic-output-struct-shadow.hlsl   | 23 +++++++++++++++++++
 .../test/AST/HLSL/semantic-output-struct.hlsl | 22 ++++++++++++++++++
 clang/test/AST/HLSL/semantic-output.hlsl      |  9 ++++++++
 8 files changed, 119 insertions(+), 9 deletions(-)
 create mode 100644 clang/test/AST/HLSL/semantic-input-struct-shadow.hlsl
 create mode 100644 clang/test/AST/HLSL/semantic-input-struct.hlsl
 create mode 100644 clang/test/AST/HLSL/semantic-input.hlsl
 create mode 100644 clang/test/AST/HLSL/semantic-output-struct-shadow.hlsl
 create mode 100644 clang/test/AST/HLSL/semantic-output-struct.hlsl
 create mode 100644 clang/test/AST/HLSL/semantic-output.hlsl

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index daaaa1d5004a9..f5c07fe2e33ff 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -745,7 +745,8 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
     }
   }
 
-  llvm_unreachable("non-handled system semantic. FIXME.");
+  llvm_unreachable(
+      "Load hasn't been implemented yet for this system semantic. FIXME");
 }
 
 static void createSPIRVBuiltinStore(IRBuilder<> &B, llvm::Module &M,
@@ -769,14 +770,21 @@ void CGHLSLRuntime::emitSystemSemanticStore(IRBuilder<> 
&B, llvm::Value *Source,
 
   std::string SemanticName = Semantic->getAttrName()->getName().upper();
   if (SemanticName == "SV_POSITION") {
-    if (CGM.getTarget().getTriple().isDXIL())
+    if (CGM.getTarget().getTriple().isDXIL()) {
       emitDXILUserSemanticStore(B, Source, Semantic, Index);
-    else if (CGM.getTarget().getTriple().isSPIRV())
+      return;
+    }
+
+    if (CGM.getTarget().getTriple().isSPIRV()) {
       createSPIRVBuiltinStore(B, CGM.getModule(), Source,
                               Semantic->getAttrName()->getName(),
                               /* BuiltIn::Position */ 0);
-  } else
-    llvm_unreachable("non-handled system semantic. FIXME.");
+      return;
+    }
+  }
+
+  llvm_unreachable(
+      "Store hasn't been implemented yet for this system semantic. FIXME");
 }
 
 llvm::Value *CGHLSLRuntime::handleScalarSemanticLoad(
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4eac34c90e6bc..3c746230a7c60 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -967,10 +967,8 @@ void SemaHLSL::checkSemanticAnnotation(
   }
 
   if (SemanticName == "SV_POSITION") {
-    // SV_Position can is I/O for vertex shaders.
-    // For pixel shaders, only valid as input.
-    // Note: for SPIR-V, not backed by a builtin when used as input in a vertex
-    // shaders.
+    // SV_Position can be an input or output in vertex shaders,
+    // but only an input in pixel shaders.
     if (ST == llvm::Triple::Vertex || (ST == llvm::Triple::Pixel && IsInput))
       return;
     DiagnoseAttrStageMismatch(SemanticAttr, ST,
diff --git a/clang/test/AST/HLSL/semantic-input-struct-shadow.hlsl 
b/clang/test/AST/HLSL/semantic-input-struct-shadow.hlsl
new file mode 100644
index 0000000000000..d4d89bd5d26ba
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-input-struct-shadow.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+
+// CHECK: CXXRecordDecl {{.*}} referenced struct S definition
+// CHECK: FieldDecl {{.*}} field1 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "A" 0
+// CHECK: FieldDecl {{.*}} field2 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "B" 4
+
+struct S {
+  int field1 : A;
+  int field2 : B4;
+};
+
+// CHECK:       FunctionDecl {{.*}} main 'void (S)'
+// CHECK-NEXT:  ParmVarDecl {{.*}} s 'S'
+// CHECK-NEXT:  HLSLParsedSemanticAttr {{.*}} "C" 0
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "C" 0
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "C" 1
+void main(S s : C) {}
diff --git a/clang/test/AST/HLSL/semantic-input-struct.hlsl 
b/clang/test/AST/HLSL/semantic-input-struct.hlsl
new file mode 100644
index 0000000000000..d71fdcff631f4
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-input-struct.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+
+// CHECK: CXXRecordDecl {{.*}} referenced struct S definition
+// CHECK: FieldDecl {{.*}} field1 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "A" 0
+// CHECK: FieldDecl {{.*}} field2 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "B" 4
+
+struct S {
+  int field1 : A;
+  int field2 : B4;
+};
+
+// CHECK:       FunctionDecl {{.*}} main 'void (S)'
+// CHECK-NEXT:  ParmVarDecl {{.*}} s 'S'
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "A" 0
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "B" 4
+void main(S s) {}
diff --git a/clang/test/AST/HLSL/semantic-input.hlsl 
b/clang/test/AST/HLSL/semantic-input.hlsl
new file mode 100644
index 0000000000000..4dc3ab9db7392
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-input.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+// CHECK:      ParmVarDecl {{.*}} a 'float4':'vector<float, 4>'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "ABC" 0
+// CHECK-NEXT: HLSLAppliedSemanticAttr {{.*}} "ABC" 0
+
+void main(float4 a : ABC) {
+}
diff --git a/clang/test/AST/HLSL/semantic-output-struct-shadow.hlsl 
b/clang/test/AST/HLSL/semantic-output-struct-shadow.hlsl
new file mode 100644
index 0000000000000..e83901bb17943
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-output-struct-shadow.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+
+// CHECK: CXXRecordDecl {{.*}} referenced struct S definition
+// CHECK: FieldDecl {{.*}} referenced field1 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "A" 0
+// CHECK: FieldDecl {{.*}} referenced field2 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "B" 4
+
+struct S {
+  int field1 : A;
+  int field2 : B4;
+};
+
+// CHECK:      FunctionDecl {{.*}} main 'S ()'
+// CHECK:       HLSLParsedSemanticAttr {{.*}} "DEF" 0
+// CHECK:       HLSLAppliedSemanticAttr {{.*}} "DEF" 0
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "DEF" 1
+S main() : DEF {
+  S tmp;
+  return tmp;
+}
diff --git a/clang/test/AST/HLSL/semantic-output-struct.hlsl 
b/clang/test/AST/HLSL/semantic-output-struct.hlsl
new file mode 100644
index 0000000000000..727c0f3040641
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-output-struct.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+
+// CHECK: CXXRecordDecl {{.*}} referenced struct S definition
+// CHECK: FieldDecl {{.*}} referenced field1 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "A" 0
+// CHECK: FieldDecl {{.*}} referenced field2 'int'
+// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} "B" 4
+
+struct S {
+  int field1 : A;
+  int field2 : B4;
+};
+
+// CHECK:      FunctionDecl {{.*}} main 'S ()'
+// CHECK:       HLSLAppliedSemanticAttr {{.*}} "A" 0
+// CHECK-NEXT:  HLSLAppliedSemanticAttr {{.*}} "B" 4
+S main() {
+  S tmp;
+  return tmp;
+}
diff --git a/clang/test/AST/HLSL/semantic-output.hlsl 
b/clang/test/AST/HLSL/semantic-output.hlsl
new file mode 100644
index 0000000000000..63429387f8d66
--- /dev/null
+++ b/clang/test/AST/HLSL/semantic-output.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex 
-finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+// CHECK: FunctionDecl {{.*}} main 'uint ()'
+// CHECK:  HLSLParsedSemanticAttr {{.*}} "ABC" 0
+// CHECK:  HLSLAppliedSemanticAttr {{.*}} "ABC" 0
+uint main() : ABC {
+  return 0;
+}

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

Reply via email to