Skip to content

Commit 8891bd3

Browse files
Merge pull request #1466 from KhronosGroup/fix-1465
Clean up and fix awkward conditional branch codegen.
2 parents 16d9fea + 2144274 commit 8891bd3

4 files changed

Lines changed: 215 additions & 37 deletions

File tree

reference/opt/shaders/asm/frag/loop-body-dominator-continue-access.asm.frag

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ void main()
5555
break;
5656
}
5757
}
58+
if (_225)
59+
{
60+
_228 = _229;
61+
break;
62+
}
5863
_228 = -1;
5964
break;
6065
} while(false);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#version 450
2+
3+
layout(binding = 0, std140) uniform type_gCBuffarrayIndex
4+
{
5+
uint gArrayIndex;
6+
} gCBuffarrayIndex;
7+
8+
uniform sampler2D SPIRV_Cross_Combinedg_textureArray0SPIRV_Cross_DummySampler;
9+
uniform sampler2D SPIRV_Cross_Combinedg_textureArray1SPIRV_Cross_DummySampler;
10+
uniform sampler2D SPIRV_Cross_Combinedg_textureArray2SPIRV_Cross_DummySampler;
11+
uniform sampler2D SPIRV_Cross_Combinedg_textureArray3SPIRV_Cross_DummySampler;
12+
13+
layout(location = 0) out vec4 out_var_SV_TARGET;
14+
15+
vec4 _32;
16+
17+
void main()
18+
{
19+
vec4 _80;
20+
do
21+
{
22+
vec4 _77;
23+
bool _78;
24+
switch (gCBuffarrayIndex.gArrayIndex)
25+
{
26+
case 0u:
27+
{
28+
_77 = texelFetch(SPIRV_Cross_Combinedg_textureArray0SPIRV_Cross_DummySampler, ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), 0).xy, 0);
29+
_78 = true;
30+
break;
31+
}
32+
case 1u:
33+
{
34+
_77 = texelFetch(SPIRV_Cross_Combinedg_textureArray1SPIRV_Cross_DummySampler, ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), 0).xy, 0);
35+
_78 = true;
36+
break;
37+
}
38+
case 2u:
39+
{
40+
_77 = texelFetch(SPIRV_Cross_Combinedg_textureArray2SPIRV_Cross_DummySampler, ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), 0).xy, 0);
41+
_78 = true;
42+
break;
43+
}
44+
case 3u:
45+
{
46+
_77 = texelFetch(SPIRV_Cross_Combinedg_textureArray3SPIRV_Cross_DummySampler, ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), 0).xy, 0);
47+
_78 = true;
48+
break;
49+
}
50+
default:
51+
{
52+
_77 = _32;
53+
_78 = false;
54+
break;
55+
}
56+
}
57+
if (_78)
58+
{
59+
_80 = _77;
60+
break;
61+
}
62+
_80 = vec4(0.0, 1.0, 0.0, 1.0);
63+
break;
64+
} while(false);
65+
out_var_SV_TARGET = _80;
66+
}
67+
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
; SPIR-V
2+
; Version: 1.3
3+
; Generator: Google spiregg; 0
4+
; Bound: 81
5+
; Schema: 0
6+
OpCapability Shader
7+
OpCapability Sampled1D
8+
OpCapability Image1D
9+
OpCapability SampledBuffer
10+
OpCapability ImageBuffer
11+
OpMemoryModel Logical GLSL450
12+
OpEntryPoint Fragment %PsTextureLoadArray "main" %gl_FragCoord %out_var_SV_TARGET
13+
OpExecutionMode %PsTextureLoadArray OriginUpperLeft
14+
OpSource HLSL 500
15+
OpName %type_2d_image "type.2d.image"
16+
OpName %type_gCBuffarrayIndex "type.gCBuffarrayIndex"
17+
OpMemberName %type_gCBuffarrayIndex 0 "gArrayIndex"
18+
OpName %gCBuffarrayIndex "gCBuffarrayIndex"
19+
OpName %g_textureArray0 "g_textureArray0"
20+
OpName %g_textureArray1 "g_textureArray1"
21+
OpName %g_textureArray2 "g_textureArray2"
22+
OpName %g_textureArray3 "g_textureArray3"
23+
OpName %out_var_SV_TARGET "out.var.SV_TARGET"
24+
OpName %PsTextureLoadArray "PsTextureLoadArray"
25+
OpDecorate %gl_FragCoord BuiltIn FragCoord
26+
OpDecorate %out_var_SV_TARGET Location 0
27+
OpDecorate %gCBuffarrayIndex DescriptorSet 0
28+
OpDecorate %gCBuffarrayIndex Binding 0
29+
OpDecorate %g_textureArray0 DescriptorSet 0
30+
OpDecorate %g_textureArray0 Binding 0
31+
OpDecorate %g_textureArray1 DescriptorSet 0
32+
OpDecorate %g_textureArray1 Binding 1
33+
OpDecorate %g_textureArray2 DescriptorSet 0
34+
OpDecorate %g_textureArray2 Binding 2
35+
OpDecorate %g_textureArray3 DescriptorSet 0
36+
OpDecorate %g_textureArray3 Binding 3
37+
OpMemberDecorate %type_gCBuffarrayIndex 0 Offset 0
38+
OpDecorate %type_gCBuffarrayIndex Block
39+
%uint = OpTypeInt 32 0
40+
%int = OpTypeInt 32 1
41+
%int_0 = OpConstant %int 0
42+
%float = OpTypeFloat 32
43+
%float_0 = OpConstant %float 0
44+
%float_1 = OpConstant %float 1
45+
%v4float = OpTypeVector %float 4
46+
%18 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
47+
%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
48+
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
49+
%type_gCBuffarrayIndex = OpTypeStruct %uint
50+
%_ptr_Uniform_type_gCBuffarrayIndex = OpTypePointer Uniform %type_gCBuffarrayIndex
51+
%_ptr_Input_v4float = OpTypePointer Input %v4float
52+
%_ptr_Output_v4float = OpTypePointer Output %v4float
53+
%void = OpTypeVoid
54+
%24 = OpTypeFunction %void
55+
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
56+
%v3int = OpTypeVector %int 3
57+
%v2int = OpTypeVector %int 2
58+
%gCBuffarrayIndex = OpVariable %_ptr_Uniform_type_gCBuffarrayIndex Uniform
59+
%g_textureArray0 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
60+
%g_textureArray1 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
61+
%g_textureArray2 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
62+
%g_textureArray3 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
63+
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
64+
%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
65+
%uint_0 = OpConstant %uint 0
66+
%bool = OpTypeBool
67+
%false = OpConstantFalse %bool
68+
%true = OpConstantTrue %bool
69+
%32 = OpUndef %v4float
70+
%PsTextureLoadArray = OpFunction %void None %24
71+
%33 = OpLabel
72+
%34 = OpLoad %v4float %gl_FragCoord
73+
OpSelectionMerge %35 None
74+
OpSwitch %uint_0 %36
75+
%36 = OpLabel
76+
%37 = OpAccessChain %_ptr_Uniform_uint %gCBuffarrayIndex %int_0
77+
%38 = OpLoad %uint %37
78+
OpSelectionMerge %39 None
79+
OpSwitch %38 %40 0 %41 1 %42 2 %43 3 %44
80+
%41 = OpLabel
81+
%45 = OpCompositeExtract %float %34 0
82+
%46 = OpCompositeExtract %float %34 1
83+
%47 = OpConvertFToS %int %45
84+
%48 = OpConvertFToS %int %46
85+
%49 = OpCompositeConstruct %v3int %47 %48 %int_0
86+
%50 = OpVectorShuffle %v2int %49 %49 0 1
87+
%51 = OpLoad %type_2d_image %g_textureArray0
88+
%52 = OpImageFetch %v4float %51 %50 Lod %int_0
89+
OpBranch %39
90+
%42 = OpLabel
91+
%53 = OpCompositeExtract %float %34 0
92+
%54 = OpCompositeExtract %float %34 1
93+
%55 = OpConvertFToS %int %53
94+
%56 = OpConvertFToS %int %54
95+
%57 = OpCompositeConstruct %v3int %55 %56 %int_0
96+
%58 = OpVectorShuffle %v2int %57 %57 0 1
97+
%59 = OpLoad %type_2d_image %g_textureArray1
98+
%60 = OpImageFetch %v4float %59 %58 Lod %int_0
99+
OpBranch %39
100+
%43 = OpLabel
101+
%61 = OpCompositeExtract %float %34 0
102+
%62 = OpCompositeExtract %float %34 1
103+
%63 = OpConvertFToS %int %61
104+
%64 = OpConvertFToS %int %62
105+
%65 = OpCompositeConstruct %v3int %63 %64 %int_0
106+
%66 = OpVectorShuffle %v2int %65 %65 0 1
107+
%67 = OpLoad %type_2d_image %g_textureArray2
108+
%68 = OpImageFetch %v4float %67 %66 Lod %int_0
109+
OpBranch %39
110+
%44 = OpLabel
111+
%69 = OpCompositeExtract %float %34 0
112+
%70 = OpCompositeExtract %float %34 1
113+
%71 = OpConvertFToS %int %69
114+
%72 = OpConvertFToS %int %70
115+
%73 = OpCompositeConstruct %v3int %71 %72 %int_0
116+
%74 = OpVectorShuffle %v2int %73 %73 0 1
117+
%75 = OpLoad %type_2d_image %g_textureArray3
118+
%76 = OpImageFetch %v4float %75 %74 Lod %int_0
119+
OpBranch %39
120+
%40 = OpLabel
121+
OpBranch %39
122+
%39 = OpLabel
123+
%77 = OpPhi %v4float %52 %41 %60 %42 %68 %43 %76 %44 %32 %40
124+
%78 = OpPhi %bool %true %41 %true %42 %true %43 %true %44 %false %40
125+
OpSelectionMerge %79 None
126+
OpBranchConditional %78 %35 %79
127+
%79 = OpLabel
128+
OpBranch %35
129+
%35 = OpLabel
130+
%80 = OpPhi %v4float %77 %39 %18 %79
131+
OpStore %out_var_SV_TARGET %80
132+
OpReturn
133+
OpFunctionEnd

spirv_glsl.cpp

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12732,64 +12732,37 @@ void CompilerGLSL::branch(BlockID from, uint32_t cond, BlockID true_block, Block
1273212732
auto &from_block = get<SPIRBlock>(from);
1273312733
BlockID merge_block = from_block.merge == SPIRBlock::MergeSelection ? from_block.next_block : BlockID(0);
1273412734

12735-
// If we branch directly to a selection merge target, we don't need a code path.
12736-
// This covers both merge out of if () / else () as well as a break for switch blocks.
12737-
bool true_sub = !is_conditional(true_block);
12738-
bool false_sub = !is_conditional(false_block);
12735+
// If we branch directly to our selection merge target, we don't need a code path.
12736+
bool true_block_needs_code = true_block != merge_block || flush_phi_required(from, true_block);
12737+
bool false_block_needs_code = false_block != merge_block || flush_phi_required(from, false_block);
1273912738

12740-
bool true_block_is_selection_merge = true_block == merge_block;
12741-
bool false_block_is_selection_merge = false_block == merge_block;
12739+
if (!true_block_needs_code && !false_block_needs_code)
12740+
return;
12741+
12742+
emit_block_hints(get<SPIRBlock>(from));
1274212743

12743-
if (true_sub)
12744+
if (true_block_needs_code)
1274412745
{
12745-
emit_block_hints(get<SPIRBlock>(from));
1274612746
statement("if (", to_expression(cond), ")");
1274712747
begin_scope();
1274812748
branch(from, true_block);
1274912749
end_scope();
1275012750

12751-
// If we merge to continue, we handle that explicitly in emit_block_chain(),
12752-
// so there is no need to branch to it directly here.
12753-
// break; is required to handle ladder fallthrough cases, so keep that in for now, even
12754-
// if we could potentially handle it in emit_block_chain().
12755-
if (false_sub || (!false_block_is_selection_merge && is_continue(false_block)) || is_break(false_block))
12751+
if (false_block_needs_code)
1275612752
{
1275712753
statement("else");
1275812754
begin_scope();
1275912755
branch(from, false_block);
1276012756
end_scope();
1276112757
}
12762-
else if (flush_phi_required(from, false_block))
12763-
{
12764-
statement("else");
12765-
begin_scope();
12766-
flush_phi(from, false_block);
12767-
end_scope();
12768-
}
1276912758
}
12770-
else if (false_sub)
12759+
else if (false_block_needs_code)
1277112760
{
1277212761
// Only need false path, use negative conditional.
12773-
emit_block_hints(get<SPIRBlock>(from));
1277412762
statement("if (!", to_enclosed_expression(cond), ")");
1277512763
begin_scope();
1277612764
branch(from, false_block);
1277712765
end_scope();
12778-
12779-
if ((!true_block_is_selection_merge && is_continue(true_block)) || is_break(true_block))
12780-
{
12781-
statement("else");
12782-
begin_scope();
12783-
branch(from, true_block);
12784-
end_scope();
12785-
}
12786-
else if (flush_phi_required(from, true_block))
12787-
{
12788-
statement("else");
12789-
begin_scope();
12790-
flush_phi(from, true_block);
12791-
end_scope();
12792-
}
1279312766
}
1279412767
}
1279512768

0 commit comments

Comments
 (0)