KhronosGroup / KhronosGroup/SPIRV-Tools

incomplete validation of 'same block' data rule for images, samplers, and sampled images

Open
#6,053 2 comments 0 reactions 1 assignee Claimed by @dneto0 View on GitHub
Dominant language
C++
Stars
1.4k
Forks
709
Avg merge
1d 22h
Merged PRs (30d)
28

Description

SPIR-V has a universal data rule:

> All OpSampledImage instructions, or instructions that load an image or sampler reference, must be in the same block in which their Result are consumed.

(I was updated/clarified as part of https://gitlab.khronos.org/spirv/SPIR-V/-/merge_requests/286 )

My reading (and checking with the internal discussion) is that this covers where the definition of a value of type OpTypeImage, OpTypeSampler, and OpTypeSampledImage can go: it must be in the same basic block as its uses.

The validator reflects an older and less clear iteration of the rule.

So, for example, the attached spir-v module passes validation when it should not.

The value `%14` of type OpTypeSampledImage is used in a later basic block, in the definition of %32.

[x.redundancy-elimination.spvasm.txt](https://github.com/user-attachments/files/19350837/x.redundancy-elimination.spvasm.txt)

```
; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 11
; Bound: 34
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %data
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
OpName %data "data"
OpName %s "s"
OpDecorate %data Location 0
OpDecorate %s Binding 0
OpDecorate %s DescriptorSet 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%data = OpVariable %_ptr_Output_v4float Output
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%11 = OpTypeSampledImage %10
%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
%s = OpVariable %_ptr_UniformConstant_11 UniformConstant
%int = OpTypeInt 32 1
%v2int = OpTypeVector %int 2
%int_0 = OpConstant %int 0
%18 = OpConstantComposite %v2int %int_0 %int_0
%uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0
%_ptr_Output_float = OpTypePointer Output %float
%float_0 = OpConstant %float 0
%bool = OpTypeBool
%main = OpFunction %void None %3
%5 = OpLabel
%14 = OpLoad %11 %s
%19 = OpImage %10 %14
%20 = OpImageFetch %v4float %19 %18 Lod %int_0
OpStore %data %20
%24 = OpAccessChain %_ptr_Output_float %data %uint_0
%25 = OpLoad %float %24
%28 = OpFOrdEqual %bool %25 %float_0
OpSelectionMerge %30 None
OpBranchConditional %28 %29 %30
%29 = OpLabel
%32 = OpImage %10 %14
%33 = OpImageFetch %v4float %32 %18 Lod %int_0
OpStore %data %33
OpBranch %30
%30 = OpLabel
OpReturn
OpFunctionEnd
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.