KhronosGroup / SPIRV-Tools

Apache License 2.0
1.05k stars 549 forks source link

Validate non-uniform group instructions #1945

Open jaebaek opened 5 years ago

jaebaek commented 5 years ago

Validator currently checks only Scope \ argument of non-uniform group instructions. We need validations for them based on the spec e.g., result type.

For example, result type of OpGroupNonUniformBallot must be a vector of four components of integer type scalar, whose Signedness operand is 0. However, putting a vector of three components is not validated by SPIRV Validator.

; 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 %v3uint %uint_3 %true
         %26 = OpCompositeExtract %uint %24 0
         %27 = OpConvertUToF %float %26
         %29 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %19
               OpStore %29 %27
               OpReturn
               OpFunctionEnd
Hugobros3 commented 1 year ago

I've ran into the same issue. Here's a smaller example that I hand-minimized:

; SPIR-V
; Version: 1.6
; Generator: Khronos; 35
; Bound: 440
; Schema: 0
               OpCapability Shader
               OpCapability GroupNonUniform
               OpCapability GroupNonUniformBallot
               OpCapability Linkage
               OpMemoryModel Logical Simple

          %2 = OpTypeVoid
          %4 = OpTypeInt 32 0
         %39 = OpTypeStruct %4 %4

         %17 = OpTypeFunction %2
         %72 = OpConstant %4 3 ; Scope::Subgroup

         %35 = OpFunction %2 None %17
         %36 = OpLabel
         %82 = OpUndef %39 ; undef[(int32, int32)]
         %83 = OpGroupNonUniformBroadcastFirst %39 %72 %82 ; should be illegal
               OpReturn
               OpFunctionEnd