Fix bug in construct block calculation (#1964)
Fixes #1960
* Only allows blocks that are dominated by the header
* Fixed a bad loop fusion test
* Added a test derived from the reported bug
diff --git a/source/val/construct.cpp b/source/val/construct.cpp
index c11a065..7b0cb2d 100644
--- a/source/val/construct.cpp
+++ b/source/val/construct.cpp
@@ -116,7 +116,10 @@
if (merge != block) {
for (auto succ : *block->successors()) {
- stack.push_back(succ);
+ // All blocks in the construct must be dominated by the header.
+ if (header->dominates(*succ)) {
+ stack.push_back(succ);
+ }
}
}
}
diff --git a/test/opt/loop_optimizations/fusion_legal.cpp b/test/opt/loop_optimizations/fusion_legal.cpp
index db7f61c..41d796f 100644
--- a/test/opt/loop_optimizations/fusion_legal.cpp
+++ b/test/opt/loop_optimizations/fusion_legal.cpp
@@ -3177,7 +3177,7 @@
%21 = OpLabel
%29 = OpSMod %6 %96 %28
%30 = OpIEqual %17 %29 %9
- OpSelectionMerge %32 None
+ OpSelectionMerge %23 None
OpBranchConditional %30 %31 %48
%31 = OpLabel
%44 = OpAccessChain %7 %41 %91 %96
@@ -3224,7 +3224,7 @@
%72 = OpSMod %6 %93 %28
%73 = OpIEqual %17 %72 %9
OpSelectionMerge %75 None
- OpBranchConditional %73 %74 %85
+ OpBranchConditional %73 %74 %66
%74 = OpLabel
%81 = OpAccessChain %7 %38 %92 %93
%82 = OpLoad %6 %81
@@ -3232,8 +3232,6 @@
%84 = OpAccessChain %7 %76 %92 %93
OpStore %84 %83
OpBranch %75
- %85 = OpLabel
- OpBranch %66
%75 = OpLabel
OpBranch %67
%67 = OpLabel
diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp
index bdfb366..d45fd10 100644
--- a/test/val/val_cfg_test.cpp
+++ b/test/val/val_cfg_test.cpp
@@ -1846,6 +1846,55 @@
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_F(ValidateCFG, GoodUnreachableSelection) {
+ const std::string text = R"(
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main"
+OpExecutionMode %main OriginUpperLeft
+%void = OpTypeVoid
+%8 = OpTypeFunction %void
+%bool = OpTypeBool
+%false = OpConstantFalse %bool
+%main = OpFunction %void None %8
+%15 = OpLabel
+OpBranch %16
+%16 = OpLabel
+OpLoopMerge %17 %18 None
+OpBranch %19
+%19 = OpLabel
+OpBranchConditional %false %21 %17
+%21 = OpLabel
+OpSelectionMerge %22 None
+OpBranchConditional %false %23 %22
+%23 = OpLabel
+OpBranch %24
+%24 = OpLabel
+OpLoopMerge %25 %26 None
+OpBranch %27
+%27 = OpLabel
+OpReturn
+%26 = OpLabel
+OpBranchConditional %false %24 %25
+%25 = OpLabel
+OpSelectionMerge %28 None
+OpBranchConditional %false %18 %28
+%28 = OpLabel
+OpBranch %22
+%22 = OpLabel
+OpBranch %18
+%18 = OpLabel
+OpBranch %16
+%17 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
/// TODO(umar): Nested CFG constructs
} // namespace