Handle OpPhi with no in operands in value numbering (#3056)
Fixes #3043
diff --git a/source/opt/value_number_table.cpp b/source/opt/value_number_table.cpp
index 8df34ef..82549a6 100644
--- a/source/opt/value_number_table.cpp
+++ b/source/opt/value_number_table.cpp
@@ -93,7 +93,7 @@
// Phi nodes are a type of copy. If all of the inputs have the same value
// number, then we can assign the result of the phi the same value number.
- if (inst->opcode() == SpvOpPhi &&
+ if (inst->opcode() == SpvOpPhi && inst->NumInOperands() > 0 &&
dec_mgr->HaveTheSameDecorations(inst->result_id(),
inst->GetSingleWordInOperand(0))) {
value = GetValueNumber(inst->GetSingleWordInOperand(0));
diff --git a/test/opt/value_table_test.cpp b/test/opt/value_table_test.cpp
index 0b7530c..a0942cc 100644
--- a/test/opt/value_table_test.cpp
+++ b/test/opt/value_table_test.cpp
@@ -653,6 +653,37 @@
EXPECT_NE(vtable.GetValueNumber(phi1), vtable.GetValueNumber(phi2));
}
+// Test to make sure that OpPhi instructions with no in operands are handled
+// correctly.
+TEST_F(ValueTableTest, EmptyPhiTest) {
+ const std::string text = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main"
+ OpExecutionMode %2 OriginUpperLeft
+ OpSource GLSL 430
+ %void = OpTypeVoid
+ %4 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %2 = OpFunction %void None %4
+ %7 = OpLabel
+ OpSelectionMerge %8 None
+ OpBranchConditional %true %9 %8
+ %9 = OpLabel
+ OpKill
+ %8 = OpLabel
+ %10 = OpPhi %bool
+ OpReturn
+ OpFunctionEnd
+ )";
+ auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ValueNumberTable vtable(context.get());
+ Instruction* inst = context->get_def_use_mgr()->GetDef(10);
+ vtable.GetValueNumber(inst);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools