diff --git a/lib/HLSL/DxilPreparePasses.cpp b/lib/HLSL/DxilPreparePasses.cpp index c809fab2a4..6ca4a9bdf4 100644 --- a/lib/HLSL/DxilPreparePasses.cpp +++ b/lib/HLSL/DxilPreparePasses.cpp @@ -719,11 +719,6 @@ class DxilFinalizeModule : public ModulePass { if (DXIL::CompareVersions(ValMajor, ValMinor, 1, 1) <= 0) { patchValidation_1_1(M); } - - // Set used masks for signature elements - MarkUsedSignatureElements(DM.GetEntryFunction(), DM); - if (DM.GetShaderModel()->IsHS()) - MarkUsedSignatureElements(DM.GetPatchConstantFunction(), DM); } // Replace lifetime intrinsics if requested or necessary. @@ -742,6 +737,28 @@ class DxilFinalizeModule : public ModulePass { // Remove store undef output. RemoveStoreUndefOutput(M, hlslOP); + if (!IsLib) { + // Set used masks for signature elements + MarkUsedSignatureElements(DM.GetEntryFunction(), DM); + if (DM.GetShaderModel()->IsHS()) + MarkUsedSignatureElements(DM.GetPatchConstantFunction(), DM); + } + + // Adding warning for pixel shader with unassigned target + if (DM.GetShaderModel()->IsPS()) { + DxilSignature &sig = DM.GetOutputSignature(); + for (auto &Elt : sig.GetElements()) { + if (Elt->GetKind() == Semantic::Kind::Target && + Elt->GetUsageMask() != Elt->GetColsAsMask()) { + dxilutil::EmitWarningOnContext( + M.getContext(), + "Declared output " + llvm::Twine(Elt->GetName()) + + llvm::Twine(Elt->GetSemanticStartIndex()) + + " not fully written in shader."); + } + } + } + // Turn dx.break() conditional into global LowerDxBreak(M); diff --git a/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/unused-output-target-warning.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/unused-output-target-warning.hlsl new file mode 100644 index 0000000000..a0f8ee155b --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/unused-output-target-warning.hlsl @@ -0,0 +1,17 @@ +// RUN: %dxc -T ps_6_0 %s | FileCheck -input=stderr %s + +// CHECK-NOT: warning: Declared output SV_Target0 not fully written in shader. +// CHECK: warning: Declared output SV_Target1 not fully written in shader. +// CHECK: warning: Declared output SV_Target2 not fully written in shader. +// CHECK: warning: Declared output SV_Target3 not fully written in shader. + +void main(out float4 outRT0 : SV_Target0, + out float4 outRT1 : SV_Target1, + out float4 outRT2 : SV_Target2, + out float4 outRT3 : SV_Target3) { + + outRT0 = 0.0f; + outRT1.x = 0.0f; + outRT2.zw = 0.0f; + // outRT3 = 0.0f; +}