Skip to content

Commit 301eab1

Browse files
Merge pull request #1099 from KhronosGroup/fix-1091
Missed case where DoWhile continue block deals with Phi.
2 parents 798282d + e06efb7 commit 301eab1

11 files changed

Lines changed: 146 additions & 42 deletions

reference/opt/shaders/asm/comp/phi-temporary-copy-loop-variable.asm.comp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ void main()
1414
{
1515
break;
1616
}
17-
else
18-
{
19-
continue;
20-
}
2117
continue;
2218
}
2319
imageStore(outImageTexture, ivec2(gl_GlobalInvocationID.xy), vec4(float(_30 - 1), float(_30), 1.0, 1.0));

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,7 @@ void main()
4646
_231 = true;
4747
break;
4848
}
49-
else
50-
{
51-
uint _204 = _227 + uint(1);
52-
_227 = _204;
53-
continue;
54-
}
55-
uint _204 = _227 + uint(1);
56-
_227 = _204;
49+
_227++;
5750
continue;
5851
}
5952
else

reference/shaders-msl-no-opt/asm/frag/inliner-dominator-inside-loop.asm.frag

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant CB0& _19 [[buffer(0)
137137
float2 _166 = in.IN_Uv_EdgeDistance1.xy * 1.0;
138138
bool _173;
139139
float4 _193;
140-
do
140+
for (;;)
141141
{
142142
_173 = 0.0 == 0.0;
143143
if (_173)
@@ -153,9 +153,9 @@ fragment main0_out main0(main0_in in [[stage_in]], constant CB0& _19 [[buffer(0)
153153
}
154154
_193 = _192;
155155
break;
156-
} while (false);
156+
}
157157
float4 _220;
158-
do
158+
for (;;)
159159
{
160160
if (_173)
161161
{
@@ -170,7 +170,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant CB0& _19 [[buffer(0)
170170
}
171171
_220 = _219;
172172
break;
173-
} while (false);
173+
}
174174
float2 _223 = float2(1.0);
175175
float2 _224 = (_220.wy * 2.0) - _223;
176176
float3 _232 = float3(_224, sqrt(fast::clamp(1.0 + dot(-_224, _224), 0.0, 1.0)));
@@ -181,7 +181,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant CB0& _19 [[buffer(0)
181181
float3 _256 = float3(_255.x, _255.y, _253.z);
182182
float3 _271 = ((in.IN_Color.xyz * (_193 * 1.0).xyz) * (1.0 + (_256.x * 0.300000011920928955078125))) * (StudsMapTexture.sample(StudsMapSampler, _156.UvStuds).x * 2.0);
183183
float4 _298;
184-
do
184+
for (;;)
185185
{
186186
if (0.75 == 0.0)
187187
{
@@ -196,7 +196,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant CB0& _19 [[buffer(0)
196196
}
197197
_298 = _297;
198198
break;
199-
} while (false);
199+
}
200200
float2 _303 = mix(float2(0.800000011920928955078125, 120.0), (_298.xy * float2(2.0, 256.0)) + float2(0.0, 0.00999999977648258209228515625), float2(_165));
201201
Surface _304 = _125;
202202
_304.albedo = _271;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#version 310 es
2+
precision mediump float;
3+
precision highp int;
4+
5+
layout(location = 0) out highp vec4 _GLF_color;
6+
7+
void main()
8+
{
9+
for (;;)
10+
{
11+
bool _32;
12+
for (;;)
13+
{
14+
if (gl_FragCoord.x != gl_FragCoord.x)
15+
{
16+
_32 = true;
17+
break;
18+
}
19+
if (false)
20+
{
21+
continue;
22+
}
23+
else
24+
{
25+
_32 = false;
26+
break;
27+
}
28+
}
29+
if (_32)
30+
{
31+
break;
32+
}
33+
_GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
34+
break;
35+
}
36+
}
37+

reference/shaders-no-opt/asm/frag/inliner-dominator-inside-loop.asm.frag

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ void main()
130130
vec2 _166 = IN_Uv_EdgeDistance1.xy * 1.0;
131131
bool _173;
132132
vec4 _193;
133-
do
133+
for (;;)
134134
{
135135
_173 = 0.0 == 0.0;
136136
if (_173)
@@ -146,9 +146,9 @@ void main()
146146
}
147147
_193 = _192;
148148
break;
149-
} while (false);
149+
}
150150
vec4 _220;
151-
do
151+
for (;;)
152152
{
153153
if (_173)
154154
{
@@ -163,7 +163,7 @@ void main()
163163
}
164164
_220 = _219;
165165
break;
166-
} while (false);
166+
}
167167
vec2 _223 = vec2(1.0);
168168
vec2 _224 = (_220.wy * 2.0) - _223;
169169
vec3 _232 = vec3(_224, sqrt(clamp(1.0 + dot(-_224, _224), 0.0, 1.0)));
@@ -174,7 +174,7 @@ void main()
174174
vec3 _256 = vec3(_255.x, _255.y, _253.z);
175175
vec3 _271 = ((IN_Color.xyz * (_193 * 1.0).xyz) * (1.0 + (_256.x * 0.300000011920928955078125))) * (texture(SPIRV_Cross_CombinedStudsMapTextureStudsMapSampler, _156.UvStuds).x * 2.0);
176176
vec4 _298;
177-
do
177+
for (;;)
178178
{
179179
if (0.75 == 0.0)
180180
{
@@ -189,7 +189,7 @@ void main()
189189
}
190190
_298 = _297;
191191
break;
192-
} while (false);
192+
}
193193
vec2 _303 = mix(vec2(0.800000011920928955078125, 120.0), (_298.xy * vec2(2.0, 256.0)) + vec2(0.0, 0.00999999977648258209228515625), vec2(_165));
194194
Surface _304 = _125;
195195
_304.albedo = _271;

reference/shaders/asm/comp/phi-temporary-copy-loop-variable.asm.comp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ void main()
1414
{
1515
break;
1616
}
17-
else
18-
{
19-
continue;
20-
}
2117
continue;
2218
}
2319
imageStore(outImageTexture, ivec2(gl_GlobalInvocationID.xy), vec4(float(_30 - 1), float(_30), 1.0, 1.0));
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos Glslang Reference Front End; 7
4+
; Bound: 42
5+
; Schema: 0
6+
OpCapability Shader
7+
%1 = OpExtInstImport "GLSL.std.450"
8+
OpMemoryModel Logical GLSL450
9+
OpEntryPoint Fragment %main "main" %gl_FragCoord %_GLF_color
10+
OpExecutionMode %main OriginUpperLeft
11+
OpSource ESSL 310
12+
OpName %main "main"
13+
OpName %gl_FragCoord "gl_FragCoord"
14+
OpName %_GLF_color "_GLF_color"
15+
OpDecorate %gl_FragCoord BuiltIn FragCoord
16+
OpDecorate %_GLF_color Location 0
17+
%void = OpTypeVoid
18+
%3 = OpTypeFunction %void
19+
%float = OpTypeFloat 32
20+
%v4float = OpTypeVector %float 4
21+
%_ptr_Input_v4float = OpTypePointer Input %v4float
22+
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
23+
%uint = OpTypeInt 32 0
24+
%uint_0 = OpConstant %uint 0
25+
%_ptr_Input_float = OpTypePointer Input %float
26+
%bool = OpTypeBool
27+
%false = OpConstantFalse %bool
28+
%_ptr_Output_v4float = OpTypePointer Output %v4float
29+
%_GLF_color = OpVariable %_ptr_Output_v4float Output
30+
%float_1 = OpConstant %float 1
31+
%float_0 = OpConstant %float 0
32+
%31 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
33+
%true = OpConstantTrue %bool
34+
%main = OpFunction %void None %3
35+
%5 = OpLabel
36+
OpBranch %33
37+
%33 = OpLabel
38+
OpLoopMerge %32 %35 None
39+
OpBranch %6
40+
%6 = OpLabel
41+
OpLoopMerge %8 %24 None
42+
OpBranch %7
43+
%7 = OpLabel
44+
%17 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
45+
%18 = OpLoad %float %17
46+
%22 = OpFOrdNotEqual %bool %18 %18
47+
OpSelectionMerge %24 None
48+
OpBranchConditional %22 %23 %24
49+
%23 = OpLabel
50+
OpBranch %8
51+
%24 = OpLabel
52+
OpBranchConditional %false %6 %8
53+
%8 = OpLabel
54+
%41 = OpPhi %bool %true %23 %false %24
55+
OpSelectionMerge %39 None
56+
OpBranchConditional %41 %32 %39
57+
%39 = OpLabel
58+
OpStore %_GLF_color %31
59+
OpBranch %32
60+
%35 = OpLabel
61+
OpBranch %33
62+
%32 = OpLabel
63+
OpReturn
64+
OpFunctionEnd

spirv_cross.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,12 @@ SPIRBlock::ContinueBlockType Compiler::continue_block_type(const SPIRBlock &bloc
15011501
const auto *true_block = maybe_get<SPIRBlock>(block.true_block);
15021502
const auto *merge_block = maybe_get<SPIRBlock>(dominator.merge_block);
15031503

1504+
// If we need to flush Phi in this block, we cannot have a DoWhile loop.
1505+
bool flush_phi_to_false = false_block && flush_phi_required(block.self, block.false_block);
1506+
bool flush_phi_to_true = true_block && flush_phi_required(block.self, block.true_block);
1507+
if (flush_phi_to_false || flush_phi_to_true)
1508+
return SPIRBlock::ComplexLoop;
1509+
15041510
bool positive_do_while = block.true_block == dominator.self &&
15051511
(block.false_block == dominator.merge_block ||
15061512
(false_block && merge_block && execution_is_noop(*false_block, *merge_block)));
@@ -4246,3 +4252,12 @@ bool Compiler::type_is_array_of_pointers(const SPIRType &type) const
42464252
// If parent type has same pointer depth, we must have an array of pointers.
42474253
return type.pointer_depth == get<SPIRType>(type.parent_type).pointer_depth;
42484254
}
4255+
4256+
bool Compiler::flush_phi_required(uint32_t from, uint32_t to) const
4257+
{
4258+
auto &child = get<SPIRBlock>(to);
4259+
for (auto &phi : child.phi_variables)
4260+
if (phi.parent == from)
4261+
return true;
4262+
return false;
4263+
}

spirv_cross.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ class Compiler
972972
bool reflection_ssbo_instance_name_is_significant() const;
973973
std::string get_remapped_declared_block_name(uint32_t id, bool fallback_prefer_instance_name) const;
974974

975+
bool flush_phi_required(uint32_t from, uint32_t to) const;
976+
975977
private:
976978
// Used only to implement the old deprecated get_entry_point() interface.
977979
const SPIREntryPoint &get_first_entry_point(const std::string &name) const;

spirv_glsl.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11068,15 +11068,6 @@ void CompilerGLSL::emit_fixup()
1106811068
}
1106911069
}
1107011070

