aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEhsan Nasiri <ehsann@google.com>2016-11-10 15:12:26 -0500
committerDavid Neto <dneto@google.com>2016-11-15 13:38:39 -0500
commitd0620061c7cd585bca89493e0a45fbc15d4cc561 (patch)
tree91b356a6cc3f5f0ec1711f33e57372e78279a8c8
parent38036a7203ca604c0f25b0dc33da169ac58e2900 (diff)
downloadspirv-tools-d0620061c7cd585bca89493e0a45fbc15d4cc561.tar.gz
Adding validation code for more data rules.
These rules are under "Data Rules" in 2.16.1 (Universal Validation Rules) part of the SPIR-V 1.1 Specification document: * Scalar floating-point types can be parameterized only as 32 bit, plus any additional sizes enabled by capabilities. * Scalar integer types can be parameterized only as 32 bit, plus any additional sizes enabled by capabilities. * Vector types can only be parameterized with numerical types or the OpTypeBool type. * Matrix types can only be parameterized with floating-point types. * Matrix types can only be parameterized as having only 2, 3, or 4 columns. * Specialization constants (see Specialization) are limited to integers, Booleans, floating-point numbers, and vectors of these.
-rw-r--r--source/validate_datarules.cpp199
-rw-r--r--test/val/val_capability_test.cpp8
-rw-r--r--test/val/val_data_test.cpp275
-rw-r--r--test/val/val_id_test.cpp11
-rw-r--r--test/val/val_layout_test.cpp9
-rw-r--r--test/val/val_ssa_test.cpp24
6 files changed, 481 insertions, 45 deletions
diff --git a/source/validate_datarules.cpp b/source/validate_datarules.cpp
index c6626b83..d1062378 100644
--- a/source/validate_datarules.cpp
+++ b/source/validate_datarules.cpp
@@ -23,6 +23,7 @@
#include "diagnostic.h"
#include "opcode.h"
#include "operand.h"
+#include "val/instruction.h"
#include "val/validation_state.h"
using libspirv::CapabilitySet;
@@ -31,32 +32,161 @@ using libspirv::ValidationState_t;
namespace {
-// Validates that the number of components in the vector type is legal.
+// Validates that the number of components in the vector is valid.
// Vector types can only be parameterized as having 2, 3, or 4 components.
// If the Vector16 capability is added, 8 and 16 components are also allowed.
-spv_result_t ValidateNumVecComponents(ValidationState_t& _,
+spv_result_t ValidateVecNumComponents(ValidationState_t& _,
const spv_parsed_instruction_t* inst) {
- if (inst->opcode == SpvOpTypeVector) {
- // operand 2 specifies the number of components in the vector.
- const uint32_t num_components = inst->words[inst->operands[2].offset];
- if (num_components == 2 || num_components == 3 || num_components == 4) {
+ // Operand 2 specifies the number of components in the vector.
+ const uint32_t num_components = inst->words[inst->operands[2].offset];
+ if (num_components == 2 || num_components == 3 || num_components == 4) {
+ return SPV_SUCCESS;
+ }
+ if (num_components == 8 || num_components == 16) {
+ if (_.HasCapability(SpvCapabilityVector16)) {
+ return SPV_SUCCESS;
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Having " << num_components << " components for "
+ << spvOpcodeString(static_cast<SpvOp>(inst->opcode))
+ << " requires the Vector16 capability";
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Illegal number of components (" << num_components << ") for "
+ << spvOpcodeString(static_cast<SpvOp>(inst->opcode));
+}
+
+// Validates that the number of bits specifed for a float type is valid.
+// Scalar floating-point types can be parameterized only with 32-bits.
+// Float16 capability allows using a 16-bit OpTypeFloat.
+// Float16Buffer capability allows creation of a 16-bit OpTypeFloat.
+// Float64 capability allows using a 64-bit OpTypeFloat.
+spv_result_t ValidateFloatSize(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Operand 1 is the number of bits for this float
+ const uint32_t num_bits = inst->words[inst->operands[1].offset];
+ if (num_bits == 32) {
+ return SPV_SUCCESS;
+ }
+ if (num_bits == 16) {
+ if (_.HasCapability(SpvCapabilityFloat16) ||
+ _.HasCapability(SpvCapabilityFloat16Buffer)) {
+ return SPV_SUCCESS;
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Using a 16-bit floating point "
+ << "type requires the Float16 or Float16Buffer capability.";
+ }
+ if (num_bits == 64) {
+ if (_.HasCapability(SpvCapabilityFloat64)) {
+ return SPV_SUCCESS;
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Using a 64-bit floating point "
+ << "type requires the Float64 capability.";
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Invalid number of bits (" << num_bits << ") used for OpTypeFloat.";
+}
+
+// Validates that the number of bits specified for an Int type is valid.
+// Scalar integer types can be parameterized only with 32-bits.
+// Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit
+// integers, respectively.
+spv_result_t ValidateIntSize(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Operand 1 is the number of bits for this integer.
+ const uint32_t num_bits = inst->words[inst->operands[1].offset];
+ if (num_bits == 32) {
+ return SPV_SUCCESS;
+ }
+ if (num_bits == 8) {
+ if (_.HasCapability(SpvCapabilityInt8)) {
return SPV_SUCCESS;
}
- if (num_components == 8 || num_components == 16) {
- if (_.HasCapability(SpvCapabilityVector16)) {
- return SPV_SUCCESS;
- } else {
- return _.diag(SPV_ERROR_INVALID_DATA)
- << "Having " << num_components << " components for "
- << spvOpcodeString(static_cast<SpvOp>(inst->opcode))
- << " requires the Vector16 capability";
- }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Using an 8-bit integer type requires the Int8 capability.";
+ }
+ if (num_bits == 16) {
+ if (_.HasCapability(SpvCapabilityInt16)) {
+ return SPV_SUCCESS;
+ }
+ return _.diag(SPV_ERROR_INVALID_DATA)
+ << "Using a 16-bit integer type requires the Int16 capability.";
+ }
+ if (num_bits == 64) {
+ if (_.HasCapability(SpvCapabilityInt64)) {
+ return SPV_SUCCESS;
}
return _.diag(SPV_ERROR_INVALID_DATA)
- << "Illegal number of components (" << num_components << ") for "
- << spvOpcodeString(static_cast<SpvOp>(inst->opcode));
+ << "Using a 64-bit integer type requires the Int64 capability.";
}
+ return _.diag(SPV_ERROR_INVALID_DATA) << "Invalid number of bits ("
+ << num_bits << ") used for OpTypeInt.";
+}
+
+// Validates that the matrix is parameterized with floating-point types.
+spv_result_t ValidateMatrixColumnType(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Find the component type of matrix columns (must be vector).
+ // Operand 1 is the <id> of the type specified for matrix columns.
+ auto type_id = inst->words[inst->operands[1].offset];
+ auto col_type_instr = _.FindDef(type_id);
+ if (col_type_instr->opcode() != SpvOpTypeVector) {
+ return _.diag(SPV_ERROR_INVALID_ID)
+ << "Columns in a matrix must be of type vector.";
+ }
+
+ // Trace back once more to find out the type of components in the vector.
+ // Operand 1 is the <id> of the type of data in the vector.
+ auto comp_type_id =
+ col_type_instr->words()[col_type_instr->operands()[1].offset];
+ auto comp_type_instruction = _.FindDef(comp_type_id);
+ if (comp_type_instruction->opcode() != SpvOpTypeFloat) {
+ return _.diag(SPV_ERROR_INVALID_DATA) << "Matrix types can only be "
+ "parameterized with "
+ "floating-point types.";
+ }
+ return SPV_SUCCESS;
+}
+
+// Validates that the matrix has 2,3, or 4 columns.
+spv_result_t ValidateMatrixNumCols(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Operand 2 is the number of columns in the matrix.
+ const uint32_t num_cols = inst->words[inst->operands[2].offset];
+ if (num_cols != 2 && num_cols != 3 && num_cols != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA) << "Matrix types can only be "
+ "parameterized as having only 2, "
+ "3, or 4 columns.";
+ }
+ return SPV_SUCCESS;
+}
+
+// Validates that OpSpecConstant specializes to either int or float type.
+spv_result_t ValidateSpecConstNumerical(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Operand 0 is the <id> of the type that we're specializing to.
+ auto type_id = inst->words[inst->operands[0].offset];
+ auto type_instruction = _.FindDef(type_id);
+ auto type_opcode = type_instruction->opcode();
+ if (type_opcode != SpvOpTypeInt && type_opcode != SpvOpTypeFloat) {
+ return _.diag(SPV_ERROR_INVALID_DATA) << "Specialization constant must be "
+ "an integer or floating-point "
+ "number.";
+ }
+ return SPV_SUCCESS;
+}
+// Validates that OpSpecConstantTrue and OpSpecConstantFalse specialize to bool.
+spv_result_t ValidateSpecConstBoolean(ValidationState_t& _,
+ const spv_parsed_instruction_t* inst) {
+ // Find out the type that we're specializing to.
+ auto type_instruction = _.FindDef(inst->type_id);
+ if (type_instruction->opcode() != SpvOpTypeBool) {
+ return _.diag(SPV_ERROR_INVALID_ID) << "Specialization constant must be "
+ "a boolean type.";
+ }
return SPV_SUCCESS;
}
@@ -68,9 +198,38 @@ namespace libspirv {
// (Data Rules subsection of 2.16.1 Universal Validation Rules)
spv_result_t DataRulesPass(ValidationState_t& _,
const spv_parsed_instruction_t* inst) {
- if (auto error = ValidateNumVecComponents(_, inst)) return error;
-
- // TODO(ehsan): add more data rules validation here.
+ switch (inst->opcode) {
+ case SpvOpTypeVector: {
+ if (auto error = ValidateVecNumComponents(_, inst)) return error;
+ break;
+ }
+ case SpvOpTypeFloat: {
+ if (auto error = ValidateFloatSize(_, inst)) return error;
+ break;
+ }
+ case SpvOpTypeInt: {
+ if (auto error = ValidateIntSize(_, inst)) return error;
+ break;
+ }
+ case SpvOpTypeMatrix: {
+ if (auto error = ValidateMatrixColumnType(_, inst)) return error;
+ if (auto error = ValidateMatrixNumCols(_, inst)) return error;
+ break;
+ }
+ // TODO(ehsan): Add OpSpecConstantComposite validation code.
+ // TODO(ehsan): Add OpSpecConstantOp validation code (if any).
+ case SpvOpSpecConstant: {
+ if (auto error = ValidateSpecConstNumerical(_, inst)) return error;
+ break;
+ }
+ case SpvOpSpecConstantFalse:
+ case SpvOpSpecConstantTrue: {
+ if (auto error = ValidateSpecConstBoolean(_, inst)) return error;
+ break;
+ }
+ // TODO(ehsan): add more data rules validation here.
+ default: { break; }
+ }
return SPV_SUCCESS;
}
diff --git a/test/val/val_capability_test.cpp b/test/val/val_capability_test.cpp
index 9e13950d..f590ba86 100644
--- a/test/val/val_capability_test.cpp
+++ b/test/val/val_capability_test.cpp
@@ -114,8 +114,8 @@ TEST_F(ValidateCapability, Default) {
OpCapability Kernel
OpCapability Matrix
OpMemoryModel Logical OpenCL
-%intt = OpTypeInt 32 1
-%vec3 = OpTypeVector %intt 3
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
%mat33 = OpTypeMatrix %vec3 3
)";
@@ -1098,8 +1098,8 @@ INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateCapability,
ValuesIn(AllCapabilities()),
Values(
make_pair(string(kOpenCLMemoryModel) +
- "%intt = OpTypeInt 32 1\n"
- "%vec3 = OpTypeVector %intt 3\n"
+ "%f32 = OpTypeFloat 32\n"
+ "%vec3 = OpTypeVector %f32 3\n"
"%mat33 = OpTypeMatrix %vec3 3\n", MatrixDependencies()))),);
// clang-format on
diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp
index b3bfb943..1eafe6cc 100644
--- a/test/val/val_data_test.cpp
+++ b/test/val/val_data_test.cpp
@@ -42,9 +42,45 @@ string header_with_vec16_cap = R"(
OpMemoryModel Logical GLSL450
%1 = OpTypeFloat 32
)";
-
+string header_with_int8 = R"(
+ OpCapability Shader
+ OpCapability Int8
+ OpMemoryModel Logical GLSL450
+)";
+string header_with_int16 = R"(
+ OpCapability Shader
+ OpCapability Int16
+ OpMemoryModel Logical GLSL450
+)";
+string header_with_int64 = R"(
+ OpCapability Shader
+ OpCapability Int64
+ OpMemoryModel Logical GLSL450
+)";
+string header_with_float16 = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpMemoryModel Logical GLSL450
+)";
+string header_with_float16_buffer = R"(
+ OpCapability Shader
+ OpCapability Float16Buffer
+ OpMemoryModel Logical GLSL450
+)";
+string header_with_float64 = R"(
+ OpCapability Shader
+ OpCapability Float64
+ OpMemoryModel Logical GLSL450
+)";
string invalid_comp_error = "Illegal number of components";
string missing_cap_error = "requires the Vector16 capability";
+string missing_int8_cap_error = "requires the Int8 capability";
+string missing_int16_cap_error = "requires the Int16 capability";
+string missing_int64_cap_error = "requires the Int64 capability";
+string missing_float16_cap_error =
+ "requires the Float16 or Float16Buffer capability.";
+string missing_float64_cap_error = "requires the Float64 capability";
+string invalid_num_bits_error = "Invalid number of bits";
TEST_F(ValidateData, vec0) {
string str = header + "%2 = OpTypeVector %1 0";
@@ -117,3 +153,240 @@ TEST_F(ValidateData, vec15) {
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_comp_error));
}
+
+TEST_F(ValidateData, int8_good) {
+ string str = header_with_int8 + "%2 = OpTypeInt 8 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, int8_bad) {
+ string str = header + "%2 = OpTypeInt 8 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int8_cap_error));
+}
+
+TEST_F(ValidateData, int16_good) {
+ string str = header_with_int16 + "%2 = OpTypeInt 16 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, int16_bad) {
+ string str = header + "%2 = OpTypeInt 16 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int16_cap_error));
+}
+
+TEST_F(ValidateData, int64_good) {
+ string str = header_with_int64 + "%2 = OpTypeInt 64 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, int64_bad) {
+ string str = header + "%2 = OpTypeInt 64 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int64_cap_error));
+}
+
+// Number of bits in an integer may be only one of: {8,16,32,64}
+TEST_F(ValidateData, int_invalid_num_bits) {
+ string str = header + "%2 = OpTypeInt 48 1";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_num_bits_error));
+}
+
+TEST_F(ValidateData, float16_good) {
+ string str = header_with_float16 + "%2 = OpTypeFloat 16";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, float16_buffer_good) {
+ string str = header_with_float16_buffer + "%2 = OpTypeFloat 16";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, float16_bad) {
+ string str = header + "%2 = OpTypeFloat 16";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float16_cap_error));
+}
+
+TEST_F(ValidateData, float64_good) {
+ string str = header_with_float64 + "%2 = OpTypeFloat 64";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, float64_bad) {
+ string str = header + "%2 = OpTypeFloat 64";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float64_cap_error));
+}
+
+// Number of bits in a float may be only one of: {16,32,64}
+TEST_F(ValidateData, float_invalid_num_bits) {
+ string str = header + "%2 = OpTypeFloat 48";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_num_bits_error));
+}
+
+TEST_F(ValidateData, matrix_data_type_float) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 3
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, matrix_bad_column_type) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%mat33 = OpTypeMatrix %f32 3
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Columns in a matrix must be of type vector"));
+}
+
+TEST_F(ValidateData, matrix_data_type_int) {
+ string str = header + R"(
+%int32 = OpTypeInt 32 1
+%vec3 = OpTypeVector %int32 3
+%mat33 = OpTypeMatrix %vec3 3
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("can only be parameterized with floating-point types"));
+}
+
+TEST_F(ValidateData, matrix_data_type_bool) {
+ string str = header + R"(
+%boolt = OpTypeBool
+%vec3 = OpTypeVector %boolt 3
+%mat33 = OpTypeMatrix %vec3 3
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("can only be parameterized with floating-point types"));
+}
+
+TEST_F(ValidateData, matrix_with_0_columns) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 0
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
+}
+
+TEST_F(ValidateData, matrix_with_1_column) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 1
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
+}
+
+TEST_F(ValidateData, matrix_with_2_columns) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 2
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, matrix_with_3_columns) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 3
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, matrix_with_4_columns) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 4
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, matrix_with_5_column) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%mat33 = OpTypeMatrix %vec3 5
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
+}
+
+TEST_F(ValidateData, specialize_int) {
+ string str = header + R"(
+%i32 = OpTypeInt 32 1
+%len = OpSpecConstant %i32 2)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, specialize_float) {
+ string str = header + R"(
+%f32 = OpTypeFloat 32
+%len = OpSpecConstant %f32 2)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, specialize_boolean) {
+ string str = header + R"(
+%2 = OpTypeBool
+%3 = OpSpecConstantTrue %2
+%4 = OpSpecConstantFalse %2)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateData, specialize_boolean_to_int) {
+ string str = header + R"(
+%2 = OpTypeInt 32 1
+%3 = OpSpecConstantTrue %2
+%4 = OpSpecConstantFalse %2)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Specialization constant must be a boolean"));
+}
diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp
index 997ece59..9a1bb468 100644
--- a/test/val/val_id_test.cpp
+++ b/test/val/val_id_test.cpp
@@ -45,6 +45,10 @@ const char kGLSL450MemoryModel[] = R"(
OpCapability LiteralSampler
OpCapability DeviceEnqueue
OpCapability Vector16
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float64
OpMemoryModel Logical GLSL450
)";
@@ -343,7 +347,7 @@ TEST_F(ValidateID, OpTypeVectorComponentTypeBad) {
TEST_F(ValidateID, OpTypeMatrixGood) {
const char* spirv = R"(
-%1 = OpTypeInt 32 0
+%1 = OpTypeFloat 32
%2 = OpTypeVector %1 2
%3 = OpTypeMatrix %2 3)";
CHECK(spirv, SPV_SUCCESS);
@@ -460,8 +464,9 @@ TEST_P(OpTypeArrayLengthTest, LengthNegative) {
Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width))));
}
+// The only valid widths for integers are 8, 16, 32, and 64.
INSTANTIATE_TEST_CASE_P(Widths, OpTypeArrayLengthTest,
- ValuesIn(vector<int>{8, 16, 32, 48, 64}));
+ ValuesIn(vector<int>{8, 16, 32, 64}));
TEST_F(ValidateID, OpTypeArrayLengthNull) {
const char* spirv = R"(
@@ -844,7 +849,7 @@ TEST_F(ValidateID, OpConstantNullGood) {
%14 = OpConstantNull %13
%15 = OpTypeQueue
%16 = OpConstantNull %15
-%17 = OpTypeVector %3 2
+%17 = OpTypeVector %5 2
%18 = OpConstantNull %17
%19 = OpTypeMatrix %17 2
%20 = OpConstantNull %19
diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp
index 7f92cdbd..bc49075a 100644
--- a/test/val/val_layout_test.cpp
+++ b/test/val/val_layout_test.cpp
@@ -20,7 +20,6 @@
#include <utility>
#include "gmock/gmock.h"
-
#include "source/diagnostic.h"
#include "unit_spirv.h"
#include "val_fixtures.h"
@@ -95,8 +94,8 @@ const vector<string>& getInstructions() {
"%floatt = OpTypeFloat 32",
"%voidt = OpTypeVoid",
"%boolt = OpTypeBool",
- "%vec4 = OpTypeVector %intt 4",
- "%vec3 = OpTypeVector %intt 3",
+ "%vec4 = OpTypeVector %floatt 4",
+ "%vec3 = OpTypeVector %floatt 3",
"%mat33 = OpTypeMatrix %vec3 3",
"%mat44 = OpTypeMatrix %vec4 4",
"%struct = OpTypeStruct %intt %mat33",
@@ -150,9 +149,9 @@ INSTANTIATE_TEST_CASE_P(InstructionsOrder,
, make_tuple(string("OpDecorationGroup") , Range<13, 16>() , Range<0, 15>())
, make_tuple(string("OpTypeBool") , Range<17, 30>() , All)
, make_tuple(string("OpTypeVoid") , Range<17, 30>() , Range<0, 25>())
- , make_tuple(string("OpTypeFloat") , Range<17, 30>() , All)
+ , make_tuple(string("OpTypeFloat") , Range<17, 30>() , Range<0,20>())
, make_tuple(string("OpTypeInt") , Range<17, 30>() , Range<0, 20>())
- , make_tuple(string("OpTypeVector %intt 4") , Range<17, 30>() , Range<18, 23>())
+ , make_tuple(string("OpTypeVector %floatt 4") , Range<17, 30>() , Range<19, 23>())
, make_tuple(string("OpTypeMatrix %vec4 4") , Range<17, 30>() , Range<22, kRangeEnd>())
, make_tuple(string("OpTypeStruct") , Range<17, 30>() , Range<24, kRangeEnd>())
, make_tuple(string("%vfunct = OpTypeFunction"), Range<17, 30>() , Range<20, 30>())
diff --git a/test/val/val_ssa_test.cpp b/test/val/val_ssa_test.cpp
index e954cbf9..09bb9bcf 100644
--- a/test/val/val_ssa_test.cpp
+++ b/test/val/val_ssa_test.cpp
@@ -234,7 +234,8 @@ TEST_F(ValidateSSA, ForwardMemberDecorateGood) {
OpMemoryModel Logical GLSL450
OpMemberDecorate %struct 1 RowMajor
%intt = OpTypeInt 32 1
-%vec3 = OpTypeVector %intt 3
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
%mat33 = OpTypeMatrix %vec3 3
%struct = OpTypeStruct %intt %mat33
)";
@@ -249,7 +250,8 @@ TEST_F(ValidateSSA, ForwardMemberDecorateInvalidIdBad) {
OpName %missing "missing"
OpMemberDecorate %missing 1 RowMajor ; Target not defined
%intt = OpTypeInt 32 1
-%vec3 = OpTypeVector %intt 3
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
%mat33 = OpTypeMatrix %vec3 3
%struct = OpTypeStruct %intt %mat33
)";
@@ -265,9 +267,9 @@ TEST_F(ValidateSSA, ForwardGroupDecorateGood) {
OpDecorate %dgrp RowMajor
%dgrp = OpDecorationGroup
OpGroupDecorate %dgrp %mat33 %mat44
-%intt = OpTypeInt 32 1
-%vec3 = OpTypeVector %intt 3
-%vec4 = OpTypeVector %intt 4
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%vec4 = OpTypeVector %f32 4
%mat33 = OpTypeMatrix %vec3 3
%mat44 = OpTypeMatrix %vec4 4
)";
@@ -302,9 +304,9 @@ TEST_F(ValidateSSA, ForwardGroupDecorateMissingTargetBad) {
OpDecorate %dgrp RowMajor
%dgrp = OpDecorationGroup
OpGroupDecorate %dgrp %missing %mat44 ; Target not defined
-%intt = OpTypeInt 32 1
-%vec3 = OpTypeVector %intt 3
-%vec4 = OpTypeVector %intt 4
+%f32 = OpTypeFloat 32
+%vec3 = OpTypeVector %f32 3
+%vec4 = OpTypeVector %f32 4
%mat33 = OpTypeMatrix %vec3 3
%mat44 = OpTypeMatrix %vec4 4
)";
@@ -1241,10 +1243,8 @@ TEST_F(ValidateSSA, PhiVariableDefNotDominatedByParentBlockBad) {
"definition does not dominate its parent .\\[if_false\\]"));
}
-TEST_F(ValidateSSA,
- PhiVariableDefDominatesButNotDefinedInParentBlock) {
- string str = kHeader + "OpName %if_true \"if_true\"\n" +
- kBasicTypes +
+TEST_F(ValidateSSA, PhiVariableDefDominatesButNotDefinedInParentBlock) {
+ string str = kHeader + "OpName %if_true \"if_true\"\n" + kBasicTypes +
R"(
%func = OpFunction %voidt None %vfunct
%entry = OpLabel