Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

[spv-in] Conditional loop backedge not lowered to Statement::Loop with break_if expression #1977

@vili-1

Description

@vili-1

Naga (ab2806e) rejects this SPIR-V:

               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %7 "main"
               OpExecutionMode %7 LocalSize 1 1 1
               
               ; Below, we declare various types and variables for storage buffers.
               ; These decorations tell SPIR-V that the types and variables relate to storage buffers


               OpDecorate %size_1_struct_type BufferBlock
               OpMemberDecorate %size_1_struct_type 0 Offset 0
               OpDecorate %size_1_array_type ArrayStride 4

               OpDecorate %output_struct_type BufferBlock
               OpMemberDecorate %output_struct_type 0 Offset 0
               OpDecorate %output_array_type ArrayStride 4

               OpDecorate %directions_8_variable DescriptorSet 0
               OpDecorate %directions_8_variable Binding 0

               OpDecorate %directions_10_variable DescriptorSet 0
               OpDecorate %directions_10_variable Binding 1

               OpDecorate %directions_14_variable DescriptorSet 0
               OpDecorate %directions_14_variable Binding 2

               OpDecorate %directions_15_variable DescriptorSet 0
               OpDecorate %directions_15_variable Binding 3

               OpDecorate %output_variable DescriptorSet 0
               OpDecorate %output_variable Binding 4


          %1 = OpTypeVoid
          %2 = OpTypeFunction %1
          %3 = OpTypeBool
          %4 = OpTypeInt 32 0
          %5 = OpConstantTrue %3
          %6 = OpConstant %4 0
          

               %constant_0 = OpConstant %4 0
               %constant_1 = OpConstant %4 1
               %constant_7 = OpConstant %4 7
               %constant_8 = OpConstant %4 8
               %constant_9 = OpConstant %4 9
               %constant_10 = OpConstant %4 10
               %constant_11 = OpConstant %4 11
               %constant_12 = OpConstant %4 12
               %constant_13 = OpConstant %4 13
               %constant_14 = OpConstant %4 14
               %constant_15 = OpConstant %4 15


               ; Declaration of storage buffers for the 4 directions and the output
               

               %size_1_array_type = OpTypeArray %4 %constant_1
               %size_1_struct_type = OpTypeStruct %size_1_array_type
               %size_1_pointer_type = OpTypePointer Uniform %size_1_struct_type
               %directions_8_variable = OpVariable %size_1_pointer_type Uniform
               %directions_10_variable = OpVariable %size_1_pointer_type Uniform
               %directions_14_variable = OpVariable %size_1_pointer_type Uniform
               %directions_15_variable = OpVariable %size_1_pointer_type Uniform

               %output_array_type = OpTypeArray %4 %constant_7
               %output_struct_type = OpTypeStruct %output_array_type
               %output_pointer_type = OpTypePointer Uniform %output_struct_type
               %output_variable = OpVariable %output_pointer_type Uniform

               ; Pointer type for declaring local variables of int type
               %local_int_ptr = OpTypePointer Function %4

               ; Pointer type for integer data in a storage buffer
               %storage_buffer_int_ptr = OpTypePointer Uniform %4


          %7 = OpFunction %1 None %2

          %8 = OpLabel ; validCFG/SelectionHeader$2
               %output_index = OpVariable %local_int_ptr Function %constant_0
               %directions_8_index = OpVariable %local_int_ptr Function %constant_0
               %directions_10_index = OpVariable %local_int_ptr Function %constant_0
               %directions_14_index = OpVariable %local_int_ptr Function %constant_0
               %directions_15_index = OpVariable %local_int_ptr Function %constant_0


   %temp_8_0 = OpLoad %4 %output_index
   %temp_8_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_8_0
               OpStore %temp_8_1 %constant_8
   %temp_8_2 = OpIAdd %4 %temp_8_0 %constant_1
               OpStore %output_index %temp_8_2
   %temp_8_3 = OpLoad %4 %directions_8_index
   %temp_8_4 = OpAccessChain %storage_buffer_int_ptr %directions_8_variable %constant_0 %temp_8_3
   %temp_8_5 = OpLoad %4 %temp_8_4
   %temp_8_7 = OpIAdd %4 %temp_8_3 %constant_1
               OpStore %directions_8_index %temp_8_7
               OpSelectionMerge %9 None
               OpSwitch %temp_8_5 %10 1 %9


         %10 = OpLabel ; validCFG/SelectionHeader$1
  %temp_10_0 = OpLoad %4 %output_index
  %temp_10_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_10_0
               OpStore %temp_10_1 %constant_10
  %temp_10_2 = OpIAdd %4 %temp_10_0 %constant_1
               OpStore %output_index %temp_10_2
  %temp_10_3 = OpLoad %4 %directions_10_index
  %temp_10_4 = OpAccessChain %storage_buffer_int_ptr %directions_10_variable %constant_0 %temp_10_3
  %temp_10_5 = OpLoad %4 %temp_10_4
  %temp_10_7 = OpIAdd %4 %temp_10_3 %constant_1
               OpStore %directions_10_index %temp_10_7
               OpSelectionMerge %11 None
               OpSwitch %temp_10_5 %12 1 %11


         %12 = OpLabel ; validCFG/Block$0
               OpReturn


         %11 = OpLabel ; validCFG/LoopHeader$0
  %temp_11_0 = OpLoad %4 %output_index
  %temp_11_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_11_0
               OpStore %temp_11_1 %constant_11
  %temp_11_2 = OpIAdd %4 %temp_11_0 %constant_1
               OpStore %output_index %temp_11_2
               OpLoopMerge %13 %14 None
               OpBranch %14


         %14 = OpLabel ; validCFG/SelectionHeader$0
  %temp_14_0 = OpLoad %4 %output_index
  %temp_14_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_14_0
               OpStore %temp_14_1 %constant_14
  %temp_14_2 = OpIAdd %4 %temp_14_0 %constant_1
               OpStore %output_index %temp_14_2
  %temp_14_3 = OpLoad %4 %directions_14_index
  %temp_14_4 = OpAccessChain %storage_buffer_int_ptr %directions_14_variable %constant_0 %temp_14_3
  %temp_14_5 = OpLoad %4 %temp_14_4
  %temp_14_7 = OpIAdd %4 %temp_14_3 %constant_1
               OpStore %directions_14_index %temp_14_7
               OpSelectionMerge %15 None
               OpSwitch %temp_14_5 %15


         %15 = OpLabel ; validCFG/StructurallyReachableBlock$2
  %temp_15_0 = OpLoad %4 %output_index
  %temp_15_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_15_0
               OpStore %temp_15_1 %constant_15
  %temp_15_2 = OpIAdd %4 %temp_15_0 %constant_1
               OpStore %output_index %temp_15_2
  %temp_15_3 = OpLoad %4 %directions_15_index
  %temp_15_4 = OpAccessChain %storage_buffer_int_ptr %directions_15_variable %constant_0 %temp_15_3
  %temp_15_5 = OpLoad %4 %temp_15_4
  %temp_15_6 = OpIEqual %3 %temp_15_5 %constant_1
  %temp_15_7 = OpIAdd %4 %temp_15_3 %constant_1
               OpStore %directions_15_index %temp_15_7
               OpBranchConditional %temp_15_6 %13 %11


         %13 = OpLabel ; validCFG/StructurallyReachableBlock$1
  %temp_13_0 = OpLoad %4 %output_index
  %temp_13_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_13_0
               OpStore %temp_13_1 %constant_13
  %temp_13_2 = OpIAdd %4 %temp_13_0 %constant_1
               OpStore %output_index %temp_13_2
               OpBranch %9


          %9 = OpLabel ; validCFG/StructurallyReachableBlock$0
   %temp_9_0 = OpLoad %4 %output_index
   %temp_9_1 = OpAccessChain %storage_buffer_int_ptr %output_variable %constant_0 %temp_9_0
               OpStore %temp_9_1 %constant_9
   %temp_9_2 = OpIAdd %4 %temp_9_0 %constant_1
               OpStore %output_index %temp_9_2
               OpReturn

               OpFunctionEnd

We get:

The 'break' is used outside of a 'loop' or 'switch' context

The SPIR-V is valid, and spirv-val accepts it. There is no "break" outside any switch.

test_0_3842908924422139125

This is exactly the same as this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: front-endInput formats for conversionkind: bugSomething isn't workinglang: SPIR-VBinary SPIR-V input and output

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions