Adding validation code for more data rules.
authorEhsan Nasiri <ehsann@google.com>
Thu, 10 Nov 2016 20:12:26 +0000 (15:12 -0500)
committerDavid Neto <dneto@google.com>
Tue, 15 Nov 2016 18:38:39 +0000 (13:38 -0500)
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.

source/validate_datarules.cpp
test/val/val_capability_test.cpp
test/val/val_data_test.cpp
test/val/val_id_test.cpp
test/val/val_layout_test.cpp
test/val/val_ssa_test.cpp

index c6626b8..d106237 100644 (file)
@@ -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;
 }
index 9e13950..f590ba8 100644 (file)
@@ -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
 
index b3bfb94..1eafe6c 100644 (file)
@@ -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"));
+}
index 997ece5..9a1bb46 100644 (file)
@@ -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
index 7f92cdb..bc49075 100644 (file)
@@ -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>())
index e954cbf..09bb9bc 100644 (file)
@@ -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