Skip to content

opt: error: Module contains unreachable blocks during merge return. Run dead branch elimination before merge return. #2746

@paulthomson

Description

@paulthomson

bug_report.zip

Issue found using GraphicsFuzz.

Tool versions:

  • glslangValidator commit hash: e383c5f
  • spirv-opt commit hash: 230c9e4

To reproduce:

glslangValidator -V shader.frag -o shader.frag.spv

spirv-opt shader.frag.spv -o temp.spv --validate-after-all --private-to-local --if-conversion --eliminate-dead-inserts --eliminate-dead-branches --reduce-load-size --vector-dce --ccp --redundancy-elimination --convert-local-access-chains --eliminate-dead-inserts --ccp --eliminate-dead-branches --merge-blocks --eliminate-local-single-block --eliminate-local-single-block --copy-propagate-arrays --inline-entry-points-exhaustive --ccp --eliminate-local-multi-store --inline-entry-points-exhaustive --reduce-load-size --ccp --eliminate-local-single-block --eliminate-dead-branches --merge-return --copy-propagate-arrays --eliminate-dead-branches --combine-access-chains --inline-entry-points-exhaustive

The following shader files are included in the attached archive, some of which are also shown inline below:

  • 0_glsl/shader.frag
  • 1_spirv/shader.frag.spv
  • 1_spirv_asm/shader.frag.asm
  • 2_spirv_opt/shader.frag.spv <-- ignore

0_glsl/shader.frag:

#version 310 es
precision highp float;

float nb_mod(float limit)
{
 if(float(1) >= limit)
  {
   return 1.0;
  }
 for(
     int _injected_loop_counter = 0;
     _injected_loop_counter < 2;
     ++_injected_loop_counter
 )
  {
   for(
       int _injected_loop_counter = 0;
       _injected_loop_counter < 1;
       ++_injected_loop_counter
   )
    {
     return 1.0;
    }
  }
}
void main()
{
 nb_mod(gl_FragCoord.x);
}

1_spirv_asm/shader.frag.asm:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 56
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main" %48
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %10 "nb_mod(f1;"
               OpName %9 "limit"
               OpName %21 "_injected_loop_counter"
               OpName %31 "_injected_loop_counter"
               OpName %48 "gl_FragCoord"
               OpName %49 "param"
               OpDecorate %21 RelaxedPrecision
               OpDecorate %28 RelaxedPrecision
               OpDecorate %31 RelaxedPrecision
               OpDecorate %37 RelaxedPrecision
               OpDecorate %41 RelaxedPrecision
               OpDecorate %42 RelaxedPrecision
               OpDecorate %43 RelaxedPrecision
               OpDecorate %44 RelaxedPrecision
               OpDecorate %48 BuiltIn FragCoord
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeFloat 32
          %7 = OpTypePointer Function %6
          %8 = OpTypeFunction %6 %7
         %12 = OpConstant %6 1
         %14 = OpTypeBool
         %19 = OpTypeInt 32 1
         %20 = OpTypePointer Function %19
         %22 = OpConstant %19 0
         %29 = OpConstant %19 2
         %38 = OpConstant %19 1
         %46 = OpTypeVector %6 4
         %47 = OpTypePointer Input %46
         %48 = OpVariable %47 Input
         %50 = OpTypeInt 32 0
         %51 = OpConstant %50 0
         %52 = OpTypePointer Input %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %49 = OpVariable %7 Function
         %53 = OpAccessChain %52 %48 %51
         %54 = OpLoad %6 %53
               OpStore %49 %54
         %55 = OpFunctionCall %6 %10 %49
               OpReturn
               OpFunctionEnd
         %10 = OpFunction %6 None %8
          %9 = OpFunctionParameter %7
         %11 = OpLabel
         %21 = OpVariable %20 Function
         %31 = OpVariable %20 Function
         %13 = OpLoad %6 %9
         %15 = OpFOrdGreaterThanEqual %14 %12 %13
               OpSelectionMerge %17 None
               OpBranchConditional %15 %16 %17
         %16 = OpLabel
               OpReturnValue %12
         %17 = OpLabel
               OpStore %21 %22
               OpBranch %23
         %23 = OpLabel
               OpLoopMerge %25 %26 None
               OpBranch %27
         %27 = OpLabel
         %28 = OpLoad %19 %21
         %30 = OpSLessThan %14 %28 %29
               OpBranchConditional %30 %24 %25
         %24 = OpLabel
               OpStore %31 %22
               OpBranch %32
         %32 = OpLabel
               OpLoopMerge %34 %35 None
               OpBranch %36
         %36 = OpLabel
         %37 = OpLoad %19 %31
         %39 = OpSLessThan %14 %37 %38
               OpBranchConditional %39 %33 %34
         %33 = OpLabel
               OpReturnValue %12
         %35 = OpLabel
         %41 = OpLoad %19 %31
         %42 = OpIAdd %19 %41 %38
               OpStore %31 %42
               OpBranch %32
         %34 = OpLabel
               OpBranch %26
         %26 = OpLabel
         %43 = OpLoad %19 %21
         %44 = OpIAdd %19 %43 %38
               OpStore %21 %44
               OpBranch %23
         %25 = OpLabel
         %45 = OpUndef %6
               OpReturnValue %45
               OpFunctionEnd

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions