Open
Description
Executing amber -t spv1.3 -v 1.1 reduced-infinite-loop.amber
hangs presumably due to an infinite loop. I can reproduce this on master (commit d15c42482).
Here is the reduced amber code:
#!amber
SHADER compute compute_shader SPIRV-ASM
; Follow the path:
; <8> -> edge_2 -> <9> -> <15> -> 12
;
; 3 CFG nodes have OpBranchConditional or OpSwitch as their terminators (denoted <n>): 8, 9 and 15.
;
; To follow this path, we need to make these decisions each time we reach 8, 9 or 15.
; This path was generated with the seed 408688807413651389 and has length 4.
;
; We equip the shader with 3+1 storage buffers:
; - An input storage buffer with the directions for each node 8, 9 or 15
; - An output storage buffer that records the blocks that are executed
; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 15
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %7 "main"
OpExecutionMode %7 LocalSize 1 1 1
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_9_variable DescriptorSet 0
OpDecorate %directions_9_variable Binding 1
OpDecorate %output_variable DescriptorSet 0
OpDecorate %output_variable Binding 3
%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_2 = OpConstant %4 2
%constant_8 = OpConstant %4 8
%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_9_variable = OpVariable %size_1_pointer_type Uniform
%output_array_type = OpTypeArray %4 %constant_2
%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$1
%output_index = OpVariable %local_int_ptr Function %constant_0
%directions_8_index = OpVariable %local_int_ptr Function %constant_0
%directions_9_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 %11 2 %9
%10 = OpLabel ; validCFG/Block$0
OpReturn
%11 = OpLabel ; validCFG/StructurallyReachableBlock$4
OpReturn
%9 = OpLabel ; validCFG/LoopHeader$0
%temp_9_3 = OpLoad %4 %directions_9_index
%temp_9_4 = OpAccessChain %storage_buffer_int_ptr %directions_9_variable %constant_0 %temp_9_3
%temp_9_5 = OpLoad %4 %temp_9_4
%temp_9_6 = OpIEqual %3 %temp_9_5 %constant_1
%temp_9_7 = OpIAdd %4 %temp_9_3 %constant_1
OpStore %directions_9_index %temp_9_7
OpLoopMerge %12 %13 None
OpBranchConditional %temp_9_6 %14 %15
%15 = OpLabel ; validCFG/SelectionHeader$0
OpSelectionMerge %16 None
OpBranchConditional %5 %12 %17
%17 = OpLabel ; validCFG/StructurallyReachableBlock$3
OpBranchConditional %5 %12 %13
%16 = OpLabel ; validCFG/StructurallyReachableBlock$2
OpBranch %14
%12 = OpLabel ; validCFG/StructurallyReachableBlock$1
OpReturn
%13 = OpLabel ; validCFG/StructurallyReachableBlock$0
OpBranch %9
%14 = OpLabel ; validCFG/StructurallyReachableBlock$5
OpReturn
OpFunctionEnd
END
BUFFER directions_8 DATA_TYPE uint32 STD430 DATA 2 END
BUFFER directions_9 DATA_TYPE uint32 STD430 DATA 0 END
BUFFER output DATA_TYPE uint32 STD430 SIZE 4 FILL 0
PIPELINE compute pipeline
ATTACH compute_shader
BIND BUFFER directions_8 AS storage DESCRIPTOR_SET 0 BINDING 0
BIND BUFFER directions_9 AS storage DESCRIPTOR_SET 0 BINDING 1
BIND BUFFER output AS storage DESCRIPTOR_SET 0 BINDING 3
END
RUN pipeline 1 1 1
EXPECT directions_8 IDX 0 EQ 2
EXPECT directions_9 IDX 0 EQ 0
EXPECT output IDX 0 EQ 8 9
I can't get rid of the input load and output store in SH0
or the input load in LH0
.
@vili-1 validCFG/Block$0
looks structurally reachable to me. Do you think this is related to the issue mentioned previously?