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) {