@@ -2979,62 +2979,69 @@ impl BlockContext<'_> {
29792979 ref accept,
29802980 ref reject,
29812981 } => {
2982- let condition_id = self . cached [ condition] ;
2982+ // In spirv 1.6, in a conditional branch the two block ids
2983+ // of the branches can't have the same label. If `accept`
2984+ // and `reject` are both empty (e.g. in `if (condition) {}`)
2985+ // merge id will be both labels. Because both branches are
2986+ // empty, we can skip the if statement.
2987+ if !( accept. is_empty ( ) && reject. is_empty ( ) ) {
2988+ let condition_id = self . cached [ condition] ;
2989+
2990+ let merge_id = self . gen_id ( ) ;
2991+ block. body . push ( Instruction :: selection_merge (
2992+ merge_id,
2993+ spirv:: SelectionControl :: NONE ,
2994+ ) ) ;
29832995
2984- let merge_id = self . gen_id ( ) ;
2985- block. body . push ( Instruction :: selection_merge (
2986- merge_id,
2987- spirv:: SelectionControl :: NONE ,
2988- ) ) ;
2996+ let accept_id = if accept. is_empty ( ) {
2997+ None
2998+ } else {
2999+ Some ( self . gen_id ( ) )
3000+ } ;
3001+ let reject_id = if reject. is_empty ( ) {
3002+ None
3003+ } else {
3004+ Some ( self . gen_id ( ) )
3005+ } ;
29893006
2990- let accept_id = if accept. is_empty ( ) {
2991- None
2992- } else {
2993- Some ( self . gen_id ( ) )
2994- } ;
2995- let reject_id = if reject. is_empty ( ) {
2996- None
2997- } else {
2998- Some ( self . gen_id ( ) )
2999- } ;
3007+ self . function . consume (
3008+ block,
3009+ Instruction :: branch_conditional (
3010+ condition_id,
3011+ accept_id. unwrap_or ( merge_id) ,
3012+ reject_id. unwrap_or ( merge_id) ,
3013+ ) ,
3014+ ) ;
30003015
3001- self . function . consume (
3002- block,
3003- Instruction :: branch_conditional (
3004- condition_id,
3005- accept_id. unwrap_or ( merge_id) ,
3006- reject_id. unwrap_or ( merge_id) ,
3007- ) ,
3008- ) ;
3016+ if let Some ( block_id) = accept_id {
3017+ // We can ignore the `BlockExitDisposition` returned here because,
3018+ // even if `merge_id` is not actually reachable, it is always
3019+ // referred to by the `OpSelectionMerge` instruction we emitted
3020+ // earlier.
3021+ let _ = self . write_block (
3022+ block_id,
3023+ accept,
3024+ BlockExit :: Branch { target : merge_id } ,
3025+ loop_context,
3026+ debug_info,
3027+ ) ?;
3028+ }
3029+ if let Some ( block_id) = reject_id {
3030+ // We can ignore the `BlockExitDisposition` returned here because,
3031+ // even if `merge_id` is not actually reachable, it is always
3032+ // referred to by the `OpSelectionMerge` instruction we emitted
3033+ // earlier.
3034+ let _ = self . write_block (
3035+ block_id,
3036+ reject,
3037+ BlockExit :: Branch { target : merge_id } ,
3038+ loop_context,
3039+ debug_info,
3040+ ) ?;
3041+ }
30093042
3010- if let Some ( block_id) = accept_id {
3011- // We can ignore the `BlockExitDisposition` returned here because,
3012- // even if `merge_id` is not actually reachable, it is always
3013- // referred to by the `OpSelectionMerge` instruction we emitted
3014- // earlier.
3015- let _ = self . write_block (
3016- block_id,
3017- accept,
3018- BlockExit :: Branch { target : merge_id } ,
3019- loop_context,
3020- debug_info,
3021- ) ?;
3022- }
3023- if let Some ( block_id) = reject_id {
3024- // We can ignore the `BlockExitDisposition` returned here because,
3025- // even if `merge_id` is not actually reachable, it is always
3026- // referred to by the `OpSelectionMerge` instruction we emitted
3027- // earlier.
3028- let _ = self . write_block (
3029- block_id,
3030- reject,
3031- BlockExit :: Branch { target : merge_id } ,
3032- loop_context,
3033- debug_info,
3034- ) ?;
3043+ block = Block :: new ( merge_id) ;
30353044 }
3036-
3037- block = Block :: new ( merge_id) ;
30383045 }
30393046 Statement :: Switch {
30403047 selector,
0 commit comments