From 9602e5c5dff15c6de49f518d772352d36758a4e2 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Fri, 16 Jan 2026 17:53:11 -0800 Subject: [PATCH 1/5] Improve dxc version printing - No longer skip QI for IDxcVersionInfo2 based on build, since that's for implementer, not user. - Print CustomVersionString from IDxcVersionInfo3 if available. - Remove ifdefs for _WIN32 around file/product version calls, because that's handled in the function. - Only print product version string if available for dxil.dll, since that's what it does for dxcompiler.dll. --- tools/clang/tools/dxclib/dxc.cpp | 144 ++++++++++++++++++------------- 1 file changed, 82 insertions(+), 62 deletions(-) diff --git a/tools/clang/tools/dxclib/dxc.cpp b/tools/clang/tools/dxclib/dxc.cpp index 8388cd70e0..6f9c1fd08d 100644 --- a/tools/clang/tools/dxclib/dxc.cpp +++ b/tools/clang/tools/dxclib/dxc.cpp @@ -1242,83 +1242,103 @@ namespace dxc { // Writes compiler version info to stream void WriteDxCompilerVersionInfo(llvm::raw_ostream &OS, const char *ExternalLib, const char *ExternalFn, DllLoader &DxcSupport) { - if (DxcSupport.IsEnabled()) { - UINT32 compilerMajor = 1; - UINT32 compilerMinor = 0; - CComPtr VerInfo; - -#ifdef SUPPORT_QUERY_GIT_COMMIT_INFO - UINT32 commitCount = 0; - CComHeapPtr commitHash; - CComPtr VerInfo2; -#endif // SUPPORT_QUERY_GIT_COMMIT_INFO - - const char *dllName = !ExternalLib ? kDxCompilerLib : ExternalLib; - std::string compilerName(dllName); - if (ExternalFn) - compilerName = compilerName + "!" + ExternalFn; - - if (SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &VerInfo))) { - VerInfo->GetVersion(&compilerMajor, &compilerMinor); -#ifdef SUPPORT_QUERY_GIT_COMMIT_INFO - if (SUCCEEDED(VerInfo->QueryInterface(&VerInfo2))) - VerInfo2->GetCommitInfo(&commitCount, &commitHash); -#endif // SUPPORT_QUERY_GIT_COMMIT_INFO - OS << compilerName << ": " << compilerMajor << "." << compilerMinor; - } + if (!DxcSupport.IsEnabled()) + return; + + UINT32 VersionMajor = 1; + UINT32 VersionMinor = 0; + CComPtr VerInfo; + + UINT32 CommitCount = 0; + CComHeapPtr CommitHash; + CComPtr VerInfo2; + + CComHeapPtr CustomVersionString; + CComPtr VerInfo3; + + const char *dllName = !ExternalLib ? kDxCompilerLib : ExternalLib; + std::string CompilerName(dllName); + if (ExternalFn) + CompilerName = CompilerName + "!" + ExternalFn; + + if (SUCCEEDED(DxcSupport.CreateInstance(CLSID_DxcCompiler, &VerInfo))) { + VerInfo->GetVersion(&VersionMajor, &VersionMinor); + if (SUCCEEDED(VerInfo->QueryInterface(&VerInfo2))) + VerInfo2->GetCommitInfo(&CommitCount, &CommitHash); + if (SUCCEEDED(VerInfo->QueryInterface(&VerInfo3))) + VerInfo3->GetCustomVersionString(&CustomVersionString); + OS << CompilerName << ": " << VersionMajor << "." << VersionMinor; + } else if (!ExternalLib) { // compiler.dll 1.0 did not support IdxcVersionInfo - else if (!ExternalLib) { - OS << compilerName << ": " << 1 << "." << 0; - } else { - // ExternalLib/ExternalFn, no version info: - OS << compilerName; - } + OS << CompilerName << ": " << 1 << "." << 0; + } else { + // ExternalLib/ExternalFn, no version info: + OS << CompilerName; + return; + } -#ifdef _WIN32 + // TBD: remove IsOldDevBuild if we no longer need it + bool IsOldDevBuild = false; + { unsigned int version[4]; if (GetDLLFileVersionInfo(dllName, version)) { - // back-compat - old dev buidls had version 3.7.0.0 + // back-compat - old dev builds had version 3.7.0.0 if (version[0] == 3 && version[1] == 7 && version[2] == 0 && version[3] == 0) { -#endif - OS << "(dev" -#ifdef SUPPORT_QUERY_GIT_COMMIT_INFO - << ";" << commitCount << "-" - << (commitHash.m_pData ? commitHash.m_pData : "") -#endif // SUPPORT_QUERY_GIT_COMMIT_I#else - << ")"; -#ifdef _WIN32 - } else { - std::string productVersion; - if (GetDLLProductVersionInfo(dllName, productVersion)) { - OS << " - " << productVersion; - } + IsOldDevBuild = true; } } -#endif } + + if (CommitCount != 0 || CommitHash.m_pData || IsOldDevBuild) { + OS << "("; + + if (IsOldDevBuild) + OS << "dev-"; + + OS << CommitCount << "-" + << (CommitHash.m_pData ? CommitHash.m_pData : "") + << ")"; + } + + if (CustomVersionString.m_pData) + OS << "(" << CustomVersionString.m_pData << ")"; + + std::string ProductVersion; + if (GetDLLProductVersionInfo(dllName, ProductVersion)) + OS << " - " << ProductVersion; } // Writes compiler version info to stream void WriteDXILVersionInfo(llvm::raw_ostream &OS, DllLoader &DxilSupport) { - if (DxilSupport.IsEnabled()) { - CComPtr VerInfo; - if (SUCCEEDED(DxilSupport.CreateInstance(CLSID_DxcValidator, &VerInfo))) { - UINT32 validatorMajor, validatorMinor = 0; - VerInfo->GetVersion(&validatorMajor, &validatorMinor); - OS << "; " << kDxilLib << ": " << validatorMajor << "." << validatorMinor; + if (!DxilSupport.IsEnabled()) + return; - } - // dxil.dll 1.0 did not support IdxcVersionInfo - else { - OS << "; " << kDxilLib << ": " << 1 << "." << 0; - } - unsigned int version[4]; - if (GetDLLFileVersionInfo(kDxilLib, version)) { - OS << "(" << version[0] << "." << version[1] << "." << version[2] << "." - << version[3] << ")"; - } + UINT32 VersionMajor = 1; + UINT32 VersionMinor = 0; + CComPtr VerInfo; + + UINT32 CommitCount = 0; + CComHeapPtr CommitHash; + CComPtr VerInfo2; + + if (SUCCEEDED(DxilSupport.CreateInstance(CLSID_DxcValidator, &VerInfo))) { + VerInfo->GetVersion(&VersionMajor, &VersionMinor); + if (SUCCEEDED(VerInfo->QueryInterface(&VerInfo2))) + VerInfo2->GetCommitInfo(&CommitCount, &CommitHash); } + + OS << "; " << kDxilLib << ": " << VersionMajor << "." << VersionMinor; + + if (CommitCount != 0 || CommitHash.m_pData) { + OS << "(" << CommitCount << "-" + << (CommitHash.m_pData ? CommitHash.m_pData : "") + << ")"; + } + + std::string ProductVersion; + if (GetDLLProductVersionInfo(kDxilLib, ProductVersion)) + OS << " - " << ProductVersion; } } // namespace dxc From 93ba0122de9d4b91ee3ed6a43b704a634b369a96 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Fri, 16 Jan 2026 17:59:11 -0800 Subject: [PATCH 2/5] Remove IsOldDevBuild handling I don't think this is necessary anymore. --- tools/clang/tools/dxclib/dxc.cpp | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/tools/clang/tools/dxclib/dxc.cpp b/tools/clang/tools/dxclib/dxc.cpp index 6f9c1fd08d..48dd69cea8 100644 --- a/tools/clang/tools/dxclib/dxc.cpp +++ b/tools/clang/tools/dxclib/dxc.cpp @@ -1277,26 +1277,8 @@ void WriteDxCompilerVersionInfo(llvm::raw_ostream &OS, const char *ExternalLib, return; } - // TBD: remove IsOldDevBuild if we no longer need it - bool IsOldDevBuild = false; - { - unsigned int version[4]; - if (GetDLLFileVersionInfo(dllName, version)) { - // back-compat - old dev builds had version 3.7.0.0 - if (version[0] == 3 && version[1] == 7 && version[2] == 0 && - version[3] == 0) { - IsOldDevBuild = true; - } - } - } - - if (CommitCount != 0 || CommitHash.m_pData || IsOldDevBuild) { - OS << "("; - - if (IsOldDevBuild) - OS << "dev-"; - - OS << CommitCount << "-" + if (CommitCount != 0 || CommitHash.m_pData) { + OS << "(" << CommitCount << "-" << (CommitHash.m_pData ? CommitHash.m_pData : "") << ")"; } From b13e25072c7a1591d6286e2a348a853c9b7a067a Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Fri, 16 Jan 2026 18:25:20 -0800 Subject: [PATCH 3/5] DxCompiler wrapper: Implement IDxcVersionInfo(2,3) --- lib/DxcSupport/dxcapi.extval.cpp | 33 +++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/DxcSupport/dxcapi.extval.cpp b/lib/DxcSupport/dxcapi.extval.cpp index 66b94a2a20..b50fd05e0c 100644 --- a/lib/DxcSupport/dxcapi.extval.cpp +++ b/lib/DxcSupport/dxcapi.extval.cpp @@ -171,7 +171,10 @@ class ExtValidationArgHelper { // '-Vd' and sets the default validator version with '-validator-version'. // After a successful compilation, it uses the provided IDxcValidator to // perform validation when it would normally be performed. -class ExternalValidationCompiler : public IDxcCompiler2, public IDxcCompiler3 { +class ExternalValidationCompiler : public IDxcCompiler2, + public IDxcCompiler3, + public IDxcVersionInfo2, + public IDxcVersionInfo3 { public: ExternalValidationCompiler(IMalloc *Malloc, IDxcValidator *OtherValidator, IUnknown *OtherCompiler) @@ -203,8 +206,10 @@ class ExternalValidationCompiler : public IDxcCompiler2, public IDxcCompiler3 { // calls. CComPtr NewWrapper( Alloc(m_pMalloc, Validator, TempCompiler)); - return DoBasicQueryInterface( - NewWrapper.p, Iid, ResultObject); + return DoBasicQueryInterface(NewWrapper.p, Iid, + ResultObject); } catch (...) { return E_FAIL; } @@ -305,6 +310,28 @@ class ExternalValidationCompiler : public IDxcCompiler2, public IDxcCompiler3 { return cast()->Disassemble(Object, Riid, ResultObject); } + // IDxcVersionInfo implementation + HRESULT STDMETHODCALLTYPE GetVersion(_Out_ UINT32 *pMajor, + _Out_ UINT32 *pMinor) override { + return cast()->GetVersion(pMajor, pMinor); + } + HRESULT STDMETHODCALLTYPE GetFlags(_Out_ UINT32 *pFlags) override { + return cast()->GetFlags(pFlags); + } + + // IDxcVersionInfo2 implementation + HRESULT STDMETHODCALLTYPE + GetCommitInfo(_Out_ UINT32 *pCommitCount, + _Outptr_result_z_ char **pCommitHash) override { + return cast()->GetCommitInfo(pCommitCount, pCommitHash); + } + + // IDxcVersionInfo3 implementation + HRESULT STDMETHODCALLTYPE + GetCustomVersionString(_Outptr_result_z_ char **pVersionString) override { + return cast()->GetCustomVersionString(pVersionString); + } + private: CComPtr Validator; From 0a19646e1fee371df58e8188f27615bfc2549e61 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Fri, 16 Jan 2026 19:53:50 -0800 Subject: [PATCH 4/5] Fix dxil validator version printing and parsing for tests No point printing some dxil module version if not used. Print it when you set the env var, in which case, the full DXIL path would be printed, so it needs to be less strict about what's immediately before the dxil.dll/libdxil.so name. --- tools/clang/test/lit.cfg | 12 +++--------- tools/clang/tools/dxclib/dxc.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/tools/clang/test/lit.cfg b/tools/clang/test/lit.cfg index 1af4a05958..563a4915cb 100644 --- a/tools/clang/test/lit.cfg +++ b/tools/clang/test/lit.cfg @@ -522,24 +522,18 @@ def get_dxil_version(): else: result = subprocess.run([lit.util.which('dxc', llvm_tools_dir), "--version"], stdout=subprocess.PIPE) output = result.stdout.decode("utf-8") - dxcPat = re.compile(r"(dxcompiler.dll|libdxcompiler.so|libdxcompiler.dylib): (?P[0-9]+)\.(?P[0-9]+).") + dxcPat = re.compile(r"(dxcompiler\.dll|libdxcompiler\.so|libdxcompiler\.dylib): (?P[0-9]+)\.(?P[0-9]+)") m = dxcPat.search(output) dxcMajor = int(m.group("dxcMajor")) dxcMinor = int(m.group("dxcMinor")) - dxilPat = re.compile(r"; (dxil.dll|libdxil.so): (?P[0-9]+)\.(?P[0-9]+)") + dxilPat = re.compile(r"(dxil\.dll|libdxil\.so|libdxil\.dylib): (?P[0-9]+)\.(?P[0-9]+)") m = dxilPat.search(output) if None == m: return dxcMajor, dxcMinor dxilMajor = int(m.group("dxilMajor")) dxilMinor = int(m.group("dxilMinor")) - if dxcMajor < dxilMajor: - return dxcMajor, dxcMinor - if dxcMajor > dxilMajor: - return dxilMajor, dxilMinor - if dxcMinor < dxilMinor: - return dxcMajor, dxcMinor - return dxilMajor, dxilMinor + return min((dxcMajor, dxcMinor), (dxilMajor, dxilMinor)) dxilMajor, dxilMinor = get_dxil_version() if dxilMajor == 1: diff --git a/tools/clang/tools/dxclib/dxc.cpp b/tools/clang/tools/dxclib/dxc.cpp index 48dd69cea8..4d12cffe56 100644 --- a/tools/clang/tools/dxclib/dxc.cpp +++ b/tools/clang/tools/dxclib/dxc.cpp @@ -1292,7 +1292,8 @@ void WriteDxCompilerVersionInfo(llvm::raw_ostream &OS, const char *ExternalLib, } // Writes compiler version info to stream -void WriteDXILVersionInfo(llvm::raw_ostream &OS, DllLoader &DxilSupport) { +void WriteDXILVersionInfo(llvm::raw_ostream &OS, const char *DxilLib, + DllLoader &DxilSupport) { if (!DxilSupport.IsEnabled()) return; @@ -1310,7 +1311,7 @@ void WriteDXILVersionInfo(llvm::raw_ostream &OS, DllLoader &DxilSupport) { VerInfo2->GetCommitInfo(&CommitCount, &CommitHash); } - OS << "; " << kDxilLib << ": " << VersionMajor << "." << VersionMinor; + OS << "; " << DxilLib << ": " << VersionMajor << "." << VersionMinor; if (CommitCount != 0 || CommitHash.m_pData) { OS << "(" << CommitCount << "-" @@ -1319,7 +1320,7 @@ void WriteDXILVersionInfo(llvm::raw_ostream &OS, DllLoader &DxilSupport) { } std::string ProductVersion; - if (GetDLLProductVersionInfo(kDxilLib, ProductVersion)) + if (GetDLLProductVersionInfo(DxilLib, ProductVersion)) OS << " - " << ProductVersion; } @@ -1332,10 +1333,12 @@ void DxcContext::GetCompilerVersionInfo(llvm::raw_string_ostream &OS) { m_Opts.ExternalFn.empty() ? nullptr : m_Opts.ExternalFn.data(), m_dxcSupport); - // Print validator if exists - SpecificDllLoader DxilSupport; - DxilSupport.InitializeForDll(kDxilLib, "DxcCreateInstance"); - WriteDXILVersionInfo(OS, DxilSupport); + // Print validator version if external + if (m_dxcSupport.IsEnabled() && !m_dxcSupport.getDxilDllPath().empty()) { + SpecificDllLoader DxilSupport; + WriteDXILVersionInfo(OS, m_dxcSupport.getDxilDllPath().c_str(), + m_dxcSupport); + } } #ifndef VERSION_STRING_SUFFIX From 295b2374672be36f7df8695b909640f2cd8aa6df Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Sat, 17 Jan 2026 10:32:54 -0800 Subject: [PATCH 5/5] Skip LitDXILValidation when testing compiler output against released validators. --- tools/clang/test/LitDXILValidation/lit.local.cfg | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/clang/test/LitDXILValidation/lit.local.cfg diff --git a/tools/clang/test/LitDXILValidation/lit.local.cfg b/tools/clang/test/LitDXILValidation/lit.local.cfg new file mode 100644 index 0000000000..a8d9b3b933 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/lit.local.cfg @@ -0,0 +1,2 @@ +# Skip when testing compiler's DXIL output against released validators. +config.unsupported = "dxc_dxil_dll_path" in config.available_features \ No newline at end of file