protonscr

Fails to build with Clang/LLVM 22

dxvkclosed build
doitsujin/dxvk#5545 · opened 2026-03-09 by NTULINUX · updated 2026-03-23 · 8 comments · github
NNTULINUX 2026-03-09 github

https://github.com/llvm/llvm-project/issues/167709#issuecomment-4021564275

In file included from ../src/dxvk/dxvk_pipemanager.cpp:1:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/optional:269:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/__format/range_format.h:19:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/__format/fmt_pair_like.h:14:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/__fwd/pair.h:14:
/home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/__fwd/tuple.h:40:52: error: a parameter pack may not be accessed at an out of bounds index
   40 |   using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Tp...>;
In file included from ../src/dxvk/dxvk_pipemanager.cpp:1:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/optional:1805:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/iterator:755:
In file included from /home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/variant:1647:
/home/fedora/llvm-mingw-polly/x86_64-w64-mingw32/include/c++/v1/tuple:1120:52: error: no member named '__base_' in 'std::tuple<>'
 1120 |   return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();

This is supposedly fixed in the release/22.x branch however I am still getting this issue. I am not sure if this is strictly an LLVM/Clang bug still or an issue with DXVK so I am posting this here as well.

Thanks!

Ddoitsujin maintainer 2026-03-09 github

What exactly does that error even come from? The message isn't exactly helpful and our use of std::optional is generally fairly basic, but I don't want to remove it for the sake of non-default build environments, especially without understanding what the problem is.

NNTULINUX 2026-03-09 github

What info do you need? I'm happy to help!

I made a fully static LLVM/Clang toolchain which uses the 22.x branch from the LLVM project:

https://github.com/NTULINUX/llvm-mingw/releases/tag/Polly-03082026

You can easily reproduce this issue with that binary toolchain. Just be sure to update your $PATH.

Mms178 2026-03-11 github

If someone is interested in a patch for 2.7.1 for this issue, this is what AI suggested to me and solves this issue with the latest Clang/LLVM 22 llvm-mingw toolchain for me:

--- a/src/dxvk/dxvk_pipemanager.cpp	2026-03-01 15:59:36.414718665 +0100
+++ b/src/dxvk/dxvk_pipemanager.cpp	2026-03-01 16:13:00.338026808 +0100
@@ -23,7 +23,7 @@ namespace dxvk {
     std::unique_lock lock(m_lock);
     this->startWorkers();
 
-    m_tasksTotal += 1;
+    m_tasksTotal.fetch_add(1, std::memory_order_relaxed);
 
     m_buckets[uint32_t(priority)].queue.emplace(library);
     notifyWorkers(priority);
@@ -38,7 +38,7 @@ namespace dxvk {
     this->startWorkers();
 
     pipeline->acquirePipeline();
-    m_tasksTotal += 1;
+    m_tasksTotal.fetch_add(1, std::memory_order_relaxed);
 
     m_buckets[uint32_t(priority)].queue.emplace(pipeline, state);
     notifyWorkers(priority);
@@ -165,7 +165,7 @@ namespace dxvk {
         entry.graphicsPipeline->releasePipeline();
       }
 
-      m_tasksCompleted += 1;
+      m_tasksCompleted.fetch_add(1, std::memory_order_relaxed);
     }
   }
 
@@ -193,9 +193,9 @@ namespace dxvk {
     const DxvkComputePipelineShaders& shaders) {
     if (shaders.cs == nullptr)
       return nullptr;
-    
+
     std::lock_guard<dxvk::mutex> lock(m_mutex);
-    
+
     auto pair = m_computePipelines.find(shaders);
     if (pair != m_computePipelines.end())
       return &pair->second;
@@ -205,11 +205,9 @@ namespace dxvk {
 
     auto library = findPipelineLibraryLocked(key);
 
-    auto iter = m_computePipelines.emplace(
-      std::piecewise_construct,
-      std::tuple(shaders),
-      std::tuple(m_device, this, shaders, library));
-    return &iter.first->second;
+    auto result = m_computePipelines.try_emplace(
+      shaders, m_device, this, shaders, library);
+    return &result.first->second;
   }
   
   
@@ -217,9 +215,9 @@ namespace dxvk {
     const DxvkGraphicsPipelineShaders& shaders) {
     if (shaders.vs == nullptr)
       return nullptr;
-    
+
     std::lock_guard<dxvk::mutex> lock(m_mutex);
-    
+
     auto pair = m_graphicsPipelines.find(shaders);
     if (pair != m_graphicsPipelines.end())
       return &pair->second;
@@ -257,11 +255,9 @@ namespace dxvk {
       }
     }
 
-    auto iter = m_graphicsPipelines.emplace(
-      std::piecewise_construct,
-      std::tuple(shaders),
-      std::tuple(m_device, this, shaders, vsLibrary, fsLibrary));
-    return &iter.first->second;
+    auto result = m_graphicsPipelines.try_emplace(
+      shaders, m_device, this, shaders, vsLibrary, fsLibrary);
+    return &result.first->second;
   }
 
   
@@ -276,15 +272,8 @@ namespace dxvk {
     const DxvkGraphicsPipelineVertexInputState& state) {
     std::lock_guard<dxvk::mutex> lock(m_mutex);
 
-    auto pair = m_vertexInputLibraries.find(state);
-    if (pair != m_vertexInputLibraries.end())
-      return &pair->second;
-
-    auto iter = m_vertexInputLibraries.emplace(
-      std::piecewise_construct,
-      std::tuple(state),
-      std::tuple(m_device, state));
-    return &iter.first->second;
+    auto result = m_vertexInputLibraries.try_emplace(state, m_device, state);
+    return &result.first->second;
   }
 
 
@@ -292,15 +281,8 @@ namespace dxvk {
     const DxvkGraphicsPipelineFragmentOutputState& state) {
     std::lock_guard<dxvk::mutex> lock(m_mutex);
 
-    auto pair = m_fragmentOutputLibraries.find(state);
-    if (pair != m_fragmentOutputLibraries.end())
-      return &pair->second;
-
-    auto iter = m_fragmentOutputLibraries.emplace(
-      std::piecewise_construct,
-      std::tuple(state),
-      std::tuple(m_device, state));
-    return &iter.first->second;
+    auto result = m_fragmentOutputLibraries.try_emplace(state, m_device, state);
+    return &result.first->second;
   }
   
   
@@ -352,39 +334,22 @@ namespace dxvk {
 
   const DxvkDescriptorSetLayout* DxvkPipelineManager::createDescriptorSetLayout(
     const DxvkDescriptorSetLayoutKey& key) {
-    auto pair = m_descriptorSetLayouts.find(key);
-    if (pair != m_descriptorSetLayouts.end())
-      return &pair->second;
-
-    auto iter = m_descriptorSetLayouts.emplace(
-      std::piecewise_construct,
-      std::tuple(key),
-      std::tuple(m_device, key));
-    return &iter.first->second;
+    auto result = m_descriptorSetLayouts.try_emplace(key, m_device, key);
+    return &result.first->second;
   }
 
 
   const DxvkPipelineLayout* DxvkPipelineManager::createPipelineLayout(
     const DxvkPipelineLayoutKey& key) {
-    auto pair = m_pipelineLayouts.find(key);
-    if (pair != m_pipelineLayouts.end())
-      return &pair->second;
-
-    auto iter = m_pipelineLayouts.emplace(
-      std::piecewise_construct,
-      std::tuple(key),
-      std::tuple(m_device, key));
-    return &iter.first->second;
+    auto result = m_pipelineLayouts.try_emplace(key, m_device, key);
+    return &result.first->second;
   }
 
 
   DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibraryLocked(
     const DxvkShaderPipelineLibraryKey& key) {
-    auto iter = m_shaderLibraries.emplace(
-      std::piecewise_construct,
-      std::tuple(key),
-      std::tuple(m_device, this, key));
-    return &iter.first->second;
+    auto result = m_shaderLibraries.try_emplace(key, m_device, this, key);
+    return &result.first->second;
   }
 
 
@@ -392,11 +357,8 @@ namespace dxvk {
     std::lock_guard<dxvk::mutex> lock(m_mutex);
     DxvkShaderPipelineLibraryKey key;
 
-    auto iter = m_shaderLibraries.emplace(
-      std::piecewise_construct,
-      std::tuple(),
-      std::tuple(m_device, this, key));
-    return &iter.first->second;
+    auto result = m_shaderLibraries.try_emplace(key, m_device, this, key);
+    return &result.first->second;
   }

Ddoitsujin maintainer 2026-03-11 github

I mean that patch is obviously complete garbage like everything generated by AI, but I guess the problem is that... tuple construction doesn't work for some stupid reason?

I really don't have time to investigate weird issues with non-default toolchains right now, but this doesn't really make an awful lot of sense.

NNTULINUX 2026-03-11 github

I hope you find time eventually because there won't be anymore updates to Clang 21, and GCC takes a dump when you throw AVX instructions at it in a MinGW environment. Been a problem for over a decade and it hasn't gotten any better since. AVX is a good thing.

This is how someone fixed it here:

https://github.com/bitcoin-core/libmultiprocess/commit/22bec918c97d32660c4694c3a8b5af4cdbb88481

It's also possible the LLVM devs will fix the behavior eventually, I'm not sure if this is by design though.

Ddoitsujin maintainer 2026-03-11 github

OK, that explains what the issue is and boils it down to something I can eventually work with.

I don't think it is illegal to use empty tuples for piecewise_construct though, so this probably shouldn't be happening in the first place.

Been a problem for over a decade and it hasn't gotten any better since.

I'm painfully aware, but it's low priority because a) our default builds will need to support non-AVX CPUs anyway and b) AVX does next to nothing for DXVK in general. Out of all the "new" instruction sets I'd guess that BMI is the most interesting one.

NNTULINUX 2026-03-11 github

SWEET! Also, good to know!

NNTULINUX 2026-03-23 github

You're awesome!

Nothing extracted yet.