Browse Source

Internal validator error messages don't need /Zi anymore. (#3606)

Adam Yang 4 years ago
parent
commit
86104f415f
40 changed files with 209 additions and 92 deletions
  1. 7 0
      include/dxc/HLSL/DxilValidation.h
  2. 11 0
      include/dxc/dxcapi.h
  3. 1 0
      include/llvm/IR/DebugInfo.h
  4. 1 1
      lib/DXIL/DxilUtil.cpp
  5. 5 11
      lib/DxilContainer/DxilContainerAssembler.cpp
  6. 1 1
      lib/HLSL/DxilCondenseResources.cpp
  7. 1 1
      lib/HLSL/DxilGenerationPass.cpp
  8. 14 0
      lib/HLSL/DxilValidation.cpp
  9. 1 1
      lib/HLSL/HLMatrixLowerPass.cpp
  10. 15 0
      lib/IR/DebugInfo.cpp
  11. 2 5
      lib/IR/DiagnosticInfo.cpp
  12. 1 1
      lib/Transforms/Scalar/LowerTypePasses.cpp
  13. 1 1
      lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
  14. 1 1
      lib/Transforms/Scalar/Scalarizer.cpp
  15. 1 3
      tools/clang/lib/CodeGen/CodeGenAction.cpp
  16. 1 1
      tools/clang/test/CodeGenHLSL/mesh-val/asOversizePayload.hlsl
  17. 2 2
      tools/clang/test/CodeGenHLSL/mesh-val/msOversizePayload.hlsl
  18. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/AddUint64Odd.hlsl
  19. 2 2
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/InnerCoverage.hlsl
  20. 3 3
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/invalid_input_output_types.hlsl
  21. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource2.hlsl
  22. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource3.hlsl
  23. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource5.hlsl
  24. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource5_dbg.hlsl
  25. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource6.hlsl
  26. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource6_dbg.hlsl
  27. 1 2
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/optForNoOpt3.hlsl
  28. 2 4
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/optForNoOpt4.hlsl
  29. 2 2
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/unsupported_error.hlsl
  30. 2 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-attribute-statement.hlsl
  31. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-comma-in-init.hlsl
  32. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-for-redefinition.hlsl
  33. 2 2
      tools/clang/test/HLSLFileCheck/hlsl/functions/entrypoints/unused_func.hlsl
  34. 12 11
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pack/sm_6_6_pack_unpack_error.hlsl
  35. 2 2
      tools/clang/test/HLSLFileCheck/validation/UndefStore.hlsl
  36. 1 1
      tools/clang/tools/dxcompiler/dxclinker.cpp
  37. 6 1
      tools/clang/tools/dxcompiler/dxcompilerobj.cpp
  38. 35 10
      tools/clang/tools/dxcompiler/dxcutil.cpp
  39. 0 2
      tools/clang/tools/dxcompiler/dxcutil.h
  40. 64 11
      tools/clang/tools/dxcompiler/dxcvalidator.cpp

+ 7 - 0
include/dxc/HLSL/DxilValidation.h

@@ -347,6 +347,13 @@ HRESULT ValidateDxilContainer(_In_reads_bytes_(ContainerSize) const void *pConta
                               _In_ uint32_t ContainerSize,
                               _In_ llvm::raw_ostream &DiagStream);
 
+// Full container validation, including ValidateDxilModule, with debug module
+HRESULT ValidateDxilContainer(_In_reads_bytes_(ContainerSize) const void *pContainer,
+                              _In_ uint32_t ContainerSize,
+                              const void *pOptDebugBitcode,
+                              uint32_t OptDebugBitcodeSize,
+                              _In_ llvm::raw_ostream &DiagStream);
+
 class PrintDiagnosticContext {
 private:
   llvm::DiagnosticPrinter &m_Printer;

+ 11 - 0
include/dxc/dxcapi.h

@@ -511,6 +511,17 @@ struct IDxcValidator : public IUnknown {
     ) = 0;
 };
 
+CROSS_PLATFORM_UUIDOF(IDxcValidator2, "458e1fd1-b1b2-4750-a6e1-9c10f03bed92")
+struct IDxcValidator2 : public IDxcValidator {
+  // Validate a shader.
+  virtual HRESULT STDMETHODCALLTYPE ValidateWithDebug(
+    _In_ IDxcBlob *pShader,                       // Shader to validate.
+    _In_ UINT32 Flags,                            // Validation flags.
+    _In_opt_ DxcBuffer *pOptDebugBitcode,         // Optional debug module bitcode to provide line numbers
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
+    ) = 0;
+};
+
 CROSS_PLATFORM_UUIDOF(IDxcContainerBuilder, "334b1f50-2292-4b35-99a1-25588d8c17fe")
 struct IDxcContainerBuilder : public IUnknown {
   virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pDxilContainerHeader) = 0;                // Loads DxilContainer to the builder

+ 1 - 0
include/llvm/IR/DebugInfo.h

@@ -60,6 +60,7 @@ bool stripDebugInfo(Function &F);
 
 /// \brief Return Debug Info Metadata Version by checking module flags.
 unsigned getDebugMetadataVersionFromModule(const Module &M);
+bool hasDebugInfo(const Module &M); // HLSL Change - Helper function to check if there's real debug info (variables, types)
 
 /// \brief Utility to find all debug info in a module.
 ///

+ 1 - 1
lib/DXIL/DxilUtil.cpp

@@ -314,7 +314,7 @@ static void EmitWarningOrErrorOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVar
 
   if (GV) {
     Module &M = *GV->getParent();
-    if (getDebugMetadataVersionFromModule(M) != 0) {
+    if (hasDebugInfo(M)) {
       DebugInfoFinder FinderObj;
       DebugInfoFinder &Finder = FinderObj;
       // Debug modules have no dxil modules. Use it if you got it.

+ 5 - 11
lib/DxilContainer/DxilContainerAssembler.cpp

@@ -1531,15 +1531,10 @@ DxilContainerWriter *hlsl::NewDxilContainerWriter() {
   return new DxilContainerWriter_impl();
 }
 
-static bool HasDebugInfo(const Module &M) {
-  for (Module::const_named_metadata_iterator NMI = M.named_metadata_begin(),
-                                             NME = M.named_metadata_end();
-       NMI != NME; ++NMI) {
-    if (NMI->getName().startswith("llvm.dbg.")) {
-      return true;
-    }
-  }
-  return false;
+static bool HasDebugInfoOrLineNumbers(const Module &M) {
+  return
+    llvm::getDebugMetadataVersionFromModule(M) != 0 ||
+    llvm::hasDebugInfo(M);
 }
 
 static void GetPaddedProgramPartSize(AbstractMemoryStream *pStream,
@@ -1776,8 +1771,7 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
   // If we have debug information present, serialize it to a debug part, then use the stripped version as the canonical program version.
   CComPtr<AbstractMemoryStream> pProgramStream = pInputProgramStream;
   bool bModuleStripped = false;
-  bool bHasDebugInfo = HasDebugInfo(*pModule->GetModule());
-  if (bHasDebugInfo) {
+  if (HasDebugInfoOrLineNumbers(*pModule->GetModule())) {
     uint32_t debugInUInt32, debugPaddingBytes;
     GetPaddedProgramPartSize(pInputProgramStream, debugInUInt32, debugPaddingBytes);
     if (Flags & SerializeDxilFlags::IncludeDebugInfoPart) {

+ 1 - 1
lib/HLSL/DxilCondenseResources.cpp

@@ -560,7 +560,7 @@ public:
 
     // Load up debug information, to cross-reference values and the instructions
     // used to load them.
-    m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+    m_HasDbgInfo = hasDebugInfo(M);
 
     GenerateDxilResourceHandles();
 

+ 1 - 1
lib/HLSL/DxilGenerationPass.cpp

@@ -201,7 +201,7 @@ public:
 
     // Load up debug information, to cross-reference values and the instructions
     // used to load them.
-    m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+    m_HasDbgInfo = hasDebugInfo(M);
 
     // EntrySig for shader functions.
     DxilEntryPropsMap EntryPropsMap;

+ 14 - 0
lib/HLSL/DxilValidation.cpp

@@ -6246,6 +6246,8 @@ _Use_decl_annotations_ HRESULT ValidateLoadModuleFromContainerLazy(
 _Use_decl_annotations_
 HRESULT ValidateDxilContainer(const void *pContainer,
                               uint32_t ContainerSize,
+                              const void *pOptDebugBitcode,
+                              uint32_t OptDebugBitcodeSize,
                               llvm::raw_ostream &DiagStream) {
   LLVMContext Ctx, DbgCtx;
   std::unique_ptr<llvm::Module> pModule, pDebugModule;
@@ -6260,6 +6262,12 @@ HRESULT ValidateDxilContainer(const void *pContainer,
   IFR(ValidateLoadModuleFromContainer(pContainer, ContainerSize, pModule, pDebugModule,
       Ctx, DbgCtx, DiagStream));
 
+  if (!pDebugModule && pOptDebugBitcode) {
+    // TODO: lazy load for perf
+    IFR(ValidateLoadModule((const char *)pOptDebugBitcode, OptDebugBitcodeSize,
+                           pDebugModule, DbgCtx, DiagStream, /*bLazyLoad*/false));
+  }
+
   // Validate DXIL Module
   IFR(ValidateDxilModule(pModule.get(), pDebugModule.get()));
 
@@ -6271,4 +6279,10 @@ HRESULT ValidateDxilContainer(const void *pContainer,
     IsDxilContainerLike(pContainer, ContainerSize), ContainerSize);
 }
 
+_Use_decl_annotations_
+HRESULT ValidateDxilContainer(const void *pContainer,
+                              uint32_t ContainerSize,
+                              llvm::raw_ostream &DiagStream) {
+  return ValidateDxilContainer(pContainer, ContainerSize, nullptr, 0, DiagStream);
+}
 } // namespace hlsl

+ 1 - 1
lib/HLSL/HLMatrixLowerPass.cpp

@@ -197,7 +197,7 @@ bool HLMatrixLowerPass::runOnModule(Module &M) {
   m_pHLModule = &m_pModule->GetOrCreateHLModule();
   // Load up debug information, to cross-reference values and the instructions
   // used to load them.
-  m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+  m_HasDbgInfo = hasDebugInfo(M);
   m_matToVecStubs = &matToVecStubs;
   m_vecToMatStubs = &vecToMatStubs;
 

+ 15 - 0
lib/IR/DebugInfo.cpp

@@ -379,6 +379,21 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
   return 0;
 }
 
+// HLSL Change - begin
+bool llvm::hasDebugInfo(const Module &M) {
+  // We might just get away with checking if there's "llvm.dbg.cu",
+  // but this is more robust.
+  for (Module::const_named_metadata_iterator NMI = M.named_metadata_begin(),
+                                             NME = M.named_metadata_end();
+       NMI != NME; ++NMI) {
+    if (NMI->getName().startswith("llvm.dbg.")) {
+      return true;
+    }
+  }
+  return false;
+}
+// HLSL Change - end
+
 DenseMap<const llvm::Function *, DISubprogram *>
 llvm::makeSubprogramMap(const Module &M) {
   DenseMap<const Function *, DISubprogram *> R;

+ 2 - 5
lib/IR/DiagnosticInfo.cpp

@@ -246,15 +246,12 @@ void DiagnosticInfoDxil::print(DiagnosticPrinter &DP) const {
     DP << "Function: " << Func->getName() << ": ";
   }
 
-  bool ZiPrompt = true;
   switch (getSeverity()) {
-  case DiagnosticSeverity::DS_Note:    DP << "note: "; ZiPrompt = false; break;
-  case DiagnosticSeverity::DS_Remark:  DP << "remark: "; ZiPrompt = false; break;
+  case DiagnosticSeverity::DS_Note:    DP << "note: "; break;
+  case DiagnosticSeverity::DS_Remark:  DP << "remark: "; break;
   case DiagnosticSeverity::DS_Warning: DP << "warning: "; break;
   case DiagnosticSeverity::DS_Error:   DP << "error: "; break;
   }
   DP << getMsgStr();
-  if (!DLoc && ZiPrompt)
-    DP << " Use /Zi for source location.";
 }
 // HLSL Change end - Dxil Diagnostic Info reporter

+ 1 - 1
lib/Transforms/Scalar/LowerTypePasses.cpp

@@ -130,7 +130,7 @@ bool LowerTypePass::runOnModule(Module &M) {
   initialize(M);
   // Load up debug information, to cross-reference values and the instructions
   // used to load them.
-  bool HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+  bool HasDbgInfo = llvm::hasDebugInfo(M);
   llvm::DebugInfoFinder Finder;
   if (HasDbgInfo) {
     Finder.processModule(M);

+ 1 - 1
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -3905,7 +3905,7 @@ public:
     const DataLayout &DL = M.getDataLayout();
     // Load up debug information, to cross-reference values and the instructions
     // used to load them.
-    m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+    m_HasDbgInfo = nullptr != M.getNamedMetadata("llvm.dbg.cu");
 
     InjectReturnAfterNoReturnPreserveOutput(*m_pHLModule);
 

+ 1 - 1
lib/Transforms/Scalar/Scalarizer.cpp

@@ -729,7 +729,7 @@ bool Scalarizer::finish() {
   Module &M = *Gathered.front().first->getModule();
   LLVMContext &Ctx = M.getContext();
   const DataLayout &DL = M.getDataLayout();
-  bool HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
+  bool HasDbgInfo = hasDebugInfo(M);
   // Map from an extract element inst to a Value which replaced it.
   DenseMap<Instruction *, Value*> EltMap;
   // HLSL Change Ends.

+ 1 - 3
tools/clang/lib/CodeGen/CodeGenAction.cpp

@@ -556,10 +556,8 @@ BackendConsumer::DxilDiagHandler(const llvm::DiagnosticInfoDxil &D) {
   }
   FullSourceLoc Loc(DILoc, SourceMgr);
 
-  // If no location information is available, prompt for debug flag
-  // and add function name to give some information
+  // If no location information is available, add function name
   if (Loc.isInvalid()) {
-    Message += " Use /Zi for source location.";
     auto *DiagClient = dynamic_cast<TextDiagnosticPrinter*>(Diags.getClient());
     auto *func = D.getFunction();
     if (DiagClient && func)

+ 1 - 1
tools/clang/test/CodeGenHLSL/mesh-val/asOversizePayload.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxilver 1.6 | %dxc -E main -T as_6_5 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 23:5: error: For amplification shader with entry 'main', payload size 16400 is greater than maximum size of 16384 bytes.
-// CHK_NODB: For amplification shader with entry 'main', payload size 16400 is greater than maximum size of 16384 bytes.
+// CHK_NODB: 23:5: error: For amplification shader with entry 'main', payload size 16400 is greater than maximum size of 16384 bytes.
 
 #define NUM_THREADS 32
 

+ 2 - 2
tools/clang/test/CodeGenHLSL/mesh-val/msOversizePayload.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxilver 1.6 | %dxc -E main -T ms_6_5 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: :29: error: For mesh shader with entry 'main', payload size 16404 is greater than maximum size of 16384 bytes.
-// CHK_NODB: error: For mesh shader with entry 'main', payload size 16404 is greater than maximum size of 16384 bytes. Use /Zi for source location.
+// CHK_NODB: :29: error: For mesh shader with entry 'main', payload size 16404 is greater than maximum size of 16384 bytes.
 
 #define MAX_VERT 32
 #define MAX_PRIM 16
@@ -62,4 +62,4 @@ void main(
       prims[tig / 3] = op;
     }
     verts[tig] = ov;
-}
+}

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/AddUint64Odd.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 8:12: error: AddUint64 can only be applied to uint2 and uint4 operands.
-// CHK_NODB: error: AddUint64 can only be applied to uint2 and uint4 operands. Use /Zi for source location.
+// CHK_NODB: 8:12: error: AddUint64 can only be applied to uint2 and uint4 operands.
 
 float4 main(uint4 a : A, uint4 b :B) : SV_TARGET {
   uint c = AddUint64(a.x, b.x);

+ 2 - 2
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/InnerCoverage.hlsl

@@ -5,8 +5,8 @@
 
 // CHK_DB: 11:1: error: Parameter with semantic SV_InnerCoverage has overlapping semantic index at 0.
 // CHK_DB: 11:1: error: Pixel shader inputs SV_Coverage and SV_InnerCoverage are mutually exclusive.
-// CHK_NODB: error: Parameter with semantic SV_InnerCoverage has overlapping semantic index at 0. Use /Zi for source location.
-// CHK_NODB: error: Pixel shader inputs SV_Coverage and SV_InnerCoverage are mutually exclusive. Use /Zi for source location.
+// CHK_NODB: 11:1: error: Parameter with semantic SV_InnerCoverage has overlapping semantic index at 0.
+// CHK_NODB: 11:1: error: Pixel shader inputs SV_Coverage and SV_InnerCoverage are mutually exclusive.
 
 void main(snorm float b : B, uint c:C, 
 #ifndef GENLL

+ 3 - 3
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/invalid_input_output_types.hlsl

@@ -3,9 +3,9 @@
 
 // CHK_DB: 9:1: error: i64(type for I) cannot be used as shader inputs or outputs.
 // CHK_DB: 9:1: error: double(type for SV_Target) cannot be used as shader inputs or outputs.
-// CHK_NODB: cannot be used as shader inputs or outputs. Use /Zi for source location.
-// CHK_NODB: cannot be used as shader inputs or outputs. Use /Zi for source location.
+// CHK_NODB: 9:1: error: i64(type for I) cannot be used as shader inputs or outputs.
+// CHK_NODB: 9:1: error: double(type for SV_Target) cannot be used as shader inputs or outputs.
 
 double main(uint64_t i:I) : SV_Target {
     return 1;
-}
+}

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource2.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 9:10: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 9:10: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource3.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 9:10: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 9:10: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource5.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 17:7: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 17:7: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource5_dbg.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 9:10: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 9:10: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource6.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 18:7: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 18:7: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/local_resource6_dbg.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
 // CHK_DB: 9:10: error: local resource not guaranteed to map to unique global resource.
-// CHK_NODB: error: local resource not guaranteed to map to unique global resource. Use /Zi for source location.
+// CHK_NODB: 9:10: error: local resource not guaranteed to map to unique global resource.
 
 float4 Tex2D(Texture2D<float4> t,
   SamplerState s, float2 c) {

+ 1 - 2
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/optForNoOpt3.hlsl

@@ -1,9 +1,8 @@
 // RUN: %dxc -Zi -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_DB
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
-// CHK_DB: 17:7: error: Offsets to texture access operations must be immediate values
+// CHK_DB: 16:7: error: Offsets to texture access operations must be immediate values
 // CHK_NODB: Offsets to texture access operations must be immediate values.
-// CHK_NODB-SAME Use /Zi for source location.
 
 SamplerState samp1 : register(s5);
 Texture2D<float4> text1 : register(t3);

+ 2 - 4
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/optForNoOpt4.hlsl

@@ -1,13 +1,11 @@
 // RUN: %dxc -Zi -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_DB
 // RUN: %dxc -E main -Od -T ps_6_0 %s | FileCheck %s -check-prefix=CHK_NODB
 
-// CHK_DB: 21:10: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
-// CHK_DB: 21:10: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
+// CHK_DB: 19:10: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
+// CHK_DB: 19:10: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
 
 // CHK_NODB: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
-// CHK_NODB-SAME Use /Zi for source location.
 // CHK_NODB: error: Offsets to texture access operations must be immediate values. Unrolling the loop containing the offset value manually and using -O3 may help in some cases.
-// CHK_NODB-SAME Use /Zi for source location.
 
 SamplerState samp1 : register(s5);
 Texture2D<float4> text1 : register(t3);

+ 2 - 2
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/unsupported_error.hlsl

@@ -4,7 +4,7 @@
 // Regression test for a crash when lowering unsupported intrinsics
 
 // CHK_DB: 10:50: error: Unsupported intrinsic
-// CHK_NODB: error: Unsupported intrinsic. Use /Zi for source location.
+// CHK_NODB: 10:50: error: Unsupported intrinsic
 
 sampler TextureSampler;
-float4 main(float2 uv	: UV) : SV_Target { return tex2D(TextureSampler, uv); }
+float4 main(float2 uv	: UV) : SV_Target { return tex2D(TextureSampler, uv); }

+ 2 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-attribute-statement.hlsl

@@ -2,6 +2,8 @@
 
 // Make sure the specified warning gets turned off
 
+// CHECK: 9:1: error: Semantic must be defined
+
 // This function has no output semantic on purpose in order to produce an error,
 // otherwise, the warnings will not be captured in the output for FileCheck.
 float main() {
@@ -14,4 +16,3 @@ float main() {
   return 0;
 }
 
-// CHECK: error: Semantic must be defined

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-comma-in-init.hlsl

@@ -7,7 +7,7 @@
 float main() {
 
 // comma expression used where a constructor list may have been intended
-// CHECK-NOT: comma
+// CHECK-NOT: comma expression
   int a = 1, b = 2;
   int c = (a, b);
 

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/Wno-for-redefinition.hlsl

@@ -7,7 +7,7 @@
 float main() {
 
 // redefinition of %0 shadows declaration in the outer scope; most recent declaration will be used
-// CHECK-NOT: redefinition
+// CHECK-NOT: redefinition of
   for (int i=0; i<4; i++);
   for (int i=0; i<4; i++);
 

+ 2 - 2
tools/clang/test/HLSLFileCheck/hlsl/functions/entrypoints/unused_func.hlsl

@@ -2,8 +2,8 @@
 
 // Make sure unused functions are not generated.
 
-// CHECK-NOT: unused
+// CHECK-NOT: unused_function_name
 
-void unused() {}
+void unused_function_name() {}
 void main() {}
 

+ 12 - 11
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pack/sm_6_6_pack_unpack_error.hlsl

@@ -1,22 +1,23 @@
 // RUN: %dxilver 1.6 | %dxc -T ps_6_5 -enable-16bit-types  %s | FileCheck %s
 
-// CHECK: Opcode Pack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Pack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Unpack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Unpack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Unpack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Unpack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Pack4x8 not valid in shader model ps_6_5
-// CHECK: Opcode Pack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 13:{{[0-9]+}}: error: Opcode Pack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 14:{{[0-9]+}}: error: Opcode Pack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 15:{{[0-9]+}}: error: Opcode Unpack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 16:{{[0-9]+}}: error: Opcode Unpack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 17:{{[0-9]+}}: error: Opcode Pack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 18:{{[0-9]+}}: error: Opcode Pack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 19:{{[0-9]+}}: error: Opcode Unpack4x8 not valid in shader model ps_6_5
+// CHECK-DAG: 20:{{[0-9]+}}: error: Opcode Unpack4x8 not valid in shader model ps_6_5
 
 int16_t4 main(int4 input1 : Inputs1, int16_t4 input2 : Inputs2) : SV_Target {
   int8_t4_packed ps1 = pack_s8(input1);
   int8_t4_packed ps2 = pack_clamp_s8(input1);
-  int16_t4 up1_out = unpack_s8s16(ps1) + unpack_s8s16(ps2);
-
+  int16_t4 up1_out = unpack_s8s16(ps1)
+   + unpack_s8s16(ps2);
   uint8_t4_packed pu1 = pack_u8(input2);
   uint8_t4_packed pu2 = pack_clamp_u8(input2);
-  uint16_t4 up2_out = unpack_u8u16(pu1) + unpack_u8u16(pu2);
+  uint16_t4 up2_out = unpack_u8u16(pu1)
+    + unpack_u8u16(pu2);
 
   return up1_out + up2_out;
 }

+ 2 - 2
tools/clang/test/HLSLFileCheck/validation/UndefStore.hlsl

@@ -2,7 +2,7 @@
 // RUN: %dxilver 1.6 | %dxc -E main -T cs_6_0 %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHK_NODB
 
 // CHK_DB: 18:17: error: Assignment of undefined values to UAV.
-// CHK_NODB: Function: main: error: Assignment of undefined values to UAV. Use /Zi for source location.
+// CHK_NODB: 18:17: error: Assignment of undefined values to UAV.
 
 RWBuffer<uint> output;
 
@@ -16,4 +16,4 @@ void main(uint3 DTid : SV_DispatchThreadID)
 {
 	uint sum = Add(sum, (uint)DTid.x);	// Deliberate use of uninitialised variable 'sum'
 	output[DTid.x] = sum;
-}
+}

+ 1 - 1
tools/clang/tools/dxcompiler/dxclinker.cpp

@@ -274,7 +274,7 @@ HRESULT STDMETHODCALLTYPE DxcLinker::Link(
         dxcutil::AssembleInputs inputs(
           std::move(pM), pOutputBlob, pMalloc, SerializeFlags,
           pOutputStream,
-          opts.DebugInfo, opts.DebugFile, &Diag);
+          opts.DebugFile, &Diag);
         if (needsValidation) {
           valHR = dxcutil::ValidateAndAssembleToContainer(inputs);
         } else {

+ 6 - 1
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -973,7 +973,7 @@ public:
 
           dxcutil::AssembleInputs inputs(
                 std::move(serializeModule), pOutputBlob, m_pMalloc, SerializeFlags,
-                pOutputStream, opts.GenerateFullDebugInfo(),
+                pOutputStream,
                 opts.GetPDBName(), &compiler.getDiagnostics(),
                 &ShaderHashContent, pReflectionStream, pRootSigStream);
 
@@ -1252,6 +1252,11 @@ public:
       // TODO: consider
       // DebugPass, DebugCompilationDir, DwarfDebugFlags, SplitDwarfFile
     }
+    else {
+      CodeGenOptions &CGOpts = compiler.getCodeGenOpts();
+      CGOpts.setDebugInfo(CodeGenOptions::LocTrackingOnly);
+      CGOpts.DebugColumnInfo = 1;
+    }
 
     clang::PreprocessorOptions &PPOpts(compiler.getPreprocessorOpts());
     for (size_t i = 0; i < defines.size(); ++i) {

+ 35 - 10
tools/clang/tools/dxcompiler/dxcutil.cpp

@@ -20,6 +20,7 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -70,7 +71,6 @@ AssembleInputs::AssembleInputs(std::unique_ptr<llvm::Module> &&pM,
                 IMalloc *pMalloc,
                 hlsl::SerializeDxilFlags SerializeFlags,
                 CComPtr<hlsl::AbstractMemoryStream> &pModuleBitcode,
-                bool bDebugInfo,
                 llvm::StringRef DebugName,
                 clang::DiagnosticsEngine *pDiag,
                 hlsl::DxilShaderHash *pShaderHashOut,
@@ -81,7 +81,6 @@ AssembleInputs::AssembleInputs(std::unique_ptr<llvm::Module> &&pM,
     pMalloc(pMalloc),
     SerializeFlags(SerializeFlags),
     pModuleBitcode(pModuleBitcode),
-    bDebugInfo(bDebugInfo),
     DebugName(DebugName),
     pDiag(pDiag),
     pShaderHashOut(pShaderHashOut),
@@ -151,6 +150,11 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) {
   bool bInternalValidator = CreateValidator(pValidator);
   // Warning on internal Validator
 
+  CComPtr<IDxcValidator2> pValidator2;
+  if (!bInternalValidator) {
+    pValidator.QueryInterface(&pValidator2);
+  }
+
   if (bInternalValidator) {
     if (inputs.pDiag) {
       unsigned diagID =
@@ -159,12 +163,15 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) {
                                "signed for use in release environments.\r\n");
       inputs.pDiag->Report(diagID);
     }
-    // If using the internal validator, we'll use the modules directly.
-    // In this case, we'll want to make a clone to avoid
-    // SerializeDxilContainerForModule stripping all the debug info. The debug
-    // info will be stripped from the orginal module, but preserved in the cloned
-    // module.
-    if (inputs.bDebugInfo) {
+  }
+
+  if (bInternalValidator || pValidator2) {
+    // If using the internal validator or external validator supports
+    // IDxcValidator2, we'll use the modules directly. In this case, we'll want
+    // to make a clone to avoid SerializeDxilContainerForModule stripping all
+    // the debug info. The debug info will be stripped from the orginal module,
+    // but preserved in the cloned module.
+    if (llvm::getDebugMetadataVersionFromModule(*inputs.pM) != 0) {
       llvmModuleWithDebugInfo.reset(llvm::CloneModule(inputs.pM.get()));
     }
   }
@@ -199,8 +206,26 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) {
                              llvmModuleWithDebugInfo.get(), inputs.pOutputContainerBlob,
                              DxcValidatorFlags_InPlaceEdit, &pValResult));
   } else {
-    IFT(pValidator->Validate(inputs.pOutputContainerBlob, DxcValidatorFlags_InPlaceEdit,
-                             &pValResult));
+    if (pValidator2 && llvmModuleWithDebugInfo) {
+
+      // If metadata was stripped, re-serialize the input module.
+      CComPtr<AbstractMemoryStream> pDebugModuleStream;
+      IFT(CreateMemoryStream(DxcGetThreadMallocNoRef(), &pDebugModuleStream));
+      raw_stream_ostream outStream(pDebugModuleStream.p);
+      WriteBitcodeToFile(llvmModuleWithDebugInfo.get(), outStream, true);
+      outStream.flush();
+
+      DxcBuffer debugModule = {};
+      debugModule.Ptr = pDebugModuleStream->GetPtr();
+      debugModule.Size = pDebugModuleStream->GetPtrSize();
+
+      IFT(pValidator2->ValidateWithDebug(inputs.pOutputContainerBlob, DxcValidatorFlags_InPlaceEdit,
+                                         &debugModule, &pValResult));
+    }
+    else {
+      IFT(pValidator->Validate(inputs.pOutputContainerBlob, DxcValidatorFlags_InPlaceEdit,
+                               &pValResult));
+    }
   }
   IFT(pValResult->GetStatus(&valHR));
   if (inputs.pDiag) {

+ 0 - 2
tools/clang/tools/dxcompiler/dxcutil.h

@@ -45,7 +45,6 @@ struct AssembleInputs {
                  IMalloc *pMalloc,
                  hlsl::SerializeDxilFlags SerializeFlags,
                  CComPtr<hlsl::AbstractMemoryStream> &pModuleBitcode,
-                 bool bDebugInfo = false,
                  llvm::StringRef DebugName = llvm::StringRef(),
                  clang::DiagnosticsEngine *pDiag = nullptr,
                  hlsl::DxilShaderHash *pShaderHashOut = nullptr,
@@ -56,7 +55,6 @@ struct AssembleInputs {
   IMalloc *pMalloc;
   hlsl::SerializeDxilFlags SerializeFlags;
   CComPtr<hlsl::AbstractMemoryStream> &pModuleBitcode;
-  bool bDebugInfo;
   llvm::StringRef DebugName = llvm::StringRef();
   clang::DiagnosticsEngine *pDiag;
   hlsl::DxilShaderHash *pShaderHashOut = nullptr;

+ 64 - 11
tools/clang/tools/dxcompiler/dxcvalidator.cpp

@@ -20,6 +20,7 @@
 #include "dxc/Support/Global.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MSFileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
@@ -53,7 +54,7 @@ struct DiagRestore {
   }
 };
 
-class DxcValidator : public IDxcValidator,
+class DxcValidator : public IDxcValidator2,
 #ifdef SUPPORT_QUERY_GIT_COMMIT_INFO
                      public IDxcVersionInfo2
 #else
@@ -66,8 +67,8 @@ private:
   HRESULT RunValidation(
     _In_ IDxcBlob *pShader,                       // Shader to validate.
     _In_ UINT32 Flags,                            // Validation flags.
-    _In_ llvm::Module *pModule,                   // Module to validate, if available.
-    _In_ llvm::Module *pDebugModule,              // Debug module to validate, if available
+    _In_opt_ llvm::Module *pModule,               // Module to validate, if available.
+    _In_opt_ llvm::Module *pDebugModule,          // Debug module to validate, if available
     _In_ AbstractMemoryStream *pDiagStream);
 
   HRESULT RunRootSignatureValidation(
@@ -79,15 +80,15 @@ public:
   DXC_MICROCOM_TM_CTOR(DxcValidator)
 
   HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) override {
-    return DoBasicQueryInterface<IDxcValidator, IDxcVersionInfo>(this, iid, ppvObject);
+    return DoBasicQueryInterface<IDxcValidator, IDxcValidator2, IDxcVersionInfo>(this, iid, ppvObject);
   }
 
   // For internal use only.
   HRESULT ValidateWithOptModules(
     _In_ IDxcBlob *pShader,                       // Shader to validate.
     _In_ UINT32 Flags,                            // Validation flags.
-    _In_ llvm::Module *pModule,                   // Module to validate, if available.
-    _In_ llvm::Module *pDebugModule,              // Debug module to validate, if available
+    _In_opt_ llvm::Module *pModule,               // Module to validate, if available.
+    _In_opt_ llvm::Module *pDebugModule,          // Debug module to validate, if available
     _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
   );
 
@@ -98,6 +99,14 @@ public:
     _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
     ) override;
 
+  // IDxcValidator2
+  HRESULT STDMETHODCALLTYPE ValidateWithDebug(
+    _In_ IDxcBlob *pShader,                       // Shader to validate.
+    _In_ UINT32 Flags,                            // Validation flags.
+    _In_opt_ DxcBuffer *pOptDebugBitcode,         // Optional debug module bitcode to provide line numbers
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
+    ) override;
+
   // IDxcVersionInfo
   HRESULT STDMETHODCALLTYPE GetVersion(_Out_ UINT32 *pMajor, _Out_ UINT32 *pMinor) override;
   HRESULT STDMETHODCALLTYPE GetFlags(_Out_ UINT32 *pFlags) override;
@@ -115,18 +124,62 @@ HRESULT STDMETHODCALLTYPE DxcValidator::Validate(
   _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
 ) {
   DxcThreadMalloc TM(m_pMalloc);
-  if (pShader == nullptr || ppResult == nullptr || Flags & ~DxcValidatorFlags_ValidMask)
+  if (ppResult == nullptr)
+    return E_INVALIDARG;
+  *ppResult = nullptr;
+  if (pShader == nullptr || Flags & ~DxcValidatorFlags_ValidMask)
     return E_INVALIDARG;
   if ((Flags & DxcValidatorFlags_ModuleOnly) && (Flags & (DxcValidatorFlags_InPlaceEdit | DxcValidatorFlags_RootSignatureOnly)))
     return E_INVALIDARG;
   return ValidateWithOptModules(pShader, Flags, nullptr, nullptr, ppResult);
 }
 
+HRESULT STDMETHODCALLTYPE DxcValidator::ValidateWithDebug(
+  _In_ IDxcBlob *pShader,                       // Shader to validate.
+  _In_ UINT32 Flags,                            // Validation flags.
+  _In_opt_ DxcBuffer *pOptDebugBitcode,         // Optional debug module bitcode to provide line numbers
+  _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
+)
+{
+  if (ppResult == nullptr)
+    return E_INVALIDARG;
+  *ppResult = nullptr;
+  if (pShader == nullptr || Flags & ~DxcValidatorFlags_ValidMask)
+    return E_INVALIDARG;
+  if ((Flags & DxcValidatorFlags_ModuleOnly) && (Flags & (DxcValidatorFlags_InPlaceEdit | DxcValidatorFlags_RootSignatureOnly)))
+    return E_INVALIDARG;
+  if (pOptDebugBitcode && (pOptDebugBitcode->Ptr == nullptr || pOptDebugBitcode->Size == 0 ||
+                           pOptDebugBitcode->Size >= UINT32_MAX))
+    return E_INVALIDARG;
+
+  HRESULT hr = S_OK;
+  DxcThreadMalloc TM(m_pMalloc);
+  try {
+    LLVMContext Ctx;
+    CComPtr<AbstractMemoryStream> pDiagStream;
+    IFT(CreateMemoryStream(m_pMalloc, &pDiagStream));
+    raw_stream_ostream DiagStream(pDiagStream);
+    llvm::DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
+    PrintDiagnosticContext DiagContext(DiagPrinter);
+    Ctx.setDiagnosticHandler(PrintDiagnosticContext::PrintDiagnosticHandler,
+                             &DiagContext, true);
+    std::unique_ptr<llvm::Module> pDebugModule;
+    if (pOptDebugBitcode) {
+      IFT(ValidateLoadModule((const char *)pOptDebugBitcode->Ptr,
+                             (uint32_t)pOptDebugBitcode->Size, pDebugModule,
+                             Ctx, DiagStream, /*bLazyLoad*/ false));
+    }
+    return ValidateWithOptModules(pShader, Flags, nullptr, pDebugModule.get(), ppResult);
+  }
+  CATCH_CPP_ASSIGN_HRESULT();
+  return hr;
+}
+
 HRESULT DxcValidator::ValidateWithOptModules(
   _In_ IDxcBlob *pShader,                       // Shader to validate.
   _In_ UINT32 Flags,                            // Validation flags.
-  _In_ llvm::Module *pModule,                   // Module to validate, if available.
-  _In_ llvm::Module *pDebugModule,              // Debug module to validate, if available
+  _In_opt_ llvm::Module *pModule,               // Module to validate, if available.
+  _In_opt_ llvm::Module *pDebugModule,          // Debug module to validate, if available
   _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
 ) {
   *ppResult = nullptr;
@@ -204,8 +257,8 @@ HRESULT STDMETHODCALLTYPE DxcValidator::GetFlags(_Out_ UINT32 *pFlags) {
 HRESULT DxcValidator::RunValidation(
   _In_ IDxcBlob *pShader,
   _In_ UINT32 Flags,                            // Validation flags.
-  _In_ llvm::Module *pModule,                   // Module to validate, if available.
-  _In_ llvm::Module *pDebugModule,              // Debug module to validate, if available
+  _In_opt_ llvm::Module *pModule,               // Module to validate, if available.
+  _In_opt_ llvm::Module *pDebugModule,          // Debug module to validate, if available
   _In_ AbstractMemoryStream *pDiagStream) {
 
   // Run validation may throw, but that indicates an inability to validate,