@@ -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-
1108011071void 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
1124711238void 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