diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-07-22 16:28:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-22 16:28:54 +0300 |
commit | c24d5a7b902d550163b83d60b1b58a7ad6d91ca4 (patch) | |
tree | f2f6f0a0bcf5244b56af4515a875ec2a22d875c8 | |
parent | 8ba0820c9d6b23df5009a46bcdc970a11f861048 (diff) | |
parent | be904dcc1ee9f8979c8ef14dde503d1d87f4ba66 (diff) |
Merge pull request #1985 from KhronosGroup/fix-1973
Handle collapsed loops similar to collapsed selections.
-rw-r--r-- | reference/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp | 51 | ||||
-rw-r--r-- | shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp | 118 | ||||
-rw-r--r-- | spirv_parser.cpp | 11 |
3 files changed, 179 insertions, 1 deletions
diff --git a/reference/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp b/reference/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp new file mode 100644 index 00000000..5a5f212f --- /dev/null +++ b/reference/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp @@ -0,0 +1,51 @@ +#version 450 +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(binding = 1, std430) buffer _2_9 +{ + uint _m0[2]; +} _9; + +layout(binding = 0, std430) buffer _4_8 +{ + uint _m0[3]; +} _8; + +layout(binding = 2, std430) buffer _6_10 +{ + uint _m0[11]; +} _10; + +void main() +{ + uint _34 = 0u; + uint _35 = 0u; + uint _36 = 0u; + _10._m0[_34] = 8u; + _34++; + for (;;) + { + _10._m0[_34] = 9u; + _34++; + uint _44 = _35; + _35 = _44 + 1u; + if (_8._m0[_44] == 1u) + { + _10._m0[_34] = 12u; + _34++; + _36++; + _10._m0[_34] = 13u; + _34++; + _10._m0[_34] = 11u; + _34++; + continue; + } + else + { + break; + } + } + _10._m0[_34] = 10u; + _34++; +} + diff --git a/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp b/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp new file mode 100644 index 00000000..e1efd564 --- /dev/null +++ b/shaders-no-opt/asm/comp/fuzz-collapse-degenerate-loop.asm.comp @@ -0,0 +1,118 @@ +; SPIR-V +; Version: 1.3 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 71 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" + OpExecutionMode %1 LocalSize 1 1 1 + OpDecorate %_struct_2 BufferBlock + OpMemberDecorate %_struct_2 0 Offset 0 + OpDecorate %_arr_uint_uint_2 ArrayStride 4 + OpDecorate %_struct_4 BufferBlock + OpMemberDecorate %_struct_4 0 Offset 0 + OpDecorate %_arr_uint_uint_3 ArrayStride 4 + OpDecorate %_struct_6 BufferBlock + OpMemberDecorate %_struct_6 0 Offset 0 + OpDecorate %_arr_uint_uint_11 ArrayStride 4 + OpDecorate %8 DescriptorSet 0 + OpDecorate %8 Binding 0 + OpDecorate %9 DescriptorSet 0 + OpDecorate %9 Binding 1 + OpDecorate %10 DescriptorSet 0 + OpDecorate %10 Binding 2 + %void = OpTypeVoid + %12 = OpTypeFunction %void + %bool = OpTypeBool + %uint = OpTypeInt 32 0 + %true = OpConstantTrue %bool + %uint_0 = OpConstant %uint 0 + %uint_0_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 + %uint_8 = OpConstant %uint 8 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %uint_11 = OpConstant %uint 11 + %uint_12 = OpConstant %uint 12 + %uint_13 = OpConstant %uint 13 + %uint_14 = OpConstant %uint 14 +%_arr_uint_uint_2 = OpTypeArray %uint %uint_2 + %_struct_2 = OpTypeStruct %_arr_uint_uint_2 +%_ptr_Uniform__struct_2 = OpTypePointer Uniform %_struct_2 + %9 = OpVariable %_ptr_Uniform__struct_2 Uniform +%_arr_uint_uint_3 = OpTypeArray %uint %uint_3 + %_struct_4 = OpTypeStruct %_arr_uint_uint_3 +%_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4 + %8 = OpVariable %_ptr_Uniform__struct_4 Uniform +%_arr_uint_uint_11 = OpTypeArray %uint %uint_11 + %_struct_6 = OpTypeStruct %_arr_uint_uint_11 +%_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6 + %10 = OpVariable %_ptr_Uniform__struct_6 Uniform +%_ptr_Function_uint = OpTypePointer Function %uint +%_ptr_Uniform_uint = OpTypePointer Uniform %uint + %1 = OpFunction %void None %12 + %33 = OpLabel + %34 = OpVariable %_ptr_Function_uint Function %uint_0_0 + %35 = OpVariable %_ptr_Function_uint Function %uint_0_0 + %36 = OpVariable %_ptr_Function_uint Function %uint_0_0 + %37 = OpLoad %uint %34 + %38 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %37 + OpStore %38 %uint_8 + %39 = OpIAdd %uint %37 %uint_1 + OpStore %34 %39 + OpBranch %40 + %40 = OpLabel + %41 = OpLoad %uint %34 + %42 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %41 + OpStore %42 %uint_9 + %43 = OpIAdd %uint %41 %uint_1 + OpStore %34 %43 + %44 = OpLoad %uint %35 + %45 = OpAccessChain %_ptr_Uniform_uint %8 %uint_0_0 %44 + %46 = OpLoad %uint %45 + %47 = OpIEqual %bool %46 %uint_1 + %48 = OpIAdd %uint %44 %uint_1 + OpStore %35 %48 + OpLoopMerge %49 %50 None + OpBranchConditional %47 %51 %49 + %51 = OpLabel + %52 = OpLoad %uint %34 + %53 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %52 + OpStore %53 %uint_12 + %54 = OpIAdd %uint %52 %uint_1 + OpStore %34 %54 + %55 = OpLoad %uint %36 + %56 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0_0 %55 + %57 = OpLoad %uint %56 + %58 = OpIEqual %bool %57 %uint_1 + %59 = OpIAdd %uint %55 %uint_1 + OpStore %36 %59 + OpLoopMerge %60 %61 None + OpBranchConditional %58 %60 %60 + %49 = OpLabel + %62 = OpLoad %uint %34 + %63 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %62 + OpStore %63 %uint_10 + %64 = OpIAdd %uint %62 %uint_1 + OpStore %34 %64 + OpReturn + %60 = OpLabel + %65 = OpLoad %uint %34 + %66 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %65 + OpStore %66 %uint_13 + %67 = OpIAdd %uint %65 %uint_1 + OpStore %34 %67 + OpBranch %50 + %61 = OpLabel + OpBranch %51 + %50 = OpLabel + %68 = OpLoad %uint %34 + %69 = OpAccessChain %_ptr_Uniform_uint %10 %uint_0_0 %68 + OpStore %69 %uint_11 + %70 = OpIAdd %uint %68 %uint_1 + OpStore %34 %70 + OpBranch %40 + OpFunctionEnd diff --git a/spirv_parser.cpp b/spirv_parser.cpp index 262aa70f..c290a5eb 100644 --- a/spirv_parser.cpp +++ b/spirv_parser.cpp @@ -1020,7 +1020,16 @@ void Parser::parse(const Instruction &instruction) } else { - ir.block_meta[current_block->next_block] &= ~ParsedIR::BLOCK_META_SELECTION_MERGE_BIT; + // Collapse loops if we have to. + bool collapsed_loop = current_block->true_block == current_block->merge_block && + current_block->merge == SPIRBlock::MergeLoop; + + if (collapsed_loop) + { + ir.block_meta[current_block->merge_block] &= ~ParsedIR::BLOCK_META_LOOP_MERGE_BIT; + ir.block_meta[current_block->continue_block] &= ~ParsedIR::BLOCK_META_CONTINUE_BIT; + } + current_block->next_block = current_block->true_block; current_block->condition = 0; current_block->true_block = 0; |