Skip to content

Commit 54cc0b0

Browse files
Deal with case where a selection construct conditionally merges/breaks.
1 parent 16d9fea commit 54cc0b0

4 files changed

Lines changed: 228 additions & 0 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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12740,6 +12740,29 @@ void CompilerGLSL::branch(BlockID from, uint32_t cond, BlockID true_block, Block
1274012740
bool true_block_is_selection_merge = true_block == merge_block;
1274112741
bool false_block_is_selection_merge = false_block == merge_block;
1274212742

12743+
// Can happen if one branch merges to selection branch merge target,
12744+
// and then the other branches to outer switch merge target.
12745+
if (!true_sub && !false_sub)
12746+
{
12747+
if (true_block_is_selection_merge && false_block_is_selection_merge)
12748+
{
12749+
// Useless case (should just be OpBranch), just flush PHI once if needed and execution will continue
12750+
// at the merge target.
12751+
if (flush_phi_required(from, merge_block))
12752+
flush_phi(from, merge_block);
12753+
return;
12754+
}
12755+
else if (true_block_is_selection_merge)
12756+
false_sub = true;
12757+
else if (false_block_is_selection_merge)
12758+
true_sub = true;
12759+
else
12760+
{
12761+
false_sub = true;
12762+
true_sub = true;
12763+
}
12764+
}
12765+
1274312766
if (true_sub)
1274412767
{
1274512768
emit_block_hints(get<SPIRBlock>(from));

0 commit comments

Comments
 (0)