spirv-opt: skips if_conversion when dontflatten is set (#4770)
diff --git a/source/opt/if_conversion.cpp b/source/opt/if_conversion.cpp
index 4920661..d1debd0 100644
--- a/source/opt/if_conversion.cpp
+++ b/source/opt/if_conversion.cpp
@@ -169,6 +169,8 @@
if (branch->opcode() != SpvOpBranchConditional) return false;
auto merge = (*common)->GetMergeInst();
if (!merge || merge->opcode() != SpvOpSelectionMerge) return false;
+ if (merge->GetSingleWordInOperand(1) == SpvSelectionControlDontFlattenMask)
+ return false;
if ((*common)->MergeBlockIdIfAny() != block->id()) return false;
return true;
diff --git a/test/opt/if_conversion_test.cpp b/test/opt/if_conversion_test.cpp
index dee15c3..81e9bb2 100644
--- a/test/opt/if_conversion_test.cpp
+++ b/test/opt/if_conversion_test.cpp
@@ -328,6 +328,40 @@
SinglePassRunAndCheck<IfConversion>(text, text, true, true);
}
+TEST_F(IfConversionTest, DontFlatten) {
+ const std::string text = R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %1 "func" %2
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%uint = OpTypeInt 32 0
+%uint_0 = OpConstant %uint 0
+%uint_1 = OpConstant %uint 1
+%v2uint = OpTypeVector %uint 2
+%10 = OpConstantComposite %v2uint %uint_0 %uint_1
+%11 = OpConstantComposite %v2uint %uint_1 %uint_0
+%_ptr_Output_v2uint = OpTypePointer Output %v2uint
+%2 = OpVariable %_ptr_Output_v2uint Output
+%13 = OpTypeFunction %void
+%1 = OpFunction %void None %13
+%14 = OpLabel
+OpSelectionMerge %15 DontFlatten
+OpBranchConditional %true %16 %17
+%16 = OpLabel
+OpBranch %15
+%17 = OpLabel
+OpBranch %15
+%15 = OpLabel
+%18 = OpPhi %v2uint %10 %16 %11 %17
+OpStore %2 %18
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<IfConversion>(text, text, true, true);
+}
+
TEST_F(IfConversionTest, LoopUntouched) {
const std::string text = R"(OpCapability Shader
OpMemoryModel Logical GLSL450