Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/opt/block_merge_util.cpp')
-rw-r--r--source/opt/block_merge_util.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/source/opt/block_merge_util.cpp b/source/opt/block_merge_util.cpp
index 8ae8020a5..83c702ca3 100644
--- a/source/opt/block_merge_util.cpp
+++ b/source/opt/block_merge_util.cpp
@@ -125,6 +125,26 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) {
return false;
}
}
+
+ if (succ_is_merge || IsContinue(context, lab_id)) {
+ auto* struct_cfg = context->GetStructuredCFGAnalysis();
+ auto switch_block_id = struct_cfg->ContainingSwitch(block->id());
+ if (switch_block_id) {
+ auto switch_merge_id = struct_cfg->SwitchMergeBlock(switch_block_id);
+ const auto* switch_inst =
+ &*block->GetParent()->FindBlock(switch_block_id)->tail();
+ for (uint32_t i = 1; i < switch_inst->NumInOperands(); i += 2) {
+ auto target_id = switch_inst->GetSingleWordInOperand(i);
+ if (target_id == block->id() && target_id != switch_merge_id) {
+ // Case constructs must be structurally dominated by the OpSwitch.
+ // Since the successor is the merge/continue for another construct,
+ // merging the blocks would break that requirement.
+ return false;
+ }
+ }
+ }
+ }
+
return true;
}