dfranx / SPIRV-VM

Virtual machine for executing SPIR-V

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Infinite loop in a simple shader

mtehver opened this issue · comments

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.