Home | History | Annotate | Download | only in val
      1 // Copyright (c) 2017 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Tests for unique type declaration rules validator.
     16 
     17 #include <string>
     18 
     19 #include "gmock/gmock.h"
     20 #include "test/unit_spirv.h"
     21 #include "test/val/val_fixtures.h"
     22 
     23 namespace spvtools {
     24 namespace val {
     25 namespace {
     26 
     27 using ::testing::HasSubstr;
     28 using ::testing::Not;
     29 
     30 using ValidateArithmetics = spvtest::ValidateBase<bool>;
     31 
     32 std::string GenerateCode(const std::string& main_body) {
     33   const std::string prefix =
     34       R"(
     35 OpCapability Shader
     36 OpCapability Int64
     37 OpCapability Float64
     38 OpCapability Matrix
     39 %ext_inst = OpExtInstImport "GLSL.std.450"
     40 OpMemoryModel Logical GLSL450
     41 OpEntryPoint Fragment %main "main"
     42 OpExecutionMode %main OriginUpperLeft
     43 %void = OpTypeVoid
     44 %func = OpTypeFunction %void
     45 %bool = OpTypeBool
     46 %f32 = OpTypeFloat 32
     47 %u32 = OpTypeInt 32 0
     48 %s32 = OpTypeInt 32 1
     49 %f64 = OpTypeFloat 64
     50 %u64 = OpTypeInt 64 0
     51 %s64 = OpTypeInt 64 1
     52 %boolvec2 = OpTypeVector %bool 2
     53 %s32vec2 = OpTypeVector %s32 2
     54 %u32vec2 = OpTypeVector %u32 2
     55 %u64vec2 = OpTypeVector %u64 2
     56 %f32vec2 = OpTypeVector %f32 2
     57 %f64vec2 = OpTypeVector %f64 2
     58 %boolvec3 = OpTypeVector %bool 3
     59 %u32vec3 = OpTypeVector %u32 3
     60 %u64vec3 = OpTypeVector %u64 3
     61 %s32vec3 = OpTypeVector %s32 3
     62 %f32vec3 = OpTypeVector %f32 3
     63 %f64vec3 = OpTypeVector %f64 3
     64 %boolvec4 = OpTypeVector %bool 4
     65 %u32vec4 = OpTypeVector %u32 4
     66 %u64vec4 = OpTypeVector %u64 4
     67 %s32vec4 = OpTypeVector %s32 4
     68 %f32vec4 = OpTypeVector %f32 4
     69 %f64vec4 = OpTypeVector %f64 4
     70 
     71 %f32mat22 = OpTypeMatrix %f32vec2 2
     72 %f32mat23 = OpTypeMatrix %f32vec2 3
     73 %f32mat32 = OpTypeMatrix %f32vec3 2
     74 %f32mat33 = OpTypeMatrix %f32vec3 3
     75 %f64mat22 = OpTypeMatrix %f64vec2 2
     76 
     77 %struct_f32_f32 = OpTypeStruct %f32 %f32
     78 %struct_u32_u32 = OpTypeStruct %u32 %u32
     79 %struct_u32_u32_u32 = OpTypeStruct %u32 %u32 %u32
     80 %struct_s32_s32 = OpTypeStruct %s32 %s32
     81 %struct_s32_u32 = OpTypeStruct %s32 %u32
     82 %struct_u32vec2_u32vec2 = OpTypeStruct %u32vec2 %u32vec2
     83 %struct_s32vec2_s32vec2 = OpTypeStruct %s32vec2 %s32vec2
     84 
     85 %f32_0 = OpConstant %f32 0
     86 %f32_1 = OpConstant %f32 1
     87 %f32_2 = OpConstant %f32 2
     88 %f32_3 = OpConstant %f32 3
     89 %f32_4 = OpConstant %f32 4
     90 %f32_pi = OpConstant %f32 3.14159
     91 
     92 %s32_0 = OpConstant %s32 0
     93 %s32_1 = OpConstant %s32 1
     94 %s32_2 = OpConstant %s32 2
     95 %s32_3 = OpConstant %s32 3
     96 %s32_4 = OpConstant %s32 4
     97 %s32_m1 = OpConstant %s32 -1
     98 
     99 %u32_0 = OpConstant %u32 0
    100 %u32_1 = OpConstant %u32 1
    101 %u32_2 = OpConstant %u32 2
    102 %u32_3 = OpConstant %u32 3
    103 %u32_4 = OpConstant %u32 4
    104 
    105 %f64_0 = OpConstant %f64 0
    106 %f64_1 = OpConstant %f64 1
    107 %f64_2 = OpConstant %f64 2
    108 %f64_3 = OpConstant %f64 3
    109 %f64_4 = OpConstant %f64 4
    110 
    111 %s64_0 = OpConstant %s64 0
    112 %s64_1 = OpConstant %s64 1
    113 %s64_2 = OpConstant %s64 2
    114 %s64_3 = OpConstant %s64 3
    115 %s64_4 = OpConstant %s64 4
    116 %s64_m1 = OpConstant %s64 -1
    117 
    118 %u64_0 = OpConstant %u64 0
    119 %u64_1 = OpConstant %u64 1
    120 %u64_2 = OpConstant %u64 2
    121 %u64_3 = OpConstant %u64 3
    122 %u64_4 = OpConstant %u64 4
    123 
    124 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
    125 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
    126 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
    127 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
    128 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
    129 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
    130 
    131 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
    132 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
    133 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
    134 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
    135 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
    136 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
    137 
    138 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
    139 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
    140 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
    141 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
    142 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
    143 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
    144 
    145 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
    146 %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
    147 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
    148 %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
    149 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
    150 %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
    151 
    152 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
    153 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
    154 %f32mat32_123123 = OpConstantComposite %f32mat32 %f32vec3_123 %f32vec3_123
    155 %f32mat33_123123123 = OpConstantComposite %f32mat33 %f32vec3_123 %f32vec3_123 %f32vec3_123
    156 
    157 %f64mat22_1212 = OpConstantComposite %f64mat22 %f64vec2_12 %f64vec2_12
    158 
    159 %main = OpFunction %void None %func
    160 %main_entry = OpLabel)";
    161 
    162   const std::string suffix =
    163       R"(
    164 OpReturn
    165 OpFunctionEnd)";
    166 
    167   return prefix + main_body + suffix;
    168 }
    169 
    170 TEST_F(ValidateArithmetics, F32Success) {
    171   const std::string body = R"(
    172 %val1 = OpFMul %f32 %f32_0 %f32_1
    173 %val2 = OpFSub %f32 %f32_2 %f32_0
    174 %val3 = OpFAdd %f32 %val1 %val2
    175 %val4 = OpFNegate %f32 %val3
    176 %val5 = OpFDiv %f32 %val4 %val1
    177 %val6 = OpFRem %f32 %val4 %f32_2
    178 %val7 = OpFMod %f32 %val4 %f32_2
    179 )";
    180 
    181   CompileSuccessfully(GenerateCode(body).c_str());
    182   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    183 }
    184 
    185 TEST_F(ValidateArithmetics, F64Success) {
    186   const std::string body = R"(
    187 %val1 = OpFMul %f64 %f64_0 %f64_1
    188 %val2 = OpFSub %f64 %f64_2 %f64_0
    189 %val3 = OpFAdd %f64 %val1 %val2
    190 %val4 = OpFNegate %f64 %val3
    191 %val5 = OpFDiv %f64 %val4 %val1
    192 %val6 = OpFRem %f64 %val4 %f64_2
    193 %val7 = OpFMod %f64 %val4 %f64_2
    194 )";
    195 
    196   CompileSuccessfully(GenerateCode(body).c_str());
    197   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    198 }
    199 
    200 TEST_F(ValidateArithmetics, Int32Success) {
    201   const std::string body = R"(
    202 %val1 = OpIMul %u32 %s32_0 %u32_1
    203 %val2 = OpIMul %s32 %s32_2 %u32_1
    204 %val3 = OpIAdd %u32 %val1 %val2
    205 %val4 = OpIAdd %s32 %val1 %val2
    206 %val5 = OpISub %u32 %val3 %val4
    207 %val6 = OpISub %s32 %val4 %val3
    208 %val7 = OpSDiv %s32 %val4 %val3
    209 %val8 = OpSNegate %s32 %val7
    210 %val9 = OpSRem %s32 %val4 %val3
    211 %val10 = OpSMod %s32 %val4 %val3
    212 )";
    213 
    214   CompileSuccessfully(GenerateCode(body).c_str());
    215   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    216 }
    217 
    218 TEST_F(ValidateArithmetics, Int64Success) {
    219   const std::string body = R"(
    220 %val1 = OpIMul %u64 %s64_0 %u64_1
    221 %val2 = OpIMul %s64 %s64_2 %u64_1
    222 %val3 = OpIAdd %u64 %val1 %val2
    223 %val4 = OpIAdd %s64 %val1 %val2
    224 %val5 = OpISub %u64 %val3 %val4
    225 %val6 = OpISub %s64 %val4 %val3
    226 %val7 = OpSDiv %s64 %val4 %val3
    227 %val8 = OpSNegate %s64 %val7
    228 %val9 = OpSRem %s64 %val4 %val3
    229 %val10 = OpSMod %s64 %val4 %val3
    230 )";
    231 
    232   CompileSuccessfully(GenerateCode(body).c_str());
    233   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    234 }
    235 
    236 TEST_F(ValidateArithmetics, F32Vec2Success) {
    237   const std::string body = R"(
    238 %val1 = OpFMul %f32vec2 %f32vec2_01 %f32vec2_12
    239 %val2 = OpFSub %f32vec2 %f32vec2_12 %f32vec2_01
    240 %val3 = OpFAdd %f32vec2 %val1 %val2
    241 %val4 = OpFNegate %f32vec2 %val3
    242 %val5 = OpFDiv %f32vec2 %val4 %val1
    243 %val6 = OpFRem %f32vec2 %val4 %f32vec2_12
    244 %val7 = OpFMod %f32vec2 %val4 %f32vec2_12
    245 )";
    246 
    247   CompileSuccessfully(GenerateCode(body).c_str());
    248   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    249 }
    250 
    251 TEST_F(ValidateArithmetics, F64Vec2Success) {
    252   const std::string body = R"(
    253 %val1 = OpFMul %f64vec2 %f64vec2_01 %f64vec2_12
    254 %val2 = OpFSub %f64vec2 %f64vec2_12 %f64vec2_01
    255 %val3 = OpFAdd %f64vec2 %val1 %val2
    256 %val4 = OpFNegate %f64vec2 %val3
    257 %val5 = OpFDiv %f64vec2 %val4 %val1
    258 %val6 = OpFRem %f64vec2 %val4 %f64vec2_12
    259 %val7 = OpFMod %f64vec2 %val4 %f64vec2_12
    260 )";
    261 
    262   CompileSuccessfully(GenerateCode(body).c_str());
    263   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    264 }
    265 
    266 TEST_F(ValidateArithmetics, U32Vec2Success) {
    267   const std::string body = R"(
    268 %val1 = OpIMul %u32vec2 %u32vec2_01 %u32vec2_12
    269 %val2 = OpISub %u32vec2 %u32vec2_12 %u32vec2_01
    270 %val3 = OpIAdd %u32vec2 %val1 %val2
    271 %val4 = OpSNegate %u32vec2 %val3
    272 %val5 = OpSDiv %u32vec2 %val4 %val1
    273 %val6 = OpSRem %u32vec2 %val4 %u32vec2_12
    274 %val7 = OpSMod %u32vec2 %val4 %u32vec2_12
    275 )";
    276 
    277   CompileSuccessfully(GenerateCode(body).c_str());
    278   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    279 }
    280 
    281 TEST_F(ValidateArithmetics, FNegateTypeIdU32) {
    282   const std::string body = R"(
    283 %val = OpFNegate %u32 %u32_0
    284 )";
    285 
    286   CompileSuccessfully(GenerateCode(body).c_str());
    287   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    288   EXPECT_THAT(
    289       getDiagnosticString(),
    290       HasSubstr(
    291           "Expected floating scalar or vector type as Result Type: FNegate"));
    292 }
    293 
    294 TEST_F(ValidateArithmetics, FNegateTypeIdVec2U32) {
    295   const std::string body = R"(
    296 %val = OpFNegate %u32vec2 %u32vec2_01
    297 )";
    298 
    299   CompileSuccessfully(GenerateCode(body).c_str());
    300   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    301   EXPECT_THAT(
    302       getDiagnosticString(),
    303       HasSubstr(
    304           "Expected floating scalar or vector type as Result Type: FNegate"));
    305 }
    306 
    307 TEST_F(ValidateArithmetics, FNegateWrongOperand) {
    308   const std::string body = R"(
    309 %val = OpFNegate %f32 %u32_0
    310 )";
    311 
    312   CompileSuccessfully(GenerateCode(body).c_str());
    313   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    314   EXPECT_THAT(getDiagnosticString(),
    315               HasSubstr("Expected arithmetic operands to be of Result Type: "
    316                         "FNegate operand index 2"));
    317 }
    318 
    319 TEST_F(ValidateArithmetics, FMulTypeIdU32) {
    320   const std::string body = R"(
    321 %val = OpFMul %u32 %u32_0 %u32_1
    322 )";
    323 
    324   CompileSuccessfully(GenerateCode(body).c_str());
    325   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    326   EXPECT_THAT(
    327       getDiagnosticString(),
    328       HasSubstr(
    329           "Expected floating scalar or vector type as Result Type: FMul"));
    330 }
    331 
    332 TEST_F(ValidateArithmetics, FMulTypeIdVec2U32) {
    333   const std::string body = R"(
    334 %val = OpFMul %u32vec2 %u32vec2_01 %u32vec2_12
    335 )";
    336 
    337   CompileSuccessfully(GenerateCode(body).c_str());
    338   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    339   EXPECT_THAT(
    340       getDiagnosticString(),
    341       HasSubstr(
    342           "Expected floating scalar or vector type as Result Type: FMul"));
    343 }
    344 
    345 TEST_F(ValidateArithmetics, FMulWrongOperand1) {
    346   const std::string body = R"(
    347 %val = OpFMul %f32 %u32_0 %f32_1
    348 )";
    349 
    350   CompileSuccessfully(GenerateCode(body).c_str());
    351   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    352   EXPECT_THAT(getDiagnosticString(),
    353               HasSubstr("Expected arithmetic operands to be of Result Type: "
    354                         "FMul operand index 2"));
    355 }
    356 
    357 TEST_F(ValidateArithmetics, FMulWrongOperand2) {
    358   const std::string body = R"(
    359 %val = OpFMul %f32 %f32_0 %u32_1
    360 )";
    361 
    362   CompileSuccessfully(GenerateCode(body).c_str());
    363   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    364   EXPECT_THAT(getDiagnosticString(),
    365               HasSubstr("Expected arithmetic operands to be of Result Type: "
    366                         "FMul operand index 3"));
    367 }
    368 
    369 TEST_F(ValidateArithmetics, FMulWrongVectorOperand1) {
    370   const std::string body = R"(
    371 %val = OpFMul %f64vec3 %f32vec3_123 %f64vec3_012
    372 )";
    373 
    374   CompileSuccessfully(GenerateCode(body).c_str());
    375   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    376   EXPECT_THAT(getDiagnosticString(),
    377               HasSubstr("Expected arithmetic operands to be of Result Type: "
    378                         "FMul operand index 2"));
    379 }
    380 
    381 TEST_F(ValidateArithmetics, FMulWrongVectorOperand2) {
    382   const std::string body = R"(
    383 %val = OpFMul %f32vec3 %f32vec3_123 %f64vec3_012
    384 )";
    385 
    386   CompileSuccessfully(GenerateCode(body).c_str());
    387   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    388   EXPECT_THAT(getDiagnosticString(),
    389               HasSubstr("Expected arithmetic operands to be of Result Type: "
    390                         "FMul operand index 3"));
    391 }
    392 
    393 TEST_F(ValidateArithmetics, IMulFloatTypeId) {
    394   const std::string body = R"(
    395 %val = OpIMul %f32 %u32_0 %s32_1
    396 )";
    397 
    398   CompileSuccessfully(GenerateCode(body).c_str());
    399   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    400   EXPECT_THAT(
    401       getDiagnosticString(),
    402       HasSubstr("Expected int scalar or vector type as Result Type: IMul"));
    403 }
    404 
    405 TEST_F(ValidateArithmetics, IMulFloatOperand1) {
    406   const std::string body = R"(
    407 %val = OpIMul %u32 %f32_0 %s32_1
    408 )";
    409 
    410   CompileSuccessfully(GenerateCode(body).c_str());
    411   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    412   EXPECT_THAT(getDiagnosticString(),
    413               HasSubstr("Expected int scalar or vector type as operand: "
    414                         "IMul operand index 2"));
    415 }
    416 
    417 TEST_F(ValidateArithmetics, IMulFloatOperand2) {
    418   const std::string body = R"(
    419 %val = OpIMul %u32 %s32_0 %f32_1
    420 )";
    421 
    422   CompileSuccessfully(GenerateCode(body).c_str());
    423   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    424   EXPECT_THAT(getDiagnosticString(),
    425               HasSubstr("Expected int scalar or vector type as operand: "
    426                         "IMul operand index 3"));
    427 }
    428 
    429 TEST_F(ValidateArithmetics, IMulWrongBitWidthOperand1) {
    430   const std::string body = R"(
    431 %val = OpIMul %u64 %u32_0 %s64_1
    432 )";
    433 
    434   CompileSuccessfully(GenerateCode(body).c_str());
    435   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    436   EXPECT_THAT(
    437       getDiagnosticString(),
    438       HasSubstr("Expected arithmetic operands to have the same bit width "
    439                 "as Result Type: IMul operand index 2"));
    440 }
    441 
    442 TEST_F(ValidateArithmetics, IMulWrongBitWidthOperand2) {
    443   const std::string body = R"(
    444 %val = OpIMul %u32 %u32_0 %s64_1
    445 )";
    446 
    447   CompileSuccessfully(GenerateCode(body).c_str());
    448   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    449   EXPECT_THAT(
    450       getDiagnosticString(),
    451       HasSubstr("Expected arithmetic operands to have the same bit width "
    452                 "as Result Type: IMul operand index 3"));
    453 }
    454 
    455 TEST_F(ValidateArithmetics, IMulWrongBitWidthVector) {
    456   const std::string body = R"(
    457 %val = OpIMul %u64vec3 %u32vec3_012 %u32vec3_123
    458 )";
    459 
    460   CompileSuccessfully(GenerateCode(body).c_str());
    461   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    462   EXPECT_THAT(
    463       getDiagnosticString(),
    464       HasSubstr("Expected arithmetic operands to have the same bit width "
    465                 "as Result Type: IMul operand index 2"));
    466 }
    467 
    468 TEST_F(ValidateArithmetics, IMulVectorScalarOperand1) {
    469   const std::string body = R"(
    470 %val = OpIMul %u32vec2 %u32_0 %u32vec2_01
    471 )";
    472 
    473   CompileSuccessfully(GenerateCode(body).c_str());
    474   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    475   EXPECT_THAT(
    476       getDiagnosticString(),
    477       HasSubstr("Expected arithmetic operands to have the same dimension "
    478                 "as Result Type: IMul operand index 2"));
    479 }
    480 
    481 TEST_F(ValidateArithmetics, IMulVectorScalarOperand2) {
    482   const std::string body = R"(
    483 %val = OpIMul %u32vec2 %u32vec2_01 %u32_0
    484 )";
    485 
    486   CompileSuccessfully(GenerateCode(body).c_str());
    487   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    488   EXPECT_THAT(
    489       getDiagnosticString(),
    490       HasSubstr("Expected arithmetic operands to have the same dimension "
    491                 "as Result Type: IMul operand index 3"));
    492 }
    493 
    494 TEST_F(ValidateArithmetics, IMulScalarVectorOperand1) {
    495   const std::string body = R"(
    496 %val = OpIMul %s32 %u32vec2_01 %u32_0
    497 )";
    498 
    499   CompileSuccessfully(GenerateCode(body).c_str());
    500   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    501   EXPECT_THAT(
    502       getDiagnosticString(),
    503       HasSubstr("Expected arithmetic operands to have the same dimension "
    504                 "as Result Type: IMul operand index 2"));
    505 }
    506 
    507 TEST_F(ValidateArithmetics, IMulScalarVectorOperand2) {
    508   const std::string body = R"(
    509 %val = OpIMul %u32 %u32_0 %s32vec2_01
    510 )";
    511 
    512   CompileSuccessfully(GenerateCode(body).c_str());
    513   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    514   EXPECT_THAT(
    515       getDiagnosticString(),
    516       HasSubstr("Expected arithmetic operands to have the same dimension "
    517                 "as Result Type: IMul operand index 3"));
    518 }
    519 
    520 TEST_F(ValidateArithmetics, SNegateFloat) {
    521   const std::string body = R"(
    522 %val = OpSNegate %s32 %f32_1
    523 )";
    524 
    525   CompileSuccessfully(GenerateCode(body).c_str());
    526   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    527   EXPECT_THAT(getDiagnosticString(),
    528               HasSubstr("Expected int scalar or vector type as operand: "
    529                         "SNegate operand index 2"));
    530 }
    531 
    532 TEST_F(ValidateArithmetics, UDivFloatType) {
    533   const std::string body = R"(
    534 %val = OpUDiv %f32 %u32_2 %u32_1
    535 )";
    536 
    537   CompileSuccessfully(GenerateCode(body).c_str());
    538   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    539   EXPECT_THAT(
    540       getDiagnosticString(),
    541       HasSubstr(
    542           "Expected unsigned int scalar or vector type as Result Type: UDiv"));
    543 }
    544 
    545 TEST_F(ValidateArithmetics, UDivSignedIntType) {
    546   const std::string body = R"(
    547 %val = OpUDiv %s32 %u32_2 %u32_1
    548 )";
    549 
    550   CompileSuccessfully(GenerateCode(body).c_str());
    551   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    552   EXPECT_THAT(
    553       getDiagnosticString(),
    554       HasSubstr(
    555           "Expected unsigned int scalar or vector type as Result Type: UDiv"));
    556 }
    557 
    558 TEST_F(ValidateArithmetics, UDivWrongOperand1) {
    559   const std::string body = R"(
    560 %val = OpUDiv %u64 %f64_2 %u64_1
    561 )";
    562 
    563   CompileSuccessfully(GenerateCode(body).c_str());
    564   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    565   EXPECT_THAT(getDiagnosticString(),
    566               HasSubstr("Expected arithmetic operands to be of Result Type: "
    567                         "UDiv operand index 2"));
    568 }
    569 
    570 TEST_F(ValidateArithmetics, UDivWrongOperand2) {
    571   const std::string body = R"(
    572 %val = OpUDiv %u64 %u64_2 %u32_1
    573 )";
    574 
    575   CompileSuccessfully(GenerateCode(body).c_str());
    576   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    577   EXPECT_THAT(getDiagnosticString(),
    578               HasSubstr("Expected arithmetic operands to be of Result Type: "
    579                         "UDiv operand index 3"));
    580 }
    581 
    582 TEST_F(ValidateArithmetics, DotSuccess) {
    583   const std::string body = R"(
    584 %val = OpDot %f32 %f32vec2_01 %f32vec2_12
    585 )";
    586 
    587   CompileSuccessfully(GenerateCode(body).c_str());
    588   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    589 }
    590 
    591 TEST_F(ValidateArithmetics, DotWrongTypeId) {
    592   const std::string body = R"(
    593 %val = OpDot %u32 %u32vec2_01 %u32vec2_12
    594 )";
    595 
    596   CompileSuccessfully(GenerateCode(body).c_str());
    597   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    598   EXPECT_THAT(getDiagnosticString(),
    599               HasSubstr("Expected float scalar type as Result Type: Dot"));
    600 }
    601 
    602 TEST_F(ValidateArithmetics, DotNotVectorTypeOperand1) {
    603   const std::string body = R"(
    604 %val = OpDot %f32 %f32 %f32vec2_12
    605 )";
    606 
    607   CompileSuccessfully(GenerateCode(body).c_str());
    608   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
    609   EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 6[%float] cannot be a "
    610                                                "type"));
    611 }
    612 
    613 TEST_F(ValidateArithmetics, DotNotVectorTypeOperand2) {
    614   const std::string body = R"(
    615 %val = OpDot %f32 %f32vec3_012 %f32_1
    616 )";
    617 
    618   CompileSuccessfully(GenerateCode(body).c_str());
    619   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    620   EXPECT_THAT(
    621       getDiagnosticString(),
    622       HasSubstr("Expected float vector as operand: Dot operand index 3"));
    623 }
    624 
    625 TEST_F(ValidateArithmetics, DotWrongComponentOperand1) {
    626   const std::string body = R"(
    627 %val = OpDot %f64 %f32vec2_01 %f64vec2_12
    628 )";
    629 
    630   CompileSuccessfully(GenerateCode(body).c_str());
    631   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    632   EXPECT_THAT(getDiagnosticString(),
    633               HasSubstr("Expected component type to be equal to Result Type: "
    634                         "Dot operand index 2"));
    635 }
    636 
    637 TEST_F(ValidateArithmetics, DotWrongComponentOperand2) {
    638   const std::string body = R"(
    639 %val = OpDot %f32 %f32vec2_01 %f64vec2_12
    640 )";
    641 
    642   CompileSuccessfully(GenerateCode(body).c_str());
    643   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    644   EXPECT_THAT(getDiagnosticString(),
    645               HasSubstr("Expected component type to be equal to Result Type: "
    646                         "Dot operand index 3"));
    647 }
    648 
    649 TEST_F(ValidateArithmetics, DotDifferentVectorSize) {
    650   const std::string body = R"(
    651 %val = OpDot %f32 %f32vec2_01 %f32vec3_123
    652 )";
    653 
    654   CompileSuccessfully(GenerateCode(body).c_str());
    655   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    656   EXPECT_THAT(
    657       getDiagnosticString(),
    658       HasSubstr(
    659           "Expected operands to have the same number of componenets: Dot"));
    660 }
    661 
    662 TEST_F(ValidateArithmetics, VectorTimesScalarSuccess) {
    663   const std::string body = R"(
    664 %val = OpVectorTimesScalar %f32vec2 %f32vec2_01 %f32_2
    665 )";
    666 
    667   CompileSuccessfully(GenerateCode(body).c_str());
    668   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    669 }
    670 
    671 TEST_F(ValidateArithmetics, VectorTimesScalarWrongTypeId) {
    672   const std::string body = R"(
    673 %val = OpVectorTimesScalar %u32vec2 %f32vec2_01 %f32_2
    674 )";
    675 
    676   CompileSuccessfully(GenerateCode(body).c_str());
    677   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    678   EXPECT_THAT(getDiagnosticString(),
    679               HasSubstr("Expected float vector type as Result Type: "
    680                         "VectorTimesScalar"));
    681 }
    682 
    683 TEST_F(ValidateArithmetics, VectorTimesScalarWrongVector) {
    684   const std::string body = R"(
    685 %val = OpVectorTimesScalar %f32vec2 %f32vec3_012 %f32_2
    686 )";
    687 
    688   CompileSuccessfully(GenerateCode(body).c_str());
    689   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    690   EXPECT_THAT(
    691       getDiagnosticString(),
    692       HasSubstr("Expected vector operand type to be equal to Result Type: "
    693                 "VectorTimesScalar"));
    694 }
    695 
    696 TEST_F(ValidateArithmetics, VectorTimesScalarWrongScalar) {
    697   const std::string body = R"(
    698 %val = OpVectorTimesScalar %f32vec2 %f32vec2_01 %f64_2
    699 )";
    700 
    701   CompileSuccessfully(GenerateCode(body).c_str());
    702   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    703   EXPECT_THAT(
    704       getDiagnosticString(),
    705       HasSubstr("Expected scalar operand type to be equal to the component "
    706                 "type of the vector operand: VectorTimesScalar"));
    707 }
    708 
    709 TEST_F(ValidateArithmetics, MatrixTimesScalarSuccess) {
    710   const std::string body = R"(
    711 %val = OpMatrixTimesScalar %f32mat22 %f32mat22_1212 %f32_2
    712 )";
    713 
    714   CompileSuccessfully(GenerateCode(body).c_str());
    715   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    716 }
    717 
    718 TEST_F(ValidateArithmetics, MatrixTimesScalarWrongTypeId) {
    719   const std::string body = R"(
    720 %val = OpMatrixTimesScalar %f32vec2 %f32mat22_1212 %f32_2
    721 )";
    722 
    723   CompileSuccessfully(GenerateCode(body).c_str());
    724   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    725   EXPECT_THAT(getDiagnosticString(),
    726               HasSubstr("Expected float matrix type as Result Type: "
    727                         "MatrixTimesScalar"));
    728 }
    729 
    730 TEST_F(ValidateArithmetics, MatrixTimesScalarWrongMatrix) {
    731   const std::string body = R"(
    732 %val = OpMatrixTimesScalar %f32mat22 %f32vec2_01 %f32_2
    733 )";
    734 
    735   CompileSuccessfully(GenerateCode(body).c_str());
    736   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    737   EXPECT_THAT(
    738       getDiagnosticString(),
    739       HasSubstr("Expected matrix operand type to be equal to Result Type: "
    740                 "MatrixTimesScalar"));
    741 }
    742 
    743 TEST_F(ValidateArithmetics, MatrixTimesScalarWrongScalar) {
    744   const std::string body = R"(
    745 %val = OpMatrixTimesScalar %f32mat22 %f32mat22_1212 %f64_2
    746 )";
    747 
    748   CompileSuccessfully(GenerateCode(body).c_str());
    749   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    750   EXPECT_THAT(
    751       getDiagnosticString(),
    752       HasSubstr("Expected scalar operand type to be equal to the component "
    753                 "type of the matrix operand: MatrixTimesScalar"));
    754 }
    755 
    756 TEST_F(ValidateArithmetics, VectorTimesMatrix2x22Success) {
    757   const std::string body = R"(
    758 %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat22_1212
    759 )";
    760 
    761   CompileSuccessfully(GenerateCode(body).c_str());
    762   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    763 }
    764 
    765 TEST_F(ValidateArithmetics, VectorTimesMatrix3x32Success) {
    766   const std::string body = R"(
    767 %val = OpVectorTimesMatrix %f32vec2 %f32vec3_123 %f32mat32_123123
    768 )";
    769 
    770   CompileSuccessfully(GenerateCode(body).c_str());
    771   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    772 }
    773 
    774 TEST_F(ValidateArithmetics, VectorTimesMatrixWrongTypeId) {
    775   const std::string body = R"(
    776 %val = OpVectorTimesMatrix %f32mat22 %f32vec2_12 %f32mat22_1212
    777 )";
    778 
    779   CompileSuccessfully(GenerateCode(body).c_str());
    780   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    781   EXPECT_THAT(getDiagnosticString(),
    782               HasSubstr("Expected float vector type as Result Type: "
    783                         "VectorTimesMatrix"));
    784 }
    785 
    786 TEST_F(ValidateArithmetics, VectorTimesMatrixNotFloatVector) {
    787   const std::string body = R"(
    788 %val = OpVectorTimesMatrix %f32vec2 %u32vec2_12 %f32mat22_1212
    789 )";
    790 
    791   CompileSuccessfully(GenerateCode(body).c_str());
    792   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    793   EXPECT_THAT(getDiagnosticString(),
    794               HasSubstr("Expected float vector type as left operand: "
    795                         "VectorTimesMatrix"));
    796 }
    797 
    798 TEST_F(ValidateArithmetics, VectorTimesMatrixWrongVectorComponent) {
    799   const std::string body = R"(
    800 %val = OpVectorTimesMatrix %f32vec2 %f64vec2_12 %f32mat22_1212
    801 )";
    802 
    803   CompileSuccessfully(GenerateCode(body).c_str());
    804   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    805   EXPECT_THAT(
    806       getDiagnosticString(),
    807       HasSubstr(
    808           "Expected component types of Result Type and vector to be equal: "
    809           "VectorTimesMatrix"));
    810 }
    811 
    812 TEST_F(ValidateArithmetics, VectorTimesMatrixWrongMatrix) {
    813   const std::string body = R"(
    814 %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32vec2_12
    815 )";
    816 
    817   CompileSuccessfully(GenerateCode(body).c_str());
    818   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    819   EXPECT_THAT(getDiagnosticString(),
    820               HasSubstr("Expected float matrix type as right operand: "
    821                         "VectorTimesMatrix"));
    822 }
    823 
    824 TEST_F(ValidateArithmetics, VectorTimesMatrixWrongMatrixComponent) {
    825   const std::string body = R"(
    826 %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f64mat22_1212
    827 )";
    828 
    829   CompileSuccessfully(GenerateCode(body).c_str());
    830   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    831   EXPECT_THAT(
    832       getDiagnosticString(),
    833       HasSubstr(
    834           "Expected component types of Result Type and matrix to be equal: "
    835           "VectorTimesMatrix"));
    836 }
    837 
    838 TEST_F(ValidateArithmetics, VectorTimesMatrix2eq2x23Fail) {
    839   const std::string body = R"(
    840 %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat23_121212
    841 )";
    842 
    843   CompileSuccessfully(GenerateCode(body).c_str());
    844   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    845   EXPECT_THAT(
    846       getDiagnosticString(),
    847       HasSubstr(
    848           "Expected number of columns of the matrix to be equal to Result Type "
    849           "vector size: VectorTimesMatrix"));
    850 }
    851 
    852 TEST_F(ValidateArithmetics, VectorTimesMatrix2x32Fail) {
    853   const std::string body = R"(
    854 %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat32_123123
    855 )";
    856 
    857   CompileSuccessfully(GenerateCode(body).c_str());
    858   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    859   EXPECT_THAT(
    860       getDiagnosticString(),
    861       HasSubstr(
    862           "Expected number of rows of the matrix to be equal to the vector "
    863           "operand size: VectorTimesMatrix"));
    864 }
    865 
    866 TEST_F(ValidateArithmetics, MatrixTimesVector22x2Success) {
    867   const std::string body = R"(
    868 %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f32vec2_12
    869 )";
    870 
    871   CompileSuccessfully(GenerateCode(body).c_str());
    872   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    873 }
    874 
    875 TEST_F(ValidateArithmetics, MatrixTimesVector23x3Success) {
    876   const std::string body = R"(
    877 %val = OpMatrixTimesVector %f32vec2 %f32mat23_121212 %f32vec3_123
    878 )";
    879 
    880   CompileSuccessfully(GenerateCode(body).c_str());
    881   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    882 }
    883 
    884 TEST_F(ValidateArithmetics, MatrixTimesVectorWrongTypeId) {
    885   const std::string body = R"(
    886 %val = OpMatrixTimesVector %f32mat22 %f32mat22_1212 %f32vec2_12
    887 )";
    888 
    889   CompileSuccessfully(GenerateCode(body).c_str());
    890   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    891   EXPECT_THAT(getDiagnosticString(),
    892               HasSubstr("Expected float vector type as Result Type: "
    893                         "MatrixTimesVector"));
    894 }
    895 
    896 TEST_F(ValidateArithmetics, MatrixTimesVectorWrongMatrix) {
    897   const std::string body = R"(
    898 %val = OpMatrixTimesVector %f32vec3 %f32vec3_123 %f32vec3_123
    899 )";
    900 
    901   CompileSuccessfully(GenerateCode(body).c_str());
    902   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    903   EXPECT_THAT(getDiagnosticString(),
    904               HasSubstr("Expected float matrix type as left operand: "
    905                         "MatrixTimesVector"));
    906 }
    907 
    908 TEST_F(ValidateArithmetics, MatrixTimesVectorWrongMatrixCol) {
    909   const std::string body = R"(
    910 %val = OpMatrixTimesVector %f32vec3 %f32mat23_121212 %f32vec3_123
    911 )";
    912 
    913   CompileSuccessfully(GenerateCode(body).c_str());
    914   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    915   EXPECT_THAT(
    916       getDiagnosticString(),
    917       HasSubstr(
    918           "Expected column type of the matrix to be equal to Result Type: "
    919           "MatrixTimesVector"));
    920 }
    921 
    922 TEST_F(ValidateArithmetics, MatrixTimesVectorWrongVector) {
    923   const std::string body = R"(
    924 %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %u32vec2_12
    925 )";
    926 
    927   CompileSuccessfully(GenerateCode(body).c_str());
    928   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    929   EXPECT_THAT(getDiagnosticString(),
    930               HasSubstr("Expected float vector type as right operand: "
    931                         "MatrixTimesVector"));
    932 }
    933 
    934 TEST_F(ValidateArithmetics, MatrixTimesVectorDifferentComponents) {
    935   const std::string body = R"(
    936 %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f64vec2_12
    937 )";
    938 
    939   CompileSuccessfully(GenerateCode(body).c_str());
    940   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    941   EXPECT_THAT(getDiagnosticString(),
    942               HasSubstr("Expected component types of the operands to be equal: "
    943                         "MatrixTimesVector"));
    944 }
    945 
    946 TEST_F(ValidateArithmetics, MatrixTimesVector22x3Fail) {
    947   const std::string body = R"(
    948 %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f32vec3_123
    949 )";
    950 
    951   CompileSuccessfully(GenerateCode(body).c_str());
    952   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    953   EXPECT_THAT(
    954       getDiagnosticString(),
    955       HasSubstr(
    956           "Expected number of columns of the matrix to be equal to the vector "
    957           "size: MatrixTimesVector"));
    958 }
    959 
    960 TEST_F(ValidateArithmetics, MatrixTimesMatrix22x22Success) {
    961   const std::string body = R"(
    962 %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f32mat22_1212
    963 )";
    964 
    965   CompileSuccessfully(GenerateCode(body).c_str());
    966   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    967 }
    968 
    969 TEST_F(ValidateArithmetics, MatrixTimesMatrix23x32Success) {
    970   const std::string body = R"(
    971 %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat32_123123
    972 )";
    973 
    974   CompileSuccessfully(GenerateCode(body).c_str());
    975   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    976 }
    977 
    978 TEST_F(ValidateArithmetics, MatrixTimesMatrix33x33Success) {
    979   const std::string body = R"(
    980 %val = OpMatrixTimesMatrix %f32mat33 %f32mat33_123123123 %f32mat33_123123123
    981 )";
    982 
    983   CompileSuccessfully(GenerateCode(body).c_str());
    984   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    985 }
    986 
    987 TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongTypeId) {
    988   const std::string body = R"(
    989 %val = OpMatrixTimesMatrix %f32vec2 %f32mat22_1212 %f32mat22_1212
    990 )";
    991 
    992   CompileSuccessfully(GenerateCode(body).c_str());
    993   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    994   EXPECT_THAT(
    995       getDiagnosticString(),
    996       HasSubstr(
    997           "Expected float matrix type as Result Type: MatrixTimesMatrix"));
    998 }
    999 
   1000 TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongLeftOperand) {
   1001   const std::string body = R"(
   1002 %val = OpMatrixTimesMatrix %f32mat22 %f32vec2_12 %f32mat22_1212
   1003 )";
   1004 
   1005   CompileSuccessfully(GenerateCode(body).c_str());
   1006   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1007   EXPECT_THAT(
   1008       getDiagnosticString(),
   1009       HasSubstr(
   1010           "Expected float matrix type as left operand: MatrixTimesMatrix"));
   1011 }
   1012 
   1013 TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongRightOperand) {
   1014   const std::string body = R"(
   1015 %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f32vec2_12
   1016 )";
   1017 
   1018   CompileSuccessfully(GenerateCode(body).c_str());
   1019   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1020   EXPECT_THAT(
   1021       getDiagnosticString(),
   1022       HasSubstr(
   1023           "Expected float matrix type as right operand: MatrixTimesMatrix"));
   1024 }
   1025 
   1026 TEST_F(ValidateArithmetics, MatrixTimesMatrix32x23Fail) {
   1027   const std::string body = R"(
   1028 %val = OpMatrixTimesMatrix %f32mat22 %f32mat32_123123 %f32mat23_121212
   1029 )";
   1030 
   1031   CompileSuccessfully(GenerateCode(body).c_str());
   1032   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1033   EXPECT_THAT(
   1034       getDiagnosticString(),
   1035       HasSubstr(
   1036           "Expected column types of Result Type and left matrix to be equal: "
   1037           "MatrixTimesMatrix"));
   1038 }
   1039 
   1040 TEST_F(ValidateArithmetics, MatrixTimesMatrixDifferentComponents) {
   1041   const std::string body = R"(
   1042 %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f64mat22_1212
   1043 )";
   1044 
   1045   CompileSuccessfully(GenerateCode(body).c_str());
   1046   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1047   EXPECT_THAT(getDiagnosticString(),
   1048               HasSubstr("Expected component types of Result Type and right "
   1049                         "matrix to be equal: "
   1050                         "MatrixTimesMatrix"));
   1051 }
   1052 
   1053 TEST_F(ValidateArithmetics, MatrixTimesMatrix23x23Fail) {
   1054   const std::string body = R"(
   1055 %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat23_121212
   1056 )";
   1057 
   1058   CompileSuccessfully(GenerateCode(body).c_str());
   1059   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1060   EXPECT_THAT(getDiagnosticString(),
   1061               HasSubstr("Expected number of columns of Result Type and right "
   1062                         "matrix to be equal: "
   1063                         "MatrixTimesMatrix"));
   1064 }
   1065 
   1066 TEST_F(ValidateArithmetics, MatrixTimesMatrix23x22Fail) {
   1067   const std::string body = R"(
   1068 %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat22_1212
   1069 )";
   1070 
   1071   CompileSuccessfully(GenerateCode(body).c_str());
   1072   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1073   EXPECT_THAT(getDiagnosticString(),
   1074               HasSubstr("Expected number of columns of left matrix and number "
   1075                         "of rows of right "
   1076                         "matrix to be equal: MatrixTimesMatrix"));
   1077 }
   1078 
   1079 TEST_F(ValidateArithmetics, OuterProduct2x2Success) {
   1080   const std::string body = R"(
   1081 %val = OpOuterProduct %f32mat22 %f32vec2_12 %f32vec2_01
   1082 )";
   1083 
   1084   CompileSuccessfully(GenerateCode(body).c_str());
   1085   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1086 }
   1087 
   1088 TEST_F(ValidateArithmetics, OuterProduct3x2Success) {
   1089   const std::string body = R"(
   1090 %val = OpOuterProduct %f32mat32 %f32vec3_123 %f32vec2_01
   1091 )";
   1092 
   1093   CompileSuccessfully(GenerateCode(body).c_str());
   1094   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1095 }
   1096 
   1097 TEST_F(ValidateArithmetics, OuterProduct2x3Success) {
   1098   const std::string body = R"(
   1099 %val = OpOuterProduct %f32mat23 %f32vec2_01 %f32vec3_123
   1100 )";
   1101 
   1102   CompileSuccessfully(GenerateCode(body).c_str());
   1103   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1104 }
   1105 
   1106 TEST_F(ValidateArithmetics, OuterProductWrongTypeId) {
   1107   const std::string body = R"(
   1108 %val = OpOuterProduct %f32vec2 %f32vec2_01 %f32vec3_123
   1109 )";
   1110 
   1111   CompileSuccessfully(GenerateCode(body).c_str());
   1112   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1113   EXPECT_THAT(getDiagnosticString(),
   1114               HasSubstr("Expected float matrix type as Result Type: "
   1115                         "OuterProduct"));
   1116 }
   1117 
   1118 TEST_F(ValidateArithmetics, OuterProductWrongLeftOperand) {
   1119   const std::string body = R"(
   1120 %val = OpOuterProduct %f32mat22 %f32vec3_123 %f32vec2_01
   1121 )";
   1122 
   1123   CompileSuccessfully(GenerateCode(body).c_str());
   1124   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1125   EXPECT_THAT(
   1126       getDiagnosticString(),
   1127       HasSubstr("Expected column type of Result Type to be equal to the type "
   1128                 "of the left operand: OuterProduct"));
   1129 }
   1130 
   1131 TEST_F(ValidateArithmetics, OuterProductRightOperandNotFloatVector) {
   1132   const std::string body = R"(
   1133 %val = OpOuterProduct %f32mat22 %f32vec2_12 %u32vec2_01
   1134 )";
   1135 
   1136   CompileSuccessfully(GenerateCode(body).c_str());
   1137   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1138   EXPECT_THAT(
   1139       getDiagnosticString(),
   1140       HasSubstr("Expected float vector type as right operand: OuterProduct"));
   1141 }
   1142 
   1143 TEST_F(ValidateArithmetics, OuterProductRightOperandWrongComponent) {
   1144   const std::string body = R"(
   1145 %val = OpOuterProduct %f32mat22 %f32vec2_12 %f64vec2_01
   1146 )";
   1147 
   1148   CompileSuccessfully(GenerateCode(body).c_str());
   1149   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1150   EXPECT_THAT(getDiagnosticString(),
   1151               HasSubstr("Expected component types of the operands to be equal: "
   1152                         "OuterProduct"));
   1153 }
   1154 
   1155 TEST_F(ValidateArithmetics, OuterProductRightOperandWrongDimension) {
   1156   const std::string body = R"(
   1157 %val = OpOuterProduct %f32mat22 %f32vec2_12 %f32vec3_123
   1158 )";
   1159 
   1160   CompileSuccessfully(GenerateCode(body).c_str());
   1161   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1162   EXPECT_THAT(
   1163       getDiagnosticString(),
   1164       HasSubstr("Expected number of columns of the matrix to be equal to the "
   1165                 "vector size of the right operand: OuterProduct"));
   1166 }
   1167 
   1168 TEST_F(ValidateArithmetics, IAddCarrySuccess) {
   1169   const std::string body = R"(
   1170 %val1 = OpIAddCarry %struct_u32_u32 %u32_0 %u32_1
   1171 %val2 = OpIAddCarry %struct_u32vec2_u32vec2 %u32vec2_01 %u32vec2_12
   1172 )";
   1173 
   1174   CompileSuccessfully(GenerateCode(body).c_str());
   1175   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1176 }
   1177 
   1178 TEST_F(ValidateArithmetics, IAddCarryResultTypeNotStruct) {
   1179   const std::string body = R"(
   1180 %val = OpIAddCarry %u32 %u32_0 %u32_1
   1181 )";
   1182 
   1183   CompileSuccessfully(GenerateCode(body).c_str());
   1184   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1185   EXPECT_THAT(getDiagnosticString(),
   1186               HasSubstr("Expected a struct as Result Type: IAddCarry"));
   1187 }
   1188 
   1189 TEST_F(ValidateArithmetics, IAddCarryResultTypeNotTwoMembers) {
   1190   const std::string body = R"(
   1191 %val = OpIAddCarry %struct_u32_u32_u32 %u32_0 %u32_1
   1192 )";
   1193 
   1194   CompileSuccessfully(GenerateCode(body).c_str());
   1195   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1196   EXPECT_THAT(
   1197       getDiagnosticString(),
   1198       HasSubstr("Expected Result Type struct to have two members: IAddCarry"));
   1199 }
   1200 
   1201 TEST_F(ValidateArithmetics, IAddCarryResultTypeMemberNotUnsignedInt) {
   1202   const std::string body = R"(
   1203 %val = OpIAddCarry %struct_s32_s32 %s32_0 %s32_1
   1204 )";
   1205 
   1206   CompileSuccessfully(GenerateCode(body).c_str());
   1207   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1208   EXPECT_THAT(getDiagnosticString(),
   1209               HasSubstr("Expected Result Type struct member types to be "
   1210                         "unsigned integer scalar "
   1211                         "or vector: IAddCarry"));
   1212 }
   1213 
   1214 TEST_F(ValidateArithmetics, IAddCarryWrongLeftOperand) {
   1215   const std::string body = R"(
   1216 %val = OpIAddCarry %struct_u32_u32 %s32_0 %u32_1
   1217 )";
   1218 
   1219   CompileSuccessfully(GenerateCode(body).c_str());
   1220   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1221   EXPECT_THAT(getDiagnosticString(),
   1222               HasSubstr("Expected both operands to be of Result Type member "
   1223                         "type: IAddCarry"));
   1224 }
   1225 
   1226 TEST_F(ValidateArithmetics, IAddCarryWrongRightOperand) {
   1227   const std::string body = R"(
   1228 %val = OpIAddCarry %struct_u32_u32 %u32_0 %s32_1
   1229 )";
   1230 
   1231   CompileSuccessfully(GenerateCode(body).c_str());
   1232   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1233   EXPECT_THAT(getDiagnosticString(),
   1234               HasSubstr("Expected both operands to be of Result Type member "
   1235                         "type: IAddCarry"));
   1236 }
   1237 
   1238 TEST_F(ValidateArithmetics, OpSMulExtendedSuccess) {
   1239   const std::string body = R"(
   1240 %val1 = OpSMulExtended %struct_u32_u32 %u32_0 %u32_1
   1241 %val2 = OpSMulExtended %struct_s32_s32 %s32_0 %s32_1
   1242 %val3 = OpSMulExtended %struct_u32vec2_u32vec2 %u32vec2_01 %u32vec2_12
   1243 %val4 = OpSMulExtended %struct_s32vec2_s32vec2 %s32vec2_01 %s32vec2_12
   1244 )";
   1245 
   1246   CompileSuccessfully(GenerateCode(body).c_str());
   1247   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1248 }
   1249 
   1250 TEST_F(ValidateArithmetics, SMulExtendedResultTypeMemberNotInt) {
   1251   const std::string body = R"(
   1252 %val = OpSMulExtended %struct_f32_f32 %f32_0 %f32_1
   1253 )";
   1254 
   1255   CompileSuccessfully(GenerateCode(body).c_str());
   1256   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1257   EXPECT_THAT(
   1258       getDiagnosticString(),
   1259       HasSubstr("Expected Result Type struct member types to be integer scalar "
   1260                 "or vector: SMulExtended"));
   1261 }
   1262 
   1263 TEST_F(ValidateArithmetics, SMulExtendedResultTypeMembersNotIdentical) {
   1264   const std::string body = R"(
   1265 %val = OpSMulExtended %struct_s32_u32 %s32_0 %s32_1
   1266 )";
   1267 
   1268   CompileSuccessfully(GenerateCode(body).c_str());
   1269   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1270   EXPECT_THAT(
   1271       getDiagnosticString(),
   1272       HasSubstr("Expected Result Type struct member types to be identical: "
   1273                 "SMulExtended"));
   1274 }
   1275 
   1276 }  // namespace
   1277 }  // namespace val
   1278 }  // namespace spvtools
   1279