11071-
bool CompilerGLSL::flush_phi_required(uint32_t from, uint32_t to)
11072-
{
11073-
auto &child = get<SPIRBlock>(to);
11074-
for (auto &phi : child.phi_variables)
11075-
if (phi.parent == from)
11076-
return true;
11077-
return false;
11078-
}
11079-
1108011071
void CompilerGLSL::flush_phi(uint32_t from, uint32_t to)
1108111072
{
1108211073
auto &child = get<SPIRBlock>(to);
@@ -11246,10 +11237,17 @@ void CompilerGLSL::branch(uint32_t from, uint32_t to)
1124611237

1124711238
void CompilerGLSL::branch(uint32_t from, uint32_t cond, uint32_t true_block, uint32_t false_block)
1124811239
{
11249-
// If we branch directly to a selection merge target, we don't really need a code path.
11240+
auto &from_block = get<SPIRBlock>(from);
11241+
uint32_t merge_block = from_block.merge == SPIRBlock::MergeSelection ? from_block.next_block : 0;
11242+
11243+
// If we branch directly to a selection merge target, we don't need a code path.
11244+
// This covers both merge out of if () / else () as well as a break for switch blocks.
1125011245
bool true_sub = !is_conditional(true_block);
1125111246
bool false_sub = !is_conditional(false_block);
1125211247

11248+
bool true_block_is_selection_merge = true_block == merge_block;
11249+
bool false_block_is_selection_merge = false_block == merge_block;
11250+
1125311251
if (true_sub)
1125411252
{
1125511253
emit_block_hints(get<SPIRBlock>(from));
@@ -11258,7 +11256,11 @@ void CompilerGLSL::branch(uint32_t from, uint32_t cond, uint32_t true_block, uin
1125811256
branch(from, true_block);
1125911257
end_scope();
1126011258

11261-
if (false_sub || is_continue(false_block) || is_break(false_block))
11259+
// If we merge to continue, we handle that explicitly in emit_block_chain(),
11260+
// so there is no need to branch to it directly here.
11261+
// break; is required to handle ladder fallthrough cases, so keep that in for now, even
11262+
// if we could potentially handle it in emit_block_chain().
11263+
if (false_sub || (!false_block_is_selection_merge && is_continue(false_block)) || is_break(false_block))
1126211264
{
1126311265
statement("else");
1126411266
begin_scope();
@@ -11273,7 +11275,7 @@ void CompilerGLSL::branch(uint32_t from, uint32_t cond, uint32_t true_block, uin
1127311275
end_scope();
1127411276
}
1127511277
}
11276-
else if (false_sub && !true_sub)
11278+
else if (false_sub)
1127711279
{
1127811280
// Only need false path, use negative conditional.
1127911281
emit_block_hints(get<SPIRBlock>(from));
@@ -11282,7 +11284,7 @@ void CompilerGLSL::branch(uint32_t from, uint32_t cond, uint32_t true_block, uin
1128211284
branch(from, false_block);
1128311285
end_scope();
1128411286

11285-
if (is_continue(true_block) || is_break(true_block))
11287+
if ((!true_block_is_selection_merge && is_continue(true_block)) || is_break(true_block))
1128611288
{
1128711289
statement("else");
1128811290
begin_scope();

0 commit comments

Comments
 (0)