KhronosGroup / KhronosGroup/SPIRV-Tools
Stack overflow from `spvtools::opt::SSARewriter::GetReachingDef` recursion
- Dominant language
- C++
- Stars
- 1.4k
- Forks
- 709
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 28
Description
Achieved on a similar test case to #6104
We're compiling this HLSL shader which we need to compile with `-fcgl` to get to the SPIR-V
https://godbolt.org/z/r75PE1xWM
[The resulting SPIR-V attached](https://github.com/user-attachments/files/24124982/sometimes_crashes.zip)
I don't know how to invoke the `spv-opt` properly on Godbolt with illegal SPIR-V, probably assembler complains before even seeing `--legalize-hlsl`
https://godbolt.org/z/fEMcoKTv3
Results in this callstack before crashing in DXC without the `-fcgl` flag inside of SPIR-V Opt.
```
msvcp140d.dll!00007ff8c692076e() Unknown
msvcp140d.dll!00007ff8c691ea06() Unknown
> dxcompiler.dll!std::_Iterator_base12::_Adopt_locked(const std::_Container_base12 * _Parent) Line 1367 C++
dxcompiler.dll!std::_Iterator_base12::_Adopt(const std::_Container_base12 * _Parent) Line 1307 C++
dxcompiler.dll!std::_List_unchecked_const_iterator,std::equal_to,std::allocator>>>>>,std::_Iterator_base12>::_List_unchecked_const_iterator,std::equal_to,std::allocator>>>>>,std::_Iterator_base12>(std::_List_node,std::equal_to,std::allocator>>>,void *> * _Pnode, const std::_List_val,std::equal_to,std::allocator>>>>> * _Plist) Line 38 C++
dxcompiler.dll!std::_List_const_iterator,std::equal_to,std::allocator>>>>>>::_List_const_iterator,std::equal_to,std::allocator>>>>>>(std::_List_node,std::equal_to,std::allocator>>>,void *> *) C++
dxcompiler.dll!std::_List_iterator,std::equal_to,std::allocator>>>>>>::_List_iterator,std::equal_to,std::allocator>>>>>>(std::_List_node,std::equal_to,std::allocator>>>,void *> *) C++
dxcompiler.dll!std::list,std::equal_to,std::allocator>>>,std::allocator,std::equal_to,std::allocator>>>>>::_Make_iter(std::_List_node,std::equal_to,std::allocator>>>,void *> * _Where) Line 1137 C++
dxcompiler.dll!std::_Hash,std::equal_to,std::allocator>>,std::_Uhash_compare,std::equal_to>,std::allocator,std::equal_to,std::allocator>>>>,0>>::find(spvtools::opt::BasicBlock * const & _Keyval) Line 1231 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetValueAtBlock(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 247 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 260 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
dxcompiler.dll!spvtools::opt::SSARewriter::GetReachingDef(unsigned int var_id, spvtools::opt::BasicBlock * bb) Line 268 C++
...
The maximum number of stack frames supported by Visual Studio has been exceeded.
```
Its also possible that the illegal SPIR-V emitted by DXC is causing infinite recursion / loops in the parsed SPIR-V, because the input HLSL is just a simple unit-test shader, so I doubt the chains are so deep to actually overflow the stack which is a few megs.
Contributor guide
Research direction
Start at spvtools::opt::SSARewriter::GetReachingDef and inspect the attached SPIR-V and the HLSL reproducer from the linked Godbolt examples. Determine whether the recursion is caused by illegal SPIR-V or a genuinely deep reaching-definition chain; done means the reproducer no longer overflows the stack.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100