Allow OpPoisonKHR as a constituent (#6713)

Spec change:
https://github.com/KhronosGroup/SPIRV-Registry/pull/417
diff --git a/source/opcode.cpp b/source/opcode.cpp
index 43fcd5e..83556e5 100644
--- a/source/opcode.cpp
+++ b/source/opcode.cpp
@@ -164,7 +164,8 @@
 }
 
 bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
-  return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode);
+  return opcode == spv::Op::OpUndef || opcode == spv::Op::OpPoisonKHR ||
+         spvOpcodeIsConstant(opcode);
 }
 
 int32_t spvOpcodeIsComposite(const spv::Op opcode) {
diff --git a/source/val/validate_constants.cpp b/source/val/validate_constants.cpp
index 54941e2..26695eb 100644
--- a/source/val/validate_constants.cpp
+++ b/source/val/validate_constants.cpp
@@ -50,9 +50,10 @@
   const bool is_constant = spvOpcodeIsConstantOrUndef(operand_opcode);
   const bool is_spec_constant = spvOpcodeIsSpecConstant(operand_opcode);
   if (!is_constant) {
-    // All operands must be constant or undef.
+    // All operands must be constant, undef, or poison.
     return _.diag(SPV_ERROR_INVALID_ID, inst)
-           << opcode_name << " must only have constant or undef operands: <id> "
+           << opcode_name
+           << " must only have constant, undef, or poison operands: <id> "
            << _.getIdName(operand_id);
   } else if (!inst_is_spec_constant && is_spec_constant) {
     // Spec constants are only allowed for spec constant opcodes.
diff --git a/test/val/val_constants_test.cpp b/test/val/val_constants_test.cpp
index d447b5c..c6e378f 100644
--- a/test/val/val_constants_test.cpp
+++ b/test/val/val_constants_test.cpp
@@ -655,7 +655,7 @@
   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("OpConstantCompositeReplicateEXT must only have "
-                        "constant or undef operands: <id>"));
+                        "constant, undef, or poison operands: <id>"));
 }
 
 TEST_F(ValidateConstant, ConstantCompositeSpecOperand) {
@@ -697,9 +697,44 @@
 )";
   CompileSuccessfully(spirv);
   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
-  EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("OpConstantComposite must only have constant or undef "
-                        "operands: <id>"));
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr("OpConstantComposite must only have constant, undef, or "
+                "poison operands: <id>"));
+}
+
+TEST_F(ValidateConstant, ConstantCompositePoisonConstituentGood) {
+  std::string spirv =
+      std::string(
+          "OpCapability Shader\nOpCapability Linkage\nOpCapability "
+          "PoisonFreezeKHR\nOpExtension \"SPV_KHR_poison_freeze\"\n"
+          "OpMemoryModel Logical Simple\n") +
+      R"(
+%int = OpTypeInt 32 1
+%int_4 = OpConstant %int 4
+%arr = OpTypeArray %int %int_4
+%poison = OpPoisonKHR %int
+%const_arr = OpConstantComposite %arr %poison %poison %poison %poison
+)";
+  CompileSuccessfully(spirv);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateConstant, SpecConstantCompositePoisonConstituentGood) {
+  std::string spirv =
+      std::string(
+          "OpCapability Shader\nOpCapability Linkage\nOpCapability "
+          "PoisonFreezeKHR\nOpExtension \"SPV_KHR_poison_freeze\"\n"
+          "OpMemoryModel Logical Simple\n") +
+      R"(
+%int = OpTypeInt 32 1
+%int_4 = OpConstant %int 4
+%arr = OpTypeArray %int %int_4
+%poison = OpPoisonKHR %int
+%const_arr = OpSpecConstantComposite %arr %poison %poison %poison %poison
+)";
+  CompileSuccessfully(spirv);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
 }
 
 TEST_F(ValidateConstant, ConstantCompositeReplicateNotComposite) {