-
Notifications
You must be signed in to change notification settings - Fork 664
opt: error: Module contains unreachable blocks during merge return. Run dead branch elimination before merge return. #2746
Description
Issue found using GraphicsFuzz.
Tool versions:
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