llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-hlsl

Author: Vladislav Dzhidzhoev (dzhidzhoev)

<details>
<summary>Changes</summary>

Add HLSL debug metadata emission for DXIL by embedding non-system source files 
(including included headers) into dx.source.contents, recording the main file 
name and user defines, and serializing the dxc-style command line into 
dx.source.args.

This metadata nodes are needed for emitting SRCI part of a debug DXContainer in 
llc.

Introduce -fdx-record-command-line option to cc1 to carry the escaped driver 
command line into cc1.
Introduce -fdx-no-source-metadata CodeGen option to cc1, to be able to disable 
dx.source metadata nodes emission. This comes in handy for writing debug info 
tests, so that CHECK-NOT lines do not match themselves in LLVM IR. For example, 
without this option, in `clang/test/CodeGenHLSL/debug/source-language.hlsl`, 
CHECK-V4-NOT line gets a match on the line with dx.source.contents node.

---

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


23 Files Affected:

- (modified) clang/include/clang/Basic/CodeGenOptions.def (+3) 
- (modified) clang/include/clang/Basic/CodeGenOptions.h (+4) 
- (modified) clang/include/clang/Driver/CommonArgs.h (+2-2) 
- (modified) clang/include/clang/Options/OptionUtils.h (+4) 
- (modified) clang/include/clang/Options/Options.td (+13) 
- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+111) 
- (modified) clang/lib/CodeGen/CMakeLists.txt (+1) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+7-1) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5-2) 
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+3-1) 
- (modified) clang/lib/Options/OptionUtils.cpp (+32) 
- (added) clang/test/CodeGenHLSL/Inputs/a.hlsl (+10) 
- (added) clang/test/CodeGenHLSL/Inputs/b.hlsl (+3) 
- (added) clang/test/CodeGenHLSL/SysInputs/c.hlsl (+3) 
- (modified) clang/test/CodeGenHLSL/debug/source-language.hlsl (+4) 
- (added) clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl (+12) 
- (added) clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl (+21) 
- (added) 
clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl (+10) 
- (added) clang/test/CodeGenHLSL/dx-source-metadata.hlsl (+28) 
- (modified) clang/test/CodeGenHLSL/lit.local.cfg (+1) 
- (modified) clang/test/Driver/dxc_debug.hlsl (+4-1) 
- (modified) clang/unittests/Driver/CMakeLists.txt (+2) 
- (added) clang/unittests/Driver/EscapedCommandLineTest.cpp (+135) 


``````````diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index aa36de6edecbf..b121e7cb46601 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -520,6 +520,9 @@ CODEGENOPT(ResMayAlias, 1, 0, Benign)
 /// Assume that all resources are bound if enabled
 CODEGENOPT(AllResourcesBound, 1, 0, Benign)
 
+/// Do not embed dx.source.* metadata in HLSL modules.
+CODEGENOPT(DisableDXSourceMetadata, 1, 0, Benign)
+
 /// Controls how unwind v2 (epilog) information should be generated for x64
 /// Windows.
 ENUM_CODEGENOPT(WinX64EHUnwindV2, WinX64EHUnwindV2Mode,
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index e43112b4bb98b..33991827eb061 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -268,6 +268,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// if non-empty.
   std::string RecordCommandLine;
 
+  /// The string containing the commandline for the dx.source.args metadata,
+  /// if non-empty.
+  std::string HLSLRecordCommandLine;
+
   llvm::SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap;
 
   /// Prefix replacement map for source-based code coverage to remap source
diff --git a/clang/include/clang/Driver/CommonArgs.h 
b/clang/include/clang/Driver/CommonArgs.h
index 0af1b89425227..51ae3b13b5550 100644
--- a/clang/include/clang/Driver/CommonArgs.h
+++ b/clang/include/clang/Driver/CommonArgs.h
@@ -275,8 +275,8 @@ const char *renderEscapedCommandLine(const ToolChain &TC,
 /// line options that were passed.
 bool shouldRecordCommandLine(const ToolChain &TC,
                              const llvm::opt::ArgList &Args,
-                             bool &FRecordCommandLine,
-                             bool &GRecordCommandLine);
+                             bool &FRecordCommandLine, bool 
&GRecordCommandLine,
+                             bool &DXRecordCommandLine);
 
 void renderGlobalISelOptions(const Driver &D, const llvm::opt::ArgList &Args,
                              llvm::opt::ArgStringList &CmdArgs,
diff --git a/clang/include/clang/Options/OptionUtils.h 
b/clang/include/clang/Options/OptionUtils.h
index 02c9c27554db1..4305cdd134bf4 100644
--- a/clang/include/clang/Options/OptionUtils.h
+++ b/clang/include/clang/Options/OptionUtils.h
@@ -77,6 +77,10 @@ std::string GetResourcesPath(StringRef BinaryPath);
 /// executable), for finding the builtin compiler path.
 std::string GetResourcesPath(const char *Argv0, void *MainAddr);
 
+/// Parse a space-separated command line with escaped spaces and backslashes.
+llvm::Expected<llvm::SmallVector<llvm::SmallString<8>>>
+parseEscapedCommandLine(const char *CommandLine);
+
 } // namespace clang
 
 #endif // LLVM_CLANG_OPTIONS_OPTIONUTILS_H
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 753e3ac1b74a5..f448a986038cb 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9670,6 +9670,19 @@ def dxc_rootsig_define :
   Alias<fdx_rootsignature_define>,
   Group<dxc_Group>,
   Visibility<[DXCOption]>;
+def dxc_record_command_line
+    : Separate<["-"], "fdx-record-command-line">,
+      Group<dxc_Group>,
+      Visibility<[CC1Option]>,
+      MarshallingInfoString<CodeGenOpts<"HLSLRecordCommandLine">>,
+      HelpText<
+          "Command line arguments to embed in the dx.source.args metadata">;
+def dxc_no_source_metadata
+    : Flag<["-"], "fdx-no-source-metadata">,
+      Group<dxc_Group>,
+      Visibility<[CC1Option]>,
+      MarshallingInfoFlag<CodeGenOpts<"DisableDXSourceMetadata">>,
+      HelpText<"Do not embed source info metadata in HLSL modules">;
 def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>,
                       Group<dxc_Group>,
                       Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 98d65715d45b9..a21b96f4acb7c 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -27,8 +27,11 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetOptions.h"
+#include "clang/Options/OptionUtils.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -45,6 +48,7 @@
 #include "llvm/Support/Alignment.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Path.h"
 #include <cstdint>
 #include <optional>
 
@@ -189,6 +193,109 @@ findAssociatedResourceDeclForStruct(ASTContext &AST, 
const MemberExpr *ME) {
   return nullptr;
 }
 
+void addSourceInfo(CodeGenModule &CGM, llvm::Module &M) {
+  auto &SM = CGM.getContext().getSourceManager();
+  auto &Macros = CGM.getPreprocessorOpts().Macros;
+  auto &Ctx = M.getContext();
+
+  // Names and content of shader source code files.
+  llvm::NamedMDNode *DXContents =
+      M.getOrInsertNamedMetadata("dx.source.contents");
+  auto addFile = [&](const std::pair<StringRef, StringRef> &NameContent) {
+    llvm::MDTuple *FileInfo =
+        llvm::MDNode::get(Ctx, {llvm::MDString::get(Ctx, NameContent.first),
+                                llvm::MDString::get(Ctx, NameContent.second)});
+    DXContents->addOperand(FileInfo);
+  };
+
+  bool Invalid = false;
+  const SrcMgr::SLocEntry *MainLocEntry =
+      &SM.getSLocEntry(SM.getMainFileID(), &Invalid);
+  assert(!Invalid && "Main file SLocEntry must not be invalid!");
+  const SrcMgr::ContentCache &MainCCEntry =
+      MainLocEntry->getFile().getContentCache();
+
+  SmallVector<std::pair<std::string, StringRef>> Files;
+  std::optional<SmallString<256>> MainFileName;
+  Files.reserve(SM.local_sloc_entry_size());
+  for (unsigned I : llvm::seq(SM.local_sloc_entry_size())) {
+    const SrcMgr::SLocEntry &LocEntry = SM.getLocalSLocEntry(I);
+    if (!LocEntry.isFile())
+      continue;
+
+    const SrcMgr::FileInfo &FInfo = LocEntry.getFile();
+    if (isSystem(FInfo.getFileCharacteristic()))
+      continue;
+
+    const SrcMgr::ContentCache &CCEntry = FInfo.getContentCache();
+    OptionalFileEntryRef FEntry = CCEntry.OrigEntry;
+    if (!FEntry)
+      continue;
+
+    llvm::SmallString<256> Path = FEntry->getName();
+    llvm::sys::path::native(Path);
+    std::optional<llvm::MemoryBufferRef> Buffer = CCEntry.getBufferOrNone(
+        SM.getDiagnostics(), SM.getFileManager(), SourceLocation());
+    if (!Buffer) {
+      unsigned ID = SM.getDiagnostics().getCustomDiagID(
+          clang::DiagnosticsEngine::Warning,
+          "failed to embed source for \"%0\" into dx.source.contents");
+      SM.getDiagnostics().Report(ID) << Path;
+      continue;
+    }
+
+    if (&MainCCEntry != &CCEntry) {
+      Files.emplace_back(Path, Buffer->getBuffer());
+    } else {
+      // Main file should be at first position.
+      addFile(std::make_pair(Path, Buffer->getBuffer()));
+      MainFileName.emplace(Path);
+    }
+  }
+  assert(MainFileName && "Main file not found.");
+
+  // Files other that main one should be sorted by name.
+  llvm::sort(Files);
+#ifndef NDEBUG
+  for (unsigned I = 1; I < Files.size(); ++I)
+    assert((Files[I - 1].first != Files[I].first) &&
+           "duplicate files in dx.source.contents");
+#endif
+  llvm::for_each(Files, addFile);
+
+  SmallVector<llvm::Metadata *> Defines;
+  Defines.reserve(Macros.size());
+  for (const auto &Macro : Macros) {
+    // Ignore undefs.
+    if (!Macro.second)
+      Defines.emplace_back(llvm::MDString::get(Ctx, Macro.first));
+  }
+  M.getOrInsertNamedMetadata("dx.source.defines")
+      ->addOperand(llvm::MDNode::get(Ctx, Defines));
+
+  if (!CGM.getCodeGenOpts().MainFileName.empty())
+    llvm::sys::path::native(CGM.getCodeGenOpts().MainFileName, *MainFileName);
+  M.getOrInsertNamedMetadata("dx.source.mainFileName")
+      ->addOperand(
+          llvm::MDNode::get(Ctx, llvm::MDString::get(Ctx, *MainFileName)));
+
+  auto ParsedArgs = clang::parseEscapedCommandLine(
+      CGM.getCodeGenOpts().HLSLRecordCommandLine.c_str());
+  if (!ParsedArgs) {
+    unsigned DiagID = CGM.getDiags().getCustomDiagID(
+        DiagnosticsEngine::Error, "invalid escaped command line: %0");
+    CGM.getDiags().Report(DiagID) << llvm::toString(ParsedArgs.takeError());
+    return;
+  }
+  SmallVector<llvm::Metadata *> Args;
+  Args.reserve(ParsedArgs->size());
+  if (!ParsedArgs->empty())
+    for (const auto &Arg : llvm::drop_begin(*ParsedArgs))
+      Args.push_back(llvm::MDString::get(Ctx, Arg));
+  M.getOrInsertNamedMetadata("dx.source.args")
+      ->addOperand(llvm::MDNode::get(Ctx, Args));
+}
+
 // Find array variable declaration from DeclRef expression
 static const ValueDecl *getArrayDecl(ASTContext &AST, const Expr *E) {
   E = E->IgnoreImpCasts();
@@ -576,6 +683,10 @@ void CGHLSLRuntime::finishCodeGen() {
   Triple T(M.getTargetTriple());
   if (T.getArch() == Triple::ArchType::dxil)
     addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
+  if (!CodeGenOpts.DisableDXSourceMetadata &&
+      CodeGenOpts.getDebugInfo() >=
+          llvm::codegenoptions::DebugInfoKind::DebugInfoConstructor)
+    addSourceInfo(CGM, M);
   if (CodeGenOpts.ResMayAlias)
     M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.resmayalias", 1);
   if (CodeGenOpts.AllResourcesBound)
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index 117438c616ab5..54498de279f42 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -173,5 +173,6 @@ add_clang_library(clangCodeGen
   clangBasic
   clangFrontend
   clangLex
+  clangOptions
   clangSerialization
   )
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 8d8e00bbaf7d0..1372798b45cb9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8058,7 +8058,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   // By default, -gno-record-gcc-switches is set on and no recording.
   auto GRecordSwitches = false;
   auto FRecordSwitches = false;
-  if (shouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches)) {
+  bool DXRecordSwitches = false;
+  if (shouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches,
+                              DXRecordSwitches)) {
     auto FlagsArgString = renderEscapedCommandLine(TC, Args);
     if (TC.UseDwarfDebugFlags() || GRecordSwitches) {
       CmdArgs.push_back("-dwarf-debug-flags");
@@ -8068,6 +8070,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
       CmdArgs.push_back("-record-command-line");
       CmdArgs.push_back(FlagsArgString);
     }
+    if (DXRecordSwitches) {
+      CmdArgs.push_back("-fdx-record-command-line");
+      CmdArgs.push_back(FlagsArgString);
+    }
   }
 
   // Host-side offloading compilation receives all device-side outputs. Include
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 2ef7c1506e18d..dae0c67ad69c9 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3338,7 +3338,8 @@ const char *tools::renderEscapedCommandLine(const 
ToolChain &TC,
 bool tools::shouldRecordCommandLine(const ToolChain &TC,
                                     const llvm::opt::ArgList &Args,
                                     bool &FRecordCommandLine,
-                                    bool &GRecordCommandLine) {
+                                    bool &GRecordCommandLine,
+                                    bool &DXRecordCommandLine) {
   const Driver &D = TC.getDriver();
   const llvm::Triple &Triple = TC.getEffectiveTriple();
   const std::string &TripleStr = Triple.getTriple();
@@ -3349,13 +3350,15 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC,
   GRecordCommandLine =
       Args.hasFlag(options::OPT_grecord_command_line,
                    options::OPT_gno_record_command_line, false);
+  DXRecordCommandLine = Triple.isDXIL() && Args.hasArg(options::OPT_g_Flag);
   if (FRecordCommandLine && !Triple.isOSBinFormatELF() &&
       !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO())
     D.Diag(diag::err_drv_unsupported_opt_for_target)
         << 
Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args)
         << TripleStr;
 
-  return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine;
+  return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine ||
+         DXRecordCommandLine;
 }
 
 void tools::renderGlobalISelOptions(const Driver &D, const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 4c722a2e021eb..3620961b4c3b1 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -1284,7 +1284,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction 
&JA,
 
   bool FRecordCmdLine = false;
   bool GRecordCmdLine = false;
-  if (shouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine)) {
+  bool DXRecordCmdLine = false;
+  if (shouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine,
+                              DXRecordCmdLine)) {
     const char *CmdLine = renderEscapedCommandLine(TC, Args);
     if (FRecordCmdLine) {
       CmdArgs.push_back("-record-command-line");
diff --git a/clang/lib/Options/OptionUtils.cpp 
b/clang/lib/Options/OptionUtils.cpp
index e5aefa012f679..77f89552e852a 100644
--- a/clang/lib/Options/OptionUtils.cpp
+++ b/clang/lib/Options/OptionUtils.cpp
@@ -244,3 +244,35 @@ std::string clang::GetResourcesPath(const char *Argv0, 
void *MainAddr) {
       llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
   return GetResourcesPath(ClangExecutable);
 }
+
+static bool isSpaceOrNull(char c) { return !c || c == ' '; }
+
+static Expected<const char *> unescapeUntilSpace(const char *Arg,
+                                                 SmallVectorImpl<char> &Res) {
+  for (; !isSpaceOrNull(*Arg); ++Arg) {
+    if (*Arg == '\\') {
+      ++Arg;
+      if (*Arg != '\\' && *Arg != ' ')
+        return llvm::createStringError(
+            llvm::inconvertibleErrorCode(),
+            "only escaped backslashes and spaces are supported");
+    }
+    Res.push_back(*Arg);
+  }
+  return Arg;
+}
+
+Expected<SmallVector<SmallString<8>>>
+clang::parseEscapedCommandLine(const char *CommandLine) {
+  SmallVector<SmallString<8>> Res;
+  while (*CommandLine) {
+    Expected<const char *> ArgEnd =
+        unescapeUntilSpace(CommandLine, Res.emplace_back());
+    if (!ArgEnd)
+      return ArgEnd.takeError();
+    CommandLine = *ArgEnd;
+    if (*CommandLine == ' ')
+      ++CommandLine;
+  }
+  return Res;
+}
diff --git a/clang/test/CodeGenHLSL/Inputs/a.hlsl 
b/clang/test/CodeGenHLSL/Inputs/a.hlsl
new file mode 100644
index 0000000000000..9c132672dea82
--- /dev/null
+++ b/clang/test/CodeGenHLSL/Inputs/a.hlsl
@@ -0,0 +1,10 @@
+#ifndef GUARD
+#define GUARD
+
+#include "b.hlsl"
+
+float helper1_add(float a, float b) {
+  return a + b;
+}
+
+#endif
diff --git a/clang/test/CodeGenHLSL/Inputs/b.hlsl 
b/clang/test/CodeGenHLSL/Inputs/b.hlsl
new file mode 100644
index 0000000000000..798909fa50569
--- /dev/null
+++ b/clang/test/CodeGenHLSL/Inputs/b.hlsl
@@ -0,0 +1,3 @@
+float helper2_mul(float a, float b) {
+  return a * b;
+}
diff --git a/clang/test/CodeGenHLSL/SysInputs/c.hlsl 
b/clang/test/CodeGenHLSL/SysInputs/c.hlsl
new file mode 100644
index 0000000000000..30223007e1920
--- /dev/null
+++ b/clang/test/CodeGenHLSL/SysInputs/c.hlsl
@@ -0,0 +1,3 @@
+float sys_helper(float a, float b) {
+  return a * b;
+}
diff --git a/clang/test/CodeGenHLSL/debug/source-language.hlsl 
b/clang/test/CodeGenHLSL/debug/source-language.hlsl
index f1e63d17724ee..83099b288853f 100644
--- a/clang/test/CodeGenHLSL/debug/source-language.hlsl
+++ b/clang/test/CodeGenHLSL/debug/source-language.hlsl
@@ -5,24 +5,28 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -hlsl-entry main \
 // RUN:   -debug-info-kind=standalone -dwarf-version=4 -o - %s \
+// RUN:   -fdx-no-source-metadata \
 // RUN:   | FileCheck %s --check-prefix=CHECK-V4
 
 // SPIR-V target, DWARFv4
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -hlsl-entry main \
 // RUN:   -debug-info-kind=standalone -dwarf-version=4 -o - %s \
+// RUN:   -fdx-no-source-metadata \
 // RUN:   | FileCheck %s --check-prefix=CHECK-V4
 
 // DXIL target, DWARFv6
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -hlsl-entry main \
 // RUN:   -debug-info-kind=standalone -dwarf-version=6 -o - %s \
+// RUN:   -fdx-no-source-metadata \
 // RUN:   | FileCheck %s --check-prefix=CHECK-V6
 
 // SPIR-V target, DWARFv6
 // RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \
 // RUN:   -disable-llvm-passes -hlsl-entry main \
 // RUN:   -debug-info-kind=standalone -dwarf-version=6 -o - %s \
+// RUN:   -fdx-no-source-metadata \
 // RUN:   | FileCheck %s --check-prefix=CHECK-V6
 
 // CHECK-V4: !DICompileUnit(language: DW_LANG_HLSL,
diff --git a/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl 
b/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl
new file mode 100644
index 0000000000000..aa26a49feeef6
--- /dev/null
+++ b/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \
+// RUN:   -debug-info-kind=constructor -fdx-no-source-metadata -o - \
+// RUN:   -disable-llvm-passes %s | FileCheck %s
+
+// CHECK-NOT: !dx.source.contents
+// CHECK-NOT: !dx.source.defines
+// CHECK-NOT: !dx.source.mainFileName
+// CHECK-NOT: !dx.source.args
+
+float foo(float a, float b) {
+  return a + b;
+}
diff --git a/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl 
b/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl
new file mode 100644
index 0000000000000..65861f5a50fdc
--- /dev/null
+++ b/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \
+// RUN:   -debug-info-kind=constructor -I %S/Inputs -isystem %S/SysInputs \
+// RUN:   -o - %s | FileCheck %s
+
+#include "a.hlsl"
+#include "a.hlsl"
+#include <c.hlsl>
+
+// The main file appears first in dx.source.contents; included files are
+// appended in sorted order afterwards. Duplicate and system includes are 
ignored.
+
+// CHECK: !dx.source.contents = !{![[MAIN:[0-9]+]], ![[H1:[0-9]+]], 
![[H2:[0-9]+]]}
+// CHECK: !dx.source.mainFileName = !{![[MAIN_FILE_NAME:[0-9]+]]}
+// CHECK: ![[MAIN]] = !{!"{{.*[\\/]dx-source-metadata-includes.hlsl}}", 
!"{{.*}}"}
+// CHECK: ![[H1]] = !{!"{{.*[\\/]a.hlsl}}", !"{{.*}}"}
+// CHECK: ![[H2]] = !{!"{{.*[\\/]b.hlsl}}", !"{{.*}}"}
+// CHECK: ![[MAIN_FILE_NAME]] = 
!{!"{{.*[\\/]dx-source-metadata-includes.hlsl}}"}
+
+float foo(float a, float b) {
+  return helper1_add(a, b) + helper2_mul(a, b) + sys_helper(a, b);
+}
diff --git 
a/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl 
b/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl
new file mode 100644
index 0000000000000..b6557503ab118
--- /dev/null
+++ b/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl
@@ -0,0 +1,10 @@
+// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl 
-emit-llvm \
+// RUN:   -debug-info-kind=constructor \
+// RUN:   -fdx-record-command-line "clang_dxc \\" \
+// RUN:   -o - %s 2>&1 | FileCheck %s
+
+// CHECK: error: invalid escaped command line: only escaped backslashes and 
spaces are supported
+
+float foo(float a, float b) {
+  return a + b;
+}
diff --git a/clang/test/CodeGenHLSL/dx-source-metadata.hlsl 
b/clang/test/CodeGenHLSL/dx-source-metadata.hlsl
new file mode 100644
index 0000000000000..c523f36cc69b6
--- /dev/null
+++ b/clang/test/CodeGenHLSL/dx-source-metadata.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \
+// RUN:   -debug-info-kind=constructor -DUSER_DEF0=42 -DUSER_DEF1=43 -...
[truncated]

``````````

</details>


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

Reply via email to