diff --git a/src/back/spv/block.rs b/src/back/spv/block.rs index 3c32ca85c7..728af63c26 100644 --- a/src/back/spv/block.rs +++ b/src/back/spv/block.rs @@ -1680,26 +1680,36 @@ impl<'w> BlockContext<'w> { spirv::SelectionControl::NONE, )); - let default_id = self.gen_id(); + let mut default_id = None; + // id of previous empty fall-through case + let mut last_id = None; let mut raw_cases = Vec::with_capacity(cases.len()); let mut case_ids = Vec::with_capacity(cases.len()); for case in cases.iter() { + let label_id = last_id.take().unwrap_or_else(|| self.gen_id()); + + if case.fall_through && case.body.is_empty() { + last_id = Some(label_id); + } + + case_ids.push(label_id); + match case.value { crate::SwitchValue::Integer(value) => { - let label_id = self.gen_id(); raw_cases.push(super::instructions::Case { value: value as Word, label_id, }); - case_ids.push(label_id); } crate::SwitchValue::Default => { - case_ids.push(default_id); + default_id = Some(label_id); } } } + let default_id = default_id.unwrap(); + self.function.consume( block, Instruction::switch(selector_id, default_id, &raw_cases), @@ -1710,7 +1720,12 @@ impl<'w> BlockContext<'w> { ..loop_context }; - for (i, (case, label_id)) in cases.iter().zip(case_ids.iter()).enumerate() { + for (i, (case, label_id)) in cases + .iter() + .zip(case_ids.iter()) + .filter(|&(case, _)| !(case.fall_through && case.body.is_empty())) + .enumerate() + { let case_finish_id = if case.fall_through { case_ids[i + 1] } else { diff --git a/tests/out/spv/control-flow.spvasm b/tests/out/spv/control-flow.spvasm index cc986fe775..e1885e7159 100644 --- a/tests/out/spv/control-flow.spvasm +++ b/tests/out/spv/control-flow.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 71 +; Bound: 69 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 @@ -45,11 +45,11 @@ OpFunctionEnd OpBranch %22 %22 = OpLabel OpSelectionMerge %23 None -OpSwitch %5 %24 0 %25 -%25 = OpLabel -OpBranch %23 +OpSwitch %5 %25 0 %24 %24 = OpLabel OpBranch %23 +%25 = OpLabel +OpBranch %23 %23 = OpLabel OpReturn OpFunctionEnd @@ -64,10 +64,10 @@ OpLoopMerge %31 %33 None OpBranch %32 %32 = OpLabel OpSelectionMerge %34 None -OpSwitch %27 %35 1 %36 -%36 = OpLabel -OpBranch %33 +OpSwitch %27 %36 1 %35 %35 = OpLabel +OpBranch %33 +%36 = OpLabel OpBranch %34 %34 = OpLabel OpBranch %33 @@ -92,51 +92,47 @@ OpBranch %50 %50 = OpLabel %52 = OpLoad %4 %37 OpSelectionMerge %53 None -OpSwitch %52 %54 1 %55 2 %56 3 %57 4 %58 5 %59 6 %60 -%55 = OpLabel +OpSwitch %52 %58 1 %54 2 %55 3 %56 4 %56 5 %57 6 %58 +%54 = OpLabel OpStore %37 %5 OpBranch %53 -%56 = OpLabel +%55 = OpLabel OpStore %37 %3 OpBranch %53 -%57 = OpLabel -OpBranch %58 -%58 = OpLabel +%56 = OpLabel OpStore %37 %6 OpBranch %53 -%59 = OpLabel +%57 = OpLabel OpStore %37 %7 OpBranch %53 -%54 = OpLabel -OpBranch %60 -%60 = OpLabel +%58 = OpLabel OpStore %37 %8 OpBranch %53 %53 = OpLabel -OpSelectionMerge %61 None -OpSwitch %9 %62 0 %63 -%63 = OpLabel -OpBranch %61 -%62 = OpLabel -OpBranch %61 +OpSelectionMerge %59 None +OpSwitch %9 %61 0 %60 +%60 = OpLabel +OpBranch %59 %61 = OpLabel -%64 = OpLoad %4 %37 -OpSelectionMerge %65 None -OpSwitch %64 %66 1 %67 2 %68 3 %69 4 %70 -%67 = OpLabel +OpBranch %59 +%59 = OpLabel +%62 = OpLoad %4 %37 +OpSelectionMerge %63 None +OpSwitch %62 %68 1 %64 2 %65 3 %66 4 %67 +%64 = OpLabel OpStore %37 %5 -OpBranch %65 -%68 = OpLabel +OpBranch %63 +%65 = OpLabel OpStore %37 %3 OpReturn -%69 = OpLabel +%66 = OpLabel OpStore %37 %6 OpReturn -%70 = OpLabel +%67 = OpLabel OpReturn -%66 = OpLabel +%68 = OpLabel OpStore %37 %7 OpReturn -%65 = OpLabel +%63 = OpLabel OpReturn OpFunctionEnd \ No newline at end of file