KhronosGroup / SPIRV-Tools

Apache License 2.0
1.04k stars 544 forks source link

Validator does not check Scope id argument of OpGroupNonUniform instructions correctly. #1944

Open jaebaek opened 5 years ago

jaebaek commented 5 years ago

SPIRV spec says "All \ used for Scope and Memory Semantics must be of an OpConstant.", but SPIRV Validator does not check the Scope \ argument of OpGroupNonUniform instructions correctly.

In the following code, %24 = OpGroupNonUniformBallot %v4uint %19 %true is not valid. %19 must be a OpConstant.

; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 34
; Schema: 0
               OpCapability Shader
               OpCapability GroupNonUniform
               OpCapability GroupNonUniformBallot
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSize 128 1 1
               OpSource GLSL 450
               OpSourceExtension "GL_KHR_shader_subgroup_ballot"
               OpSourceExtension "GL_KHR_shader_subgroup_basic"
               OpName %main "main"
               OpName %layout_result "layout_result"
               OpMemberName %layout_result 0 "result"
               OpName %_ ""
               OpName %layout_foo "layout_foo"
               OpMemberName %layout_foo 0 "foo"
               OpName %__0 ""
               OpDecorate %_runtimearr_float ArrayStride 4
               OpMemberDecorate %layout_result 0 Offset 0
               OpDecorate %layout_result BufferBlock
               OpDecorate %_ DescriptorSet 0
               OpDecorate %_ Binding 1
               OpMemberDecorate %layout_foo 0 Offset 0
               OpDecorate %layout_foo BufferBlock
               OpDecorate %__0 DescriptorSet 0
               OpDecorate %__0 Binding 0
               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
%_runtimearr_float = OpTypeRuntimeArray %float
%layout_result = OpTypeStruct %_runtimearr_float
%_ptr_Uniform_layout_result = OpTypePointer Uniform %layout_result
          %_ = OpVariable %_ptr_Uniform_layout_result Uniform
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
       %uint = OpTypeInt 32 0
 %layout_foo = OpTypeStruct %uint
%_ptr_Uniform_layout_foo = OpTypePointer Uniform %layout_foo
        %__0 = OpVariable %_ptr_Uniform_layout_foo Uniform
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
       %bool = OpTypeBool
       %true = OpConstantTrue %bool
     %v4uint = OpTypeVector %uint 4
     %uint_3 = OpConstant %uint 3
     %uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
     %v3uint = OpTypeVector %uint 3
   %uint_128 = OpConstant %uint 128
     %uint_1 = OpConstant %uint 1
%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_128 %uint_1 %uint_1
       %main = OpFunction %void None %3
          %5 = OpLabel
         %18 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0
         %19 = OpLoad %uint %18
         %24 = OpGroupNonUniformBallot %v4uint %19 %true
         %26 = OpCompositeExtract %uint %24 0
         %27 = OpConvertUToF %float %26
         %29 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %19
               OpStore %29 %27
               OpReturn
               OpFunctionEnd
jaebaek commented 5 years ago

I checked Scope \ and Memory Semantics \ for both OpAtomicIAdd and OpMemoryBarrier. SPIRV Validator did not check that Scope \ and Memory Semantics \ are not OpConstant.

Those Scope \ and Memory Semantics \ issues are not only the problem of OpGroupNonUniform instructions but also the problem of other instructions that have Scope \ and Memory Semantics \ as arguments.