Comments (18)
Looping in @umar456 since he has better understanding of the validator.
from spirv-tools.
Looking into it now
from spirv-tools.
I haven't looked into this carefully, but I can reproduce a segfault using SDK 1.0.21 with VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_validation
.
Test case dEQP-VK.glsl.functions.control_flow.return_in_loop_vertex
triggers a segfault. Here is its source code. (Well, meta source code, maybe.)
from spirv-tools.
And this is a .vert
test case that will blow up the validator:
#version 310 es
float func (float a)
{
while (a < 100.0)
return -a;
return 1.0;
}
void main()
{
float t = func(50.0);
}
from spirv-tools.
Thanks. I have reproduced the error. I should have a fix shortly
from spirv-tools.
It seems to me that glslang is generating SPIR-V violating structured control flow rules.
Here is the disassembly of the above program:
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main"
OpSource ESSL 310
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
OpName %func_f1_ "func(f1;"
OpName %a "a"
OpName %t "t"
OpName %param "param"
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%8 = OpTypeFunction %float %_ptr_Function_float
%18 = OpConstant %float 100
%bool = OpTypeBool
%24 = OpConstant %float 1
%28 = OpConstant %float 50
%main = OpFunction %void None %3
%5 = OpLabel
%t = OpVariable %_ptr_Function_float Function
%param = OpVariable %_ptr_Function_float Function
OpStore %param %28
%30 = OpFunctionCall %float %func_f1_ %param
OpStore %t %30
OpReturn
OpFunctionEnd
%func_f1_ = OpFunction %float None %8
%a = OpFunctionParameter %_ptr_Function_float
%11 = OpLabel
OpBranch %12
%12 = OpLabel
OpLoopMerge %14 %15 None
OpBranch %16
%16 = OpLabel
%17 = OpLoad %float %a
%20 = OpFOrdLessThan %bool %17 %18
OpBranchConditional %20 %13 %14
%13 = OpLabel
%21 = OpLoad %float %a
%22 = OpFNegate %float %21
OpReturnValue %22
%15 = OpLabel
OpBranch %12
%14 = OpLabel
OpReturnValue %24
OpFunctionEnd
Loop header: %12
Merge block: %14
Continue target: %15
There is no continue block since there is no block "containing a branch to an OpLoopMerge instruction’s Continue Target."
There is no back edge block since Block %15
is not reachable at all, so doing a DF traversal from %11
won't encounter any back edge.
So, one SPIR-V structured control flow rules---all CFG back edges must branch to a loop header, with each loop header having exactly one back edge branching to it---is violated because of no back edge branching to the loop header.
With that said, the validator should still print an error instead of segfault.
But I feel I'm quite clumsy and dumb regarding interpreting the SPIR-V structured control flow spec. So it would be very nice if @johnkslang could shed some light on this issue.
from spirv-tools.
Well %15
is the continue block because it is specified as the continue target of OpLoopMerge %14 %15 None
and it is branching back to the loop header so it is a complete loop construct.
There doesn't seem to be a back-edge or a back-edge block as defined by the spec.
Back Edge: If a depth-first traversal is done on a function's CFG,
starting from the first block of the function, a /back edge/ is a branch
to a previously visited block. A /back-edge block/ is the block
containing such a branch.
The back-edge block should be %15
but the block cannot be reached in the CFG from the first block of the function. It should be reachable from the pseudo_entry block but this construct is not defined in the spec itself.
I don't know how else this function would be implemented in SPIR-V(unless we create an unconditionally false branch to the continue target which seems like a messy solution).
from spirv-tools.
Hmm, my interpretation of "Continue Block: A block containing a branch to an OpLoopMerge instruction’s Continue Target" in the spec is, continuing block is the block jumping to the continue target, not the continue target block itself. For this case, %15
is the continue target, and it doesn't contain a branch to itself, so it is not the continue block.
from spirv-tools.
Ahh sorry. You are right. I was confusing the continue construct with the continue block.
from spirv-tools.
Fixed with 6c61bf2
from spirv-tools.
So, one SPIR-V structured control flow rules---all CFG back edges must branch to a loop header, with each loop header having exactly one back edge branching to it---is violated because of no back edge branching to the loop header.
I see the last instruction in the loop OpBranch %12
as a branch back up to the loop header. I'm not quite clear on where the spec. is being violated here. Further, the specification says
each loop header having exactly one back edge branching to it
I don't immediately see where it says that branch must be reachable. Does it say that?
Or, is the problem truly solved, with no remaining questions?
from spirv-tools.
The back-edge is defined in a way that implies that it needs to be reachable. Here is the text:
/Back Edge/: If a depth-first traversal is done on a function's CFG,
starting from the first block of the function, a /back edge/ is a branch
to a previously visited block. A /back-edge block/ is the block
containing such a branch.
The branch up to the loop header is not reachable from the first block of the function so it is not part of the back-edge set.
Open Question:
Is this an acceptable definition of the back-edge or is it too restrictive?
How should the shader that raised the issue be represented in SPIR-V with the current definition?
from spirv-tools.
+1 to what @umar456 said. That's my interpretation of the spec too.
from spirv-tools.
Okay, so this is a side effect of adding a definition that was not originally there, and having the definition be too restrictive (it wasn't part of the core rule set for making all this work). I don't yet see the real reason the back edge must be reachable.
from spirv-tools.
The validator crash is resolved (software issue).
Still open is whether the given module uses valid structured control flow.
My opinion is +1 to what @umar456 said.
The spec's definition for back-edge is non-standard. (My reference is https://en.wikipedia.org/wiki/Depth-first_search)
I think the spec's definition of back-edge incorrectly allows cross edges to be classified as back-edges. I think it should instead say the equivalent of "A back-edge is an edge in the CFG from a block B to a block C that dominates B. B may be the same as C."
But I think glslang's code generation is sensible, and if anything the spec should be amended to clearly allow unreachable continue-constructs.
from spirv-tools.
For B-> C to be a back edge the "previously visited" phrasing to me means "I am currently visiting B, and the edge makes me want to visit C, but I have previously visited C". It's the "I am currently visiting B" part that is not satisfied if doing a DFS starting a the entry block of the function.
from spirv-tools.
@dneto0 sounds right; I'm transferring this to the headers project, at: KhronosGroup/SPIRV-Headers#16.
from spirv-tools.
+1 to moving the spec issue elsewhere.
While I still have this in my head:
- The validator uses the wikipedia sense of "back-edge".
- A couple of weeks ago (5065227 ) I changed the traversals in the validator to use an "augmented CFG" for the depth-first-search: add a pseudo-entry node before doing the DFS (a pseudo-exit node already existed). The point was to make the code and invariants more regular in the face of weird cases. In particular, unreachable nodes in the regular CFG end up being visited in the augmented CFG. And so the "back-edge" in the case given above ends up looking like a cross-edge in the augmented CFG, but also where the source is not dominated by the entry block.
from spirv-tools.
Related Issues (20)
- Fails to compile with GCC 13.2 (SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS not declated) HOT 1
- [spirv-opt] Inlining pass generates OpVariable of PhysicalStorageBuffer pointer type without AliasedPointer decoration. HOT 2
- spirv-val: VUID-FragCoord-FragCoord-04212 interaction with PerVertexKHR HOT 7
- Compile-related issue: SPIRV-Headers not found HOT 1
- new release https://github.com/KhronosGroup/SPIRV-Tools/archive/refs/tags/vulkan-sdk-1.3.280.0/SPIRV-Tools-1.3.280.0.tar.gz HOT 1
- [ spirv-opt ] Infinite recursion/crash with shader HOT 6
- SPIRV code fails validation after optimization HOT 3
- Wrong validation error when using RTA in SPV1.4? HOT 2
- Request: allow SpirvToolsEliminateDeadInputComponents() to strip non-trailing members from blocks HOT 2
- SpirvToolsEliminateDeadInputComponents() doesn't seem to be trimming array size down HOT 1
- spirv-val false positive error HOT 6
- Compilation error in validate_atomics.cpp HOT 2
- Using opt C API makes no change to shader HOT 1
- v2024.1 flatpak build fails: validation_state.cpp error: ‘BlockMatchSamplerQCOM’ is not a member of ‘spv::Decoration’ HOT 2
- How to add a new OpName with DescriptorSet and Binding HOT 2
- spirv-opt fma folding causes large performance degradation on Adreno HOT 6
- how to remove the OpVariable inst??
- Implicit LOD functions can be supported when compute shader derivatives are supported HOT 6
- How to compile on arm platform HOT 3
- Disallows TypeManager::GetId on non unique types
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spirv-tools.