Infinite loop in a simple shader
mtehver opened this issue · comments
Mark Tehver commented
The following shader fails to execute correctly, the loop never terminates:
#version 430
layout(location = 0) out float _30;
void main()
{
float _37;
_37 = 0.5;
for (int _36 = 0; _36 < 4; )
{
_37 = sin(_37);
_36++;
continue;
}
_30 = _37;
}
The SPIR-V corresponding to this shader:
; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 10
; Bound: 34
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %30
OpExecutionMode %4 OriginUpperLeft
OpDecorate %30 Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%float_0_5 = OpConstant %float 0.5
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%int_4 = OpConstant %int 4
%bool = OpTypeBool
%int_1 = OpConstant %int 1
%_ptr_Output_float = OpTypePointer Output %float
%30 = OpVariable %_ptr_Output_float Output
%4 = OpFunction %void None %3
%5 = OpLabel
OpBranch %14
%14 = OpLabel
%33 = OpPhi %float %float_0_5 %5 %24 %15
%32 = OpPhi %int %int_0 %5 %27 %15
%22 = OpSLessThan %bool %32 %int_4
OpLoopMerge %16 %15 None
OpBranchConditional %22 %15 %16
%15 = OpLabel
%24 = OpExtInst %float %1 Sin %33
%27 = OpIAdd %int %32 %int_1
OpBranch %14
%16 = OpLabel
OpStore %30 %33
OpReturn
OpFunctionEnd
After looking closely at the issue, it seems that the current version does not properly handle Phi nodes. The issue is related to incrementing counter in %27
and then jumping to %14
and then handling Phi node in %32
. Due to the way the block labels are handled, %27
is never copied into %32
and this causes the infinite loop. I have created a PR that fixes the issue.