Nathan =?utf-8?q?Gauër?= <[email protected]>, Nathan =?utf-8?q?Gauër?= <[email protected]>, Nathan =?utf-8?q?Gauër?= <[email protected]> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>
llvmbot wrote: <!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-spir-v Author: Nathan Gauër (Keenuts) <details> <summary>Changes</summary> This commit adds the support for vk::location attribute which can be applied to input and output variables. As in/inout parameters are not supported yet, vk::location on such parameters is not tested. As implemented in DXC, vk::location has the following rules: - input and outputs are handled independently. - input/output lowered to a SPIR-V builtins are not using the assigned vk::location and thus ignored. - input/output lowered to a Location decoration must either all have explicit locations, or none. Mixing is not allowed (except with builtins). --- Patch is 33.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/169479.diff 21 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+8) - (modified) clang/include/clang/Basic/AttrDocs.td (+12) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6) - (modified) clang/include/clang/Sema/SemaHLSL.h (+22-3) - (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+18-7) - (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) - (modified) clang/lib/Sema/SemaHLSL.cpp (+109-8) - (added) clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl (+19) - (added) clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl (+37) - (added) clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl (+19) - (added) clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.hlsl (+39) - (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (+1) - (modified) clang/test/SemaHLSL/Semantics/position.ps.hlsl (+1-1) - (added) clang/test/SemaHLSL/Semantics/semantic.explicit-mix-builtin-vs.hlsl (+16) - (added) clang/test/SemaHLSL/Semantics/semantic.explicit-mix-location-2.hlsl (+15) - (added) clang/test/SemaHLSL/Semantics/semantic.explicit-mix-location.hlsl (+15) - (added) clang/test/SemaHLSL/Semantics/target.ps.input.hlsl (+7) - (added) clang/test/SemaHLSL/Semantics/target.vs.input.hlsl (+8) - (added) clang/test/SemaHLSL/Semantics/target.vs.output.hlsl (+7) - (added) llvm/test/CodeGen/SPIRV/semantics/target.ps.ll (+33) ``````````diff diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 8e5f7ef0bb82d..9e7dc200bc6cf 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -5172,6 +5172,14 @@ def HLSLVkConstantId : InheritableAttr { let Documentation = [VkConstantIdDocs]; } +def HLSLVkLocation : HLSLAnnotationAttr { + let Spellings = [CXX11<"vk", "location">]; + let Args = [IntArgument<"Location">]; + let Subjects = SubjectList<[ParmVar, Field, Function], ErrorDiag>; + let LangOpts = [HLSL]; + let Documentation = [HLSLVkLocationDocs]; +} + def RandomizeLayout : InheritableAttr { let Spellings = [GCC<"randomize_layout">]; let Subjects = SubjectList<[Record]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index c1b1510f363d4..fa365da3ed9aa 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -8981,6 +8981,18 @@ The descriptor set is optional and defaults to 0 if not provided. }]; } +def HLSLVkLocationDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +Attribute used for specifying the location number for the stage input/output +variables. Allowed on function parameters, function returns, and struct +fields. This parameter has no effect when used outside of an entrypoint +parameter/parameter field/return value. + +This attribute maps to the 'Location' SPIR-V decoration. + }]; +} + def WebAssemblyFuncrefDocs : Documentation { let Category = DocCatType; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 53aa86a7dabde..04812bd78d9b4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13231,6 +13231,12 @@ def err_hlsl_semantic_indexing_not_supported def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; def err_hlsl_semantic_index_overlap : Error<"semantic index overlap %0">; +def err_hlsl_semantic_unsupported_iotype_for_stage + : Error<"semantic %0 is unsupported in %2 shaders as %1, requires one of " + "the following: %3">; +def err_hlsl_semantic_partial_explicit_indexing + : Error<"partial explicit stage input location assignment via " + "vk::location(X) unsupported">; 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 15edb7e77a22b..cac89f6e51cae 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -134,9 +134,6 @@ class SemaHLSL : public SemaBase { void CheckEntryPoint(FunctionDecl *FD); bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, SourceLocation Loc); - void DiagnoseAttrStageMismatch( - const Attr *A, llvm::Triple::EnvironmentType Stage, - std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages); QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, @@ -171,6 +168,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 handleVkLocationAttr(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); @@ -243,6 +241,19 @@ class SemaHLSL : public SemaBase { HLSLParsedSemanticAttr *Semantic; std::optional<uint32_t> Index; }; + std::optional<bool> InputUsesExplicitVkLocations = std::nullopt; + std::optional<bool> OutputUsesExplicitVkLocations = std::nullopt; + + enum IOType { + In = 0b01, + Out = 0b10, + InOut = 0b11, + }; + + struct SemanticStageInfo { + llvm::Triple::EnvironmentType Stage; + IOType AllowedIOTypesMask; + }; private: void collectResourceBindingsOnVarDecl(VarDecl *D); @@ -269,6 +280,14 @@ class SemaHLSL : public SemaBase { void diagnoseAvailabilityViolations(TranslationUnitDecl *TU); + void diagnoseAttrStageMismatch( + const Attr *A, llvm::Triple::EnvironmentType Stage, + std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages); + + void diagnoseSemanticStageMismatch( + const Attr *A, llvm::Triple::EnvironmentType Stage, bool IsInput, + std::initializer_list<SemanticStageInfo> AllowedStages); + uint32_t getNextImplicitBindingOrderID() { return ImplicitBindingNextOrderID++; } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index f5c07fe2e33ff..913d80b7e5c25 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -582,20 +582,22 @@ static llvm::Value *createSPIRVLocationLoad(IRBuilder<> &B, llvm::Module &M, return B.CreateLoad(Ty, GV); } -llvm::Value * -CGHLSLRuntime::emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - HLSLAppliedSemanticAttr *Semantic, - std::optional<unsigned> Index) { +llvm::Value *CGHLSLRuntime::emitSPIRVUserSemanticLoad( + llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, + HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) { Twine BaseName = Twine(Semantic->getAttrName()->getName()); Twine VariableName = BaseName.concat(Twine(Index.value_or(0))); unsigned Location = SPIRVLastAssignedInputSemanticLocation; + if (auto *L = Decl->getAttr<HLSLVkLocationAttr>()) + Location = L->getLocation(); // DXC completely ignores the semantic/index pair. Location are assigned from // the first semantic to the last. llvm::ArrayType *AT = dyn_cast<llvm::ArrayType>(Type); unsigned ElementCount = AT ? AT->getNumElements() : 1; SPIRVLastAssignedInputSemanticLocation += ElementCount; + return createSPIRVLocationLoad(B, CGM.getModule(), Type, Location, VariableName.str()); } @@ -616,10 +618,14 @@ static void createSPIRVLocationStore(IRBuilder<> &B, llvm::Module &M, void CGHLSLRuntime::emitSPIRVUserSemanticStore( llvm::IRBuilder<> &B, llvm::Value *Source, - HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) { + const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic, + std::optional<unsigned> Index) { Twine BaseName = Twine(Semantic->getAttrName()->getName()); Twine VariableName = BaseName.concat(Twine(Index.value_or(0))); + unsigned Location = SPIRVLastAssignedOutputSemanticLocation; + if (auto *L = Decl->getAttr<HLSLVkLocationAttr>()) + Location = L->getLocation(); // DXC completely ignores the semantic/index pair. Location are assigned from // the first semantic to the last. @@ -671,7 +677,7 @@ llvm::Value *CGHLSLRuntime::emitUserSemanticLoad( IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) { if (CGM.getTarget().getTriple().isSPIRV()) - return emitSPIRVUserSemanticLoad(B, Type, Semantic, Index); + return emitSPIRVUserSemanticLoad(B, Type, Decl, Semantic, Index); if (CGM.getTarget().getTriple().isDXIL()) return emitDXILUserSemanticLoad(B, Type, Semantic, Index); @@ -684,7 +690,7 @@ void CGHLSLRuntime::emitUserSemanticStore(IRBuilder<> &B, llvm::Value *Source, HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) { if (CGM.getTarget().getTriple().isSPIRV()) - return emitSPIRVUserSemanticStore(B, Source, Semantic, Index); + return emitSPIRVUserSemanticStore(B, Source, Decl, Semantic, Index); if (CGM.getTarget().getTriple().isDXIL()) return emitDXILUserSemanticStore(B, Source, Semantic, Index); @@ -783,6 +789,11 @@ void CGHLSLRuntime::emitSystemSemanticStore(IRBuilder<> &B, llvm::Value *Source, } } + if (SemanticName == "SV_TARGET") { + emitUserSemanticStore(B, Source, Decl, Semantic, Index); + return; + } + llvm_unreachable( "Store hasn't been implemented yet for this system semantic. FIXME"); } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index c883282a8d9c8..d057add2db222 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -278,6 +278,7 @@ class CGHLSLRuntime { HLSLResourceBindingAttr *RBA); llvm::Value *emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index); llvm::Value *emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, @@ -289,6 +290,7 @@ class CGHLSLRuntime { std::optional<unsigned> Index); void emitSPIRVUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source, + const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index); void emitDXILUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index e3af5023c74d0..c9d1ee76a2e52 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7703,6 +7703,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLUnparsedSemantic: S.HLSL().handleSemanticAttr(D, AL); break; + case ParsedAttr::AT_HLSLVkLocation: + S.HLSL().handleVkLocationAttr(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 ecab3946b58c7..2a69703d0d1e9 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -771,6 +771,22 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { } } +static bool isPipelineBuiltin(const ASTContext &AstContext, FunctionDecl *FD, + HLSLAppliedSemanticAttr *Semantic) { + if (AstContext.getTargetInfo().getTriple().getOS() != llvm::Triple::Vulkan) + return false; + + const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>(); + assert(ShaderAttr && "Entry point has no shader attribute"); + llvm::Triple::EnvironmentType ST = ShaderAttr->getType(); + auto SemanticName = Semantic->getSemanticName().upper(); + + if (ST == llvm::Triple::Pixel && SemanticName == "SV_POSITION") + return true; + + return false; +} + bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD, DeclaratorDecl *OutputDecl, DeclaratorDecl *D, @@ -800,6 +816,22 @@ bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD, unsigned Location = ActiveSemantic.Index.value_or(0); + if (!isPipelineBuiltin(getASTContext(), FD, A)) { + bool HasVkLocation = false; + if (auto *A = D->getAttr<HLSLVkLocationAttr>()) { + HasVkLocation = true; + Location = A->getLocation(); + } + + auto &UsesExplicitVkLocations = + IsInput ? InputUsesExplicitVkLocations : OutputUsesExplicitVkLocations; + if (UsesExplicitVkLocations.value_or(HasVkLocation) != HasVkLocation) { + Diag(D->getLocation(), diag::err_hlsl_semantic_partial_explicit_indexing); + return false; + } + UsesExplicitVkLocations = HasVkLocation; + } + const ConstantArrayType *AT = dyn_cast<ConstantArrayType>(D->getType()); unsigned ElementCount = AT ? AT->getZExtSize() : 1; ActiveSemantic.Index = Location + ElementCount; @@ -873,14 +905,14 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) { case llvm::Triple::Miss: case llvm::Triple::Callable: if (const auto *NT = FD->getAttr<HLSLNumThreadsAttr>()) { - DiagnoseAttrStageMismatch(NT, ST, + diagnoseAttrStageMismatch(NT, ST, {llvm::Triple::Compute, llvm::Triple::Amplification, llvm::Triple::Mesh}); FD->setInvalidDecl(); } if (const auto *WS = FD->getAttr<HLSLWaveSizeAttr>()) { - DiagnoseAttrStageMismatch(WS, ST, + diagnoseAttrStageMismatch(WS, ST, {llvm::Triple::Compute, llvm::Triple::Amplification, llvm::Triple::Mesh}); @@ -954,7 +986,8 @@ void SemaHLSL::checkSemanticAnnotation( SemanticName == "SV_GROUPID") { if (ST != llvm::Triple::Compute) - DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Compute}); + diagnoseSemanticStageMismatch(SemanticAttr, ST, IsInput, + {{llvm::Triple::Compute, IOType::In}}); if (SemanticAttr->getSemanticIndex() != 0) { std::string PrettyName = @@ -969,10 +1002,15 @@ void SemaHLSL::checkSemanticAnnotation( if (SemanticName == "SV_POSITION") { // 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, - {llvm::Triple::Pixel, llvm::Triple::Vertex}); + diagnoseSemanticStageMismatch(SemanticAttr, ST, IsInput, + {{llvm::Triple::Vertex, IOType::InOut}, + {llvm::Triple::Pixel, IOType::In}}); + return; + } + + if (SemanticName == "SV_TARGET") { + diagnoseSemanticStageMismatch(SemanticAttr, ST, IsInput, + {{llvm::Triple::Pixel, IOType::Out}}); return; } @@ -982,7 +1020,7 @@ void SemaHLSL::checkSemanticAnnotation( llvm_unreachable("Unknown SemanticAttr"); } -void SemaHLSL::DiagnoseAttrStageMismatch( +void SemaHLSL::diagnoseAttrStageMismatch( const Attr *A, llvm::Triple::EnvironmentType Stage, std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages) { SmallVector<StringRef, 8> StageStrings; @@ -996,6 +1034,50 @@ void SemaHLSL::DiagnoseAttrStageMismatch( << (AllowedStages.size() != 1) << join(StageStrings, ", "); } +void SemaHLSL::diagnoseSemanticStageMismatch( + const Attr *A, llvm::Triple::EnvironmentType Stage, bool IsInput, + std::initializer_list<SemanticStageInfo> Allowed) { + + for (auto &Case : Allowed) { + if (Case.Stage != Stage) + continue; + + if (IsInput && Case.AllowedIOTypesMask & IOType::In) + return; + if (!IsInput && Case.AllowedIOTypesMask & IOType::Out) + return; + + SmallVector<std::string, 8> ValidCases; + llvm::transform( + Allowed, std::back_inserter(ValidCases), [](SemanticStageInfo Case) { + SmallVector<std::string, 2> ValidType; + if (Case.AllowedIOTypesMask & IOType::In) + ValidType.push_back("input"); + if (Case.AllowedIOTypesMask & IOType::Out) + ValidType.push_back("output"); + return std::string( + HLSLShaderAttr::ConvertEnvironmentTypeToStr(Case.Stage)) + + " " + join(ValidType, "/"); + }); + Diag(A->getLoc(), diag::err_hlsl_semantic_unsupported_iotype_for_stage) + << A->getAttrName() << (IsInput ? "input" : "output") + << llvm::Triple::getEnvironmentTypeName(Case.Stage) + << join(ValidCases, ", "); + return; + } + + SmallVector<StringRef, 8> StageStrings; + llvm::transform( + Allowed, std::back_inserter(StageStrings), [](SemanticStageInfo Case) { + return StringRef( + HLSLShaderAttr::ConvertEnvironmentTypeToStr(Case.Stage)); + }); + + Diag(A->getLoc(), diag::err_hlsl_attr_unsupported_in_stage) + << A->getAttrName() << llvm::Triple::getEnvironmentTypeName(Stage) + << (Allowed.size() != 1) << join(StageStrings, ", "); +} + template <CastKind Kind> static void castVector(Sema &S, ExprResult &E, QualType &Ty, unsigned Sz) { if (const auto *VTy = Ty->getAs<VectorType>()) @@ -1707,6 +1789,15 @@ void SemaHLSL::handleVkBindingAttr(Decl *D, const ParsedAttr &AL) { HLSLVkBindingAttr(getASTContext(), AL, Binding, Set)); } +void SemaHLSL::handleVkLocationAttr(Decl *D, const ParsedAttr &AL) { + uint32_t Location; + if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Location)) + return; + + D->addAttr(::new (getASTContext()) + HLSLVkLocationAttr(getASTContext(), AL, Location)); +} + bool SemaHLSL::diagnoseInputIDType(QualType T, const ParsedAttr &AL) { const auto *VT = T->getAs<VectorType>(); @@ -1797,6 +1888,16 @@ void SemaHLSL::diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, return; } + if (SemanticName == "SV_TARGET") { + 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"; + D->addAttr(createSemanticAttr<HLSLParsedSemanticAttr>(AL, Index)); + return; + } + Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL; } diff --git a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl new file mode 100644 index 0000000000000..4dc622a1eb6bb --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl @@ -0,0 +1,19 @@ +// 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-SPIRV: @SV_Target0 = 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_Target { + // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#]]) + // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 16 + + // 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_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 30, i32 0} +// | `-> Location index +// `-> SPIR-V decoration 'Location' diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl new file mode 100644 index 0000000000000..c5d86637fb4ea --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,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-prefixes=CHECK,CHECK-DXIL + +// CHECK-SPIRV: @SV_Positi... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/169479 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
