Home | History | Annotate | Download | only in comp
      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 <functional>
     18 #include <memory>
     19 #include <string>
     20 #include <vector>
     21 
     22 #include "gmock/gmock.h"
     23 #include "source/comp/markv.h"
     24 #include "test/test_fixture.h"
     25 #include "test/unit_spirv.h"
     26 #include "tools/comp/markv_model_factory.h"
     27 
     28 namespace spvtools {
     29 namespace comp {
     30 namespace {
     31 
     32 using spvtest::ScopedContext;
     33 using MarkvTest = ::testing::TestWithParam<MarkvModelType>;
     34 
     35 void DiagnosticsMessageHandler(spv_message_level_t level, const char*,
     36                                const spv_position_t& position,
     37                                const char* message) {
     38   switch (level) {
     39     case SPV_MSG_FATAL:
     40     case SPV_MSG_INTERNAL_ERROR:
     41     case SPV_MSG_ERROR:
     42       std::cerr << "error: " << position.index << ": " << message << std::endl;
     43       break;
     44     case SPV_MSG_WARNING:
     45       std::cout << "warning: " << position.index << ": " << message
     46                 << std::endl;
     47       break;
     48     case SPV_MSG_INFO:
     49       std::cout << "info: " << position.index << ": " << message << std::endl;
     50       break;
     51     default:
     52       break;
     53   }
     54 }
     55 
     56 // Compiles |code| to SPIR-V |words|.
     57 void Compile(const std::string& code, std::vector<uint32_t>* words,
     58              uint32_t options = SPV_TEXT_TO_BINARY_OPTION_NONE,
     59              spv_target_env env = SPV_ENV_UNIVERSAL_1_2) {
     60   spvtools::Context ctx(env);
     61   ctx.SetMessageConsumer(DiagnosticsMessageHandler);
     62 
     63   spv_binary spirv_binary;
     64   ASSERT_EQ(SPV_SUCCESS, spvTextToBinaryWithOptions(
     65                              ctx.CContext(), code.c_str(), code.size(), options,
     66                              &spirv_binary, nullptr));
     67 
     68   *words = std::vector<uint32_t>(spirv_binary->code,
     69                                  spirv_binary->code + spirv_binary->wordCount);
     70 
     71   spvBinaryDestroy(spirv_binary);
     72 }
     73 
     74 // Disassembles SPIR-V |words| to |out_text|.
     75 void Disassemble(const std::vector<uint32_t>& words, std::string* out_text,
     76                  spv_target_env env = SPV_ENV_UNIVERSAL_1_2) {
     77   spvtools::Context ctx(env);
     78   ctx.SetMessageConsumer(DiagnosticsMessageHandler);
     79 
     80   spv_text text = nullptr;
     81   ASSERT_EQ(SPV_SUCCESS, spvBinaryToText(ctx.CContext(), words.data(),
     82                                          words.size(), 0, &text, nullptr));
     83   assert(text);
     84 
     85   *out_text = std::string(text->str, text->length);
     86   spvTextDestroy(text);
     87 }
     88 
     89 // Encodes/decodes |original|, assembles/dissasembles |original|, then compares
     90 // the results of the two operations.
     91 void TestEncodeDecode(MarkvModelType model_type,
     92                       const std::string& original_text) {
     93   spvtools::Context ctx(SPV_ENV_UNIVERSAL_1_2);
     94   std::unique_ptr<MarkvModel> model = CreateMarkvModel(model_type);
     95   MarkvCodecOptions options;
     96 
     97   std::vector<uint32_t> expected_binary;
     98   Compile(original_text, &expected_binary);
     99   ASSERT_FALSE(expected_binary.empty());
    100 
    101   std::string expected_text;
    102   Disassemble(expected_binary, &expected_text);
    103   ASSERT_FALSE(expected_text.empty());
    104 
    105   std::vector<uint32_t> binary_to_encode;
    106   Compile(original_text, &binary_to_encode,
    107           SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    108   ASSERT_FALSE(binary_to_encode.empty());
    109 
    110   std::stringstream encoder_comments;
    111   const auto output_to_string_stream =
    112       [&encoder_comments](const std::string& str) { encoder_comments << str; };
    113 
    114   std::vector<uint8_t> markv;
    115   ASSERT_EQ(SPV_SUCCESS,
    116             SpirvToMarkv(ctx.CContext(), binary_to_encode, options, *model,
    117                          DiagnosticsMessageHandler, output_to_string_stream,
    118                          MarkvDebugConsumer(), &markv));
    119   ASSERT_FALSE(markv.empty());
    120 
    121   std::vector<uint32_t> decoded_binary;
    122   ASSERT_EQ(SPV_SUCCESS,
    123             MarkvToSpirv(ctx.CContext(), markv, options, *model,
    124                          DiagnosticsMessageHandler, MarkvLogConsumer(),
    125                          MarkvDebugConsumer(), &decoded_binary));
    126   ASSERT_FALSE(decoded_binary.empty());
    127 
    128   EXPECT_EQ(expected_binary, decoded_binary) << encoder_comments.str();
    129 
    130   std::string decoded_text;
    131   Disassemble(decoded_binary, &decoded_text);
    132   ASSERT_FALSE(decoded_text.empty());
    133 
    134   EXPECT_EQ(expected_text, decoded_text) << encoder_comments.str();
    135 }
    136 
    137 void TestEncodeDecodeShaderMainBody(MarkvModelType model_type,
    138                                     const std::string& body) {
    139   const std::string prefix =
    140       R"(
    141 OpCapability Shader
    142 OpCapability Int64
    143 OpCapability Float64
    144 %ext_inst = OpExtInstImport "GLSL.std.450"
    145 OpMemoryModel Logical GLSL450
    146 OpEntryPoint Fragment %main "main"
    147 %void = OpTypeVoid
    148 %func = OpTypeFunction %void
    149 %bool = OpTypeBool
    150 %f32 = OpTypeFloat 32
    151 %u32 = OpTypeInt 32 0
    152 %s32 = OpTypeInt 32 1
    153 %f64 = OpTypeFloat 64
    154 %u64 = OpTypeInt 64 0
    155 %s64 = OpTypeInt 64 1
    156 %boolvec2 = OpTypeVector %bool 2
    157 %s32vec2 = OpTypeVector %s32 2
    158 %u32vec2 = OpTypeVector %u32 2
    159 %f32vec2 = OpTypeVector %f32 2
    160 %f64vec2 = OpTypeVector %f64 2
    161 %boolvec3 = OpTypeVector %bool 3
    162 %u32vec3 = OpTypeVector %u32 3
    163 %s32vec3 = OpTypeVector %s32 3
    164 %f32vec3 = OpTypeVector %f32 3
    165 %f64vec3 = OpTypeVector %f64 3
    166 %boolvec4 = OpTypeVector %bool 4
    167 %u32vec4 = OpTypeVector %u32 4
    168 %s32vec4 = OpTypeVector %s32 4
    169 %f32vec4 = OpTypeVector %f32 4
    170 %f64vec4 = OpTypeVector %f64 4
    171 
    172 %f32_0 = OpConstant %f32 0
    173 %f32_1 = OpConstant %f32 1
    174 %f32_2 = OpConstant %f32 2
    175 %f32_3 = OpConstant %f32 3
    176 %f32_4 = OpConstant %f32 4
    177 %f32_pi = OpConstant %f32 3.14159
    178 
    179 %s32_0 = OpConstant %s32 0
    180 %s32_1 = OpConstant %s32 1
    181 %s32_2 = OpConstant %s32 2
    182 %s32_3 = OpConstant %s32 3
    183 %s32_4 = OpConstant %s32 4
    184 %s32_m1 = OpConstant %s32 -1
    185 
    186 %u32_0 = OpConstant %u32 0
    187 %u32_1 = OpConstant %u32 1
    188 %u32_2 = OpConstant %u32 2
    189 %u32_3 = OpConstant %u32 3
    190 %u32_4 = OpConstant %u32 4
    191 
    192 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
    193 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
    194 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
    195 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
    196 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
    197 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
    198 
    199 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
    200 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
    201 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
    202 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
    203 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
    204 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
    205 
    206 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
    207 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
    208 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
    209 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
    210 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
    211 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
    212 
    213 %main = OpFunction %void None %func
    214 %main_entry = OpLabel)";
    215 
    216   const std::string suffix =
    217       R"(
    218 OpReturn
    219 OpFunctionEnd)";
    220 
    221   TestEncodeDecode(model_type, prefix + body + suffix);
    222 }
    223 
    224 TEST_P(MarkvTest, U32Literal) {
    225   TestEncodeDecode(GetParam(), R"(
    226 OpCapability Shader
    227 OpCapability Linkage
    228 OpMemoryModel Logical GLSL450
    229 %u32 = OpTypeInt 32 0
    230 %100 = OpConstant %u32 0
    231 %200 = OpConstant %u32 1
    232 %300 = OpConstant %u32 4294967295
    233 )");
    234 }
    235 
    236 TEST_P(MarkvTest, S32Literal) {
    237   TestEncodeDecode(GetParam(), R"(
    238 OpCapability Shader
    239 OpCapability Linkage
    240 OpMemoryModel Logical GLSL450
    241 %s32 = OpTypeInt 32 1
    242 %100 = OpConstant %s32 0
    243 %200 = OpConstant %s32 1
    244 %300 = OpConstant %s32 -1
    245 %400 = OpConstant %s32 2147483647
    246 %500 = OpConstant %s32 -2147483648
    247 )");
    248 }
    249 
    250 TEST_P(MarkvTest, U64Literal) {
    251   TestEncodeDecode(GetParam(), R"(
    252 OpCapability Shader
    253 OpCapability Linkage
    254 OpCapability Int64
    255 OpMemoryModel Logical GLSL450
    256 %u64 = OpTypeInt 64 0
    257 %100 = OpConstant %u64 0
    258 %200 = OpConstant %u64 1
    259 %300 = OpConstant %u64 18446744073709551615
    260 )");
    261 }
    262 
    263 TEST_P(MarkvTest, S64Literal) {
    264   TestEncodeDecode(GetParam(), R"(
    265 OpCapability Shader
    266 OpCapability Linkage
    267 OpCapability Int64
    268 OpMemoryModel Logical GLSL450
    269 %s64 = OpTypeInt 64 1
    270 %100 = OpConstant %s64 0
    271 %200 = OpConstant %s64 1
    272 %300 = OpConstant %s64 -1
    273 %400 = OpConstant %s64 9223372036854775807
    274 %500 = OpConstant %s64 -9223372036854775808
    275 )");
    276 }
    277 
    278 TEST_P(MarkvTest, U16Literal) {
    279   TestEncodeDecode(GetParam(), R"(
    280 OpCapability Shader
    281 OpCapability Linkage
    282 OpCapability Int16
    283 OpMemoryModel Logical GLSL450
    284 %u16 = OpTypeInt 16 0
    285 %100 = OpConstant %u16 0
    286 %200 = OpConstant %u16 1
    287 %300 = OpConstant %u16 65535
    288 )");
    289 }
    290 
    291 TEST_P(MarkvTest, S16Literal) {
    292   TestEncodeDecode(GetParam(), R"(
    293 OpCapability Shader
    294 OpCapability Linkage
    295 OpCapability Int16
    296 OpMemoryModel Logical GLSL450
    297 %s16 = OpTypeInt 16 1
    298 %100 = OpConstant %s16 0
    299 %200 = OpConstant %s16 1
    300 %300 = OpConstant %s16 -1
    301 %400 = OpConstant %s16 32767
    302 %500 = OpConstant %s16 -32768
    303 )");
    304 }
    305 
    306 TEST_P(MarkvTest, F32Literal) {
    307   TestEncodeDecode(GetParam(), R"(
    308 OpCapability Shader
    309 OpCapability Linkage
    310 OpMemoryModel Logical GLSL450
    311 %f32 = OpTypeFloat 32
    312 %100 = OpConstant %f32 0
    313 %200 = OpConstant %f32 1
    314 %300 = OpConstant %f32 0.1
    315 %400 = OpConstant %f32 -0.1
    316 )");
    317 }
    318 
    319 TEST_P(MarkvTest, F64Literal) {
    320   TestEncodeDecode(GetParam(), R"(
    321 OpCapability Shader
    322 OpCapability Linkage
    323 OpCapability Float64
    324 OpMemoryModel Logical GLSL450
    325 %f64 = OpTypeFloat 64
    326 %100 = OpConstant %f64 0
    327 %200 = OpConstant %f64 1
    328 %300 = OpConstant %f64 0.1
    329 %400 = OpConstant %f64 -0.1
    330 )");
    331 }
    332 
    333 TEST_P(MarkvTest, F16Literal) {
    334   TestEncodeDecode(GetParam(), R"(
    335 OpCapability Shader
    336 OpCapability Linkage
    337 OpCapability Float16
    338 OpMemoryModel Logical GLSL450
    339 %f16 = OpTypeFloat 16
    340 %100 = OpConstant %f16 0
    341 %200 = OpConstant %f16 1
    342 %300 = OpConstant %f16 0.1
    343 %400 = OpConstant %f16 -0.1
    344 )");
    345 }
    346 
    347 TEST_P(MarkvTest, StringLiteral) {
    348   TestEncodeDecode(GetParam(), R"(
    349 OpCapability Shader
    350 OpCapability Linkage
    351 OpExtension "SPV_KHR_16bit_storage"
    352 OpExtension "xxx"
    353 OpExtension "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    354 OpExtension ""
    355 OpMemoryModel Logical GLSL450
    356 )");
    357 }
    358 
    359 TEST_P(MarkvTest, WithFunction) {
    360   TestEncodeDecode(GetParam(), R"(
    361 OpCapability Addresses
    362 OpCapability Kernel
    363 OpCapability GenericPointer
    364 OpCapability Linkage
    365 OpExtension "SPV_KHR_16bit_storage"
    366 OpMemoryModel Physical32 OpenCL
    367 %f32 = OpTypeFloat 32
    368 %u32 = OpTypeInt 32 0
    369 %void = OpTypeVoid
    370 %void_func = OpTypeFunction %void
    371 %100 = OpConstant %u32 1
    372 %200 = OpConstant %u32 2
    373 %main = OpFunction %void None %void_func
    374 %entry_main = OpLabel
    375 %300 = OpIAdd %u32 %100 %200
    376 OpReturn
    377 OpFunctionEnd
    378 )");
    379 }
    380 
    381 TEST_P(MarkvTest, WithMultipleFunctions) {
    382   TestEncodeDecode(GetParam(), R"(
    383 OpCapability Addresses
    384 OpCapability Kernel
    385 OpCapability GenericPointer
    386 OpCapability Linkage
    387 OpMemoryModel Physical32 OpenCL
    388 %f32 = OpTypeFloat 32
    389 %one = OpConstant %f32 1
    390 %void = OpTypeVoid
    391 %void_func = OpTypeFunction %void
    392 %f32_func = OpTypeFunction %f32 %f32
    393 %sqr_plus_one = OpFunction %f32 None %f32_func
    394 %x = OpFunctionParameter %f32
    395 %100 = OpLabel
    396 %x2 = OpFMul %f32 %x %x
    397 %x2p1 = OpFunctionCall %f32 %plus_one %x2
    398 OpReturnValue %x2p1
    399 OpFunctionEnd
    400 %plus_one = OpFunction %f32 None %f32_func
    401 %y = OpFunctionParameter %f32
    402 %200 = OpLabel
    403 %yp1 = OpFAdd %f32 %y %one
    404 OpReturnValue %yp1
    405 OpFunctionEnd
    406 %main = OpFunction %void None %void_func
    407 %entry_main = OpLabel
    408 %1p1 = OpFunctionCall %f32 %sqr_plus_one %one
    409 OpReturn
    410 OpFunctionEnd
    411 )");
    412 }
    413 
    414 TEST_P(MarkvTest, ForwardDeclaredId) {
    415   TestEncodeDecode(GetParam(), R"(
    416 OpCapability Addresses
    417 OpCapability Kernel
    418 OpCapability GenericPointer
    419 OpCapability Linkage
    420 OpMemoryModel Physical32 OpenCL
    421 OpEntryPoint Kernel %1 "simple_kernel"
    422 %2 = OpTypeInt 32 0
    423 %3 = OpTypeVector %2 2
    424 %4 = OpConstant %2 2
    425 %5 = OpTypeArray %2 %4
    426 %6 = OpTypeVoid
    427 %7 = OpTypeFunction %6
    428 %1 = OpFunction %6 None %7
    429 %8 = OpLabel
    430 OpReturn
    431 OpFunctionEnd
    432 )");
    433 }
    434 
    435 TEST_P(MarkvTest, WithSwitch) {
    436   TestEncodeDecode(GetParam(), R"(
    437 OpCapability Addresses
    438 OpCapability Kernel
    439 OpCapability GenericPointer
    440 OpCapability Linkage
    441 OpCapability Int64
    442 OpMemoryModel Physical32 OpenCL
    443 %u64 = OpTypeInt 64 0
    444 %void = OpTypeVoid
    445 %void_func = OpTypeFunction %void
    446 %val = OpConstant %u64 1
    447 %main = OpFunction %void None %void_func
    448 %entry_main = OpLabel
    449 OpSwitch %val %default 1 %case1 1000000000000 %case2
    450 %case1 = OpLabel
    451 OpNop
    452 OpBranch %after_switch
    453 %case2 = OpLabel
    454 OpNop
    455 OpBranch %after_switch
    456 %default = OpLabel
    457 OpNop
    458 OpBranch %after_switch
    459 %after_switch = OpLabel
    460 OpReturn
    461 OpFunctionEnd
    462 )");
    463 }
    464 
    465 TEST_P(MarkvTest, WithLoop) {
    466   TestEncodeDecode(GetParam(), R"(
    467 OpCapability Addresses
    468 OpCapability Kernel
    469 OpCapability GenericPointer
    470 OpCapability Linkage
    471 OpMemoryModel Physical32 OpenCL
    472 %void = OpTypeVoid
    473 %void_func = OpTypeFunction %void
    474 %main = OpFunction %void None %void_func
    475 %entry_main = OpLabel
    476 OpLoopMerge %merge %continue DontUnroll|DependencyLength 10
    477 OpBranch %begin_loop
    478 %begin_loop = OpLabel
    479 OpNop
    480 OpBranch %continue
    481 %continue = OpLabel
    482 OpNop
    483 OpBranch %begin_loop
    484 %merge = OpLabel
    485 OpReturn
    486 OpFunctionEnd
    487 )");
    488 }
    489 
    490 TEST_P(MarkvTest, WithDecorate) {
    491   TestEncodeDecode(GetParam(), R"(
    492 OpCapability Shader
    493 OpCapability Linkage
    494 OpMemoryModel Logical GLSL450
    495 OpDecorate %1 ArrayStride 4
    496 OpDecorate %1 Uniform
    497 %2 = OpTypeFloat 32
    498 %1 = OpTypeRuntimeArray %2
    499 )");
    500 }
    501 
    502 TEST_P(MarkvTest, WithExtInst) {
    503   TestEncodeDecode(GetParam(), R"(
    504 OpCapability Addresses
    505 OpCapability Kernel
    506 OpCapability GenericPointer
    507 OpCapability Linkage
    508 %opencl = OpExtInstImport "OpenCL.std"
    509 OpMemoryModel Physical32 OpenCL
    510 %f32 = OpTypeFloat 32
    511 %void = OpTypeVoid
    512 %void_func = OpTypeFunction %void
    513 %100 = OpConstant %f32 1.1
    514 %main = OpFunction %void None %void_func
    515 %entry_main = OpLabel
    516 %200 = OpExtInst %f32 %opencl cos %100
    517 OpReturn
    518 OpFunctionEnd
    519 )");
    520 }
    521 
    522 TEST_P(MarkvTest, F32Mul) {
    523   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    524 %val1 = OpFMul %f32 %f32_0 %f32_1
    525 %val2 = OpFMul %f32 %f32_2 %f32_0
    526 %val3 = OpFMul %f32 %f32_pi %f32_2
    527 %val4 = OpFMul %f32 %f32_1 %f32_1
    528 )");
    529 }
    530 
    531 TEST_P(MarkvTest, U32Mul) {
    532   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    533 %val1 = OpIMul %u32 %u32_0 %u32_1
    534 %val2 = OpIMul %u32 %u32_2 %u32_0
    535 %val3 = OpIMul %u32 %u32_3 %u32_2
    536 %val4 = OpIMul %u32 %u32_1 %u32_1
    537 )");
    538 }
    539 
    540 TEST_P(MarkvTest, S32Mul) {
    541   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    542 %val1 = OpIMul %s32 %s32_0 %s32_1
    543 %val2 = OpIMul %s32 %s32_2 %s32_0
    544 %val3 = OpIMul %s32 %s32_m1 %s32_2
    545 %val4 = OpIMul %s32 %s32_1 %s32_1
    546 )");
    547 }
    548 
    549 TEST_P(MarkvTest, F32Add) {
    550   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    551 %val1 = OpFAdd %f32 %f32_0 %f32_1
    552 %val2 = OpFAdd %f32 %f32_2 %f32_0
    553 %val3 = OpFAdd %f32 %f32_pi %f32_2
    554 %val4 = OpFAdd %f32 %f32_1 %f32_1
    555 )");
    556 }
    557 
    558 TEST_P(MarkvTest, U32Add) {
    559   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    560 %val1 = OpIAdd %u32 %u32_0 %u32_1
    561 %val2 = OpIAdd %u32 %u32_2 %u32_0
    562 %val3 = OpIAdd %u32 %u32_3 %u32_2
    563 %val4 = OpIAdd %u32 %u32_1 %u32_1
    564 )");
    565 }
    566 
    567 TEST_P(MarkvTest, S32Add) {
    568   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    569 %val1 = OpIAdd %s32 %s32_0 %s32_1
    570 %val2 = OpIAdd %s32 %s32_2 %s32_0
    571 %val3 = OpIAdd %s32 %s32_m1 %s32_2
    572 %val4 = OpIAdd %s32 %s32_1 %s32_1
    573 )");
    574 }
    575 
    576 TEST_P(MarkvTest, F32Dot) {
    577   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    578 %dot2_1 = OpDot %f32 %f32vec2_01 %f32vec2_12
    579 %dot2_2 = OpDot %f32 %f32vec2_01 %f32vec2_01
    580 %dot2_3 = OpDot %f32 %f32vec2_12 %f32vec2_12
    581 %dot3_1 = OpDot %f32 %f32vec3_012 %f32vec3_123
    582 %dot3_2 = OpDot %f32 %f32vec3_012 %f32vec3_012
    583 %dot3_3 = OpDot %f32 %f32vec3_123 %f32vec3_123
    584 %dot4_1 = OpDot %f32 %f32vec4_0123 %f32vec4_1234
    585 %dot4_2 = OpDot %f32 %f32vec4_0123 %f32vec4_0123
    586 %dot4_3 = OpDot %f32 %f32vec4_1234 %f32vec4_1234
    587 )");
    588 }
    589 
    590 TEST_P(MarkvTest, F32VectorCompositeConstruct) {
    591   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    592 %cc1 = OpCompositeConstruct %f32vec4 %f32vec2_01 %f32vec2_12
    593 %cc2 = OpCompositeConstruct %f32vec3 %f32vec2_01 %f32_2
    594 %cc3 = OpCompositeConstruct %f32vec2 %f32_1 %f32_2
    595 %cc4 = OpCompositeConstruct %f32vec4 %f32_1 %f32_2 %cc3
    596 )");
    597 }
    598 
    599 TEST_P(MarkvTest, U32VectorCompositeConstruct) {
    600   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    601 %cc1 = OpCompositeConstruct %u32vec4 %u32vec2_01 %u32vec2_12
    602 %cc2 = OpCompositeConstruct %u32vec3 %u32vec2_01 %u32_2
    603 %cc3 = OpCompositeConstruct %u32vec2 %u32_1 %u32_2
    604 %cc4 = OpCompositeConstruct %u32vec4 %u32_1 %u32_2 %cc3
    605 )");
    606 }
    607 
    608 TEST_P(MarkvTest, S32VectorCompositeConstruct) {
    609   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    610 %cc1 = OpCompositeConstruct %u32vec4 %u32vec2_01 %u32vec2_12
    611 %cc2 = OpCompositeConstruct %u32vec3 %u32vec2_01 %u32_2
    612 %cc3 = OpCompositeConstruct %u32vec2 %u32_1 %u32_2
    613 %cc4 = OpCompositeConstruct %u32vec4 %u32_1 %u32_2 %cc3
    614 )");
    615 }
    616 
    617 TEST_P(MarkvTest, F32VectorCompositeExtract) {
    618   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    619 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
    620 %f32vec3_013 = OpCompositeExtract %f32vec3 %f32vec4_0123 0 1 3
    621 )");
    622 }
    623 
    624 TEST_P(MarkvTest, F32VectorComparison) {
    625   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    626 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
    627 %c1 = OpFOrdEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    628 %c2 = OpFUnordEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    629 %c3 = OpFOrdNotEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    630 %c4 = OpFUnordNotEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    631 %c5 = OpFOrdLessThan %boolvec4 %f32vec4_0123 %f32vec4_3210
    632 %c6 = OpFUnordLessThan %boolvec4 %f32vec4_0123 %f32vec4_3210
    633 %c7 = OpFOrdGreaterThan %boolvec4 %f32vec4_0123 %f32vec4_3210
    634 %c8 = OpFUnordGreaterThan %boolvec4 %f32vec4_0123 %f32vec4_3210
    635 %c9 = OpFOrdLessThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    636 %c10 = OpFUnordLessThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    637 %c11 = OpFOrdGreaterThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    638 %c12 = OpFUnordGreaterThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
    639 )");
    640 }
    641 
    642 TEST_P(MarkvTest, VectorShuffle) {
    643   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    644 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
    645 %sh1 = OpVectorShuffle %f32vec2 %f32vec4_0123 %f32vec4_3210 3 6
    646 %sh2 = OpVectorShuffle %f32vec3 %f32vec2_01 %f32vec4_3210 0 3 4
    647 )");
    648 }
    649 
    650 TEST_P(MarkvTest, VectorTimesScalar) {
    651   TestEncodeDecodeShaderMainBody(GetParam(), R"(
    652 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
    653 %res1 = OpVectorTimesScalar %f32vec4 %f32vec4_0123 %f32_2
    654 %res2 = OpVectorTimesScalar %f32vec4 %f32vec4_3210 %f32_2
    655 )");
    656 }
    657 
    658 TEST_P(MarkvTest, SpirvSpecSample) {
    659   TestEncodeDecode(GetParam(), R"(
    660                OpCapability Shader
    661           %1 = OpExtInstImport "GLSL.std.450"
    662                OpMemoryModel Logical GLSL450
    663                OpEntryPoint Fragment %4 "main" %31 %33 %42 %57
    664                OpExecutionMode %4 OriginLowerLeft
    665 
    666 ; Debug information
    667                OpSource GLSL 450
    668                OpName %4 "main"
    669                OpName %9 "scale"
    670                OpName %17 "S"
    671                OpMemberName %17 0 "b"
    672                OpMemberName %17 1 "v"
    673                OpMemberName %17 2 "i"
    674                OpName %18 "blockName"
    675                OpMemberName %18 0 "s"
    676                OpMemberName %18 1 "cond"
    677                OpName %20 ""
    678                OpName %31 "color"
    679                OpName %33 "color1"
    680                OpName %42 "color2"
    681                OpName %48 "i"
    682                OpName %57 "multiplier"
    683 
    684 ; Annotations (non-debug)
    685                OpDecorate %15 ArrayStride 16
    686                OpMemberDecorate %17 0 Offset 0
    687                OpMemberDecorate %17 1 Offset 16
    688                OpMemberDecorate %17 2 Offset 96
    689                OpMemberDecorate %18 0 Offset 0
    690                OpMemberDecorate %18 1 Offset 112
    691                OpDecorate %18 Block
    692                OpDecorate %20 DescriptorSet 0
    693                OpDecorate %42 NoPerspective
    694 
    695 ; All types, variables, and constants
    696           %2 = OpTypeVoid
    697           %3 = OpTypeFunction %2                      ; void ()
    698           %6 = OpTypeFloat 32                         ; 32-bit float
    699           %7 = OpTypeVector %6 4                      ; vec4
    700           %8 = OpTypePointer Function %7              ; function-local vec4*
    701          %10 = OpConstant %6 1
    702          %11 = OpConstant %6 2
    703          %12 = OpConstantComposite %7 %10 %10 %11 %10 ; vec4(1.0, 1.0, 2.0, 1.0)
    704          %13 = OpTypeInt 32 0                         ; 32-bit int, sign-less
    705          %14 = OpConstant %13 5
    706          %15 = OpTypeArray %7 %14
    707          %16 = OpTypeInt 32 1
    708          %17 = OpTypeStruct %13 %15 %16
    709          %18 = OpTypeStruct %17 %13
    710          %19 = OpTypePointer Uniform %18
    711          %20 = OpVariable %19 Uniform
    712          %21 = OpConstant %16 1
    713          %22 = OpTypePointer Uniform %13
    714          %25 = OpTypeBool
    715          %26 = OpConstant %13 0
    716          %30 = OpTypePointer Output %7
    717          %31 = OpVariable %30 Output
    718          %32 = OpTypePointer Input %7
    719          %33 = OpVariable %32 Input
    720          %35 = OpConstant %16 0
    721          %36 = OpConstant %16 2
    722          %37 = OpTypePointer Uniform %7
    723          %42 = OpVariable %32 Input
    724          %47 = OpTypePointer Function %16
    725          %55 = OpConstant %16 4
    726          %57 = OpVariable %32 Input
    727 
    728 ; All functions
    729           %4 = OpFunction %2 None %3                  ; main()
    730           %5 = OpLabel
    731           %9 = OpVariable %8 Function
    732          %48 = OpVariable %47 Function
    733                OpStore %9 %12
    734          %23 = OpAccessChain %22 %20 %21              ; location of cond
    735          %24 = OpLoad %13 %23                         ; load 32-bit int from cond
    736          %27 = OpINotEqual %25 %24 %26                ; convert to bool
    737                OpSelectionMerge %29 None              ; structured if
    738                OpBranchConditional %27 %28 %41        ; if cond
    739          %28 = OpLabel                                ; then
    740          %34 = OpLoad %7 %33
    741          %38 = OpAccessChain %37 %20 %35 %21 %36      ; s.v[2]
    742          %39 = OpLoad %7 %38
    743          %40 = OpFAdd %7 %34 %39
    744                OpStore %31 %40
    745                OpBranch %29
    746          %41 = OpLabel                                ; else
    747          %43 = OpLoad %7 %42
    748          %44 = OpExtInst %7 %1 Sqrt %43               ; extended instruction sqrt
    749          %45 = OpLoad %7 %9
    750          %46 = OpFMul %7 %44 %45
    751                OpStore %31 %46
    752                OpBranch %29
    753          %29 = OpLabel                                ; endif
    754                OpStore %48 %35
    755                OpBranch %49
    756          %49 = OpLabel
    757                OpLoopMerge %51 %52 None               ; structured loop
    758                OpBranch %53
    759          %53 = OpLabel
    760          %54 = OpLoad %16 %48
    761          %56 = OpSLessThan %25 %54 %55                ; i < 4 ?
    762                OpBranchConditional %56 %50 %51        ; body or break
    763          %50 = OpLabel                                ; body
    764          %58 = OpLoad %7 %57
    765          %59 = OpLoad %7 %31
    766          %60 = OpFMul %7 %59 %58
    767                OpStore %31 %60
    768                OpBranch %52
    769          %52 = OpLabel                                ; continue target
    770          %61 = OpLoad %16 %48
    771          %62 = OpIAdd %16 %61 %21                     ; ++i
    772                OpStore %48 %62
    773                OpBranch %49                           ; loop back
    774          %51 = OpLabel                                ; loop merge point
    775                OpReturn
    776                OpFunctionEnd
    777 )");
    778 }
    779 
    780 TEST_P(MarkvTest, SampleFromDeadBranchEliminationTest) {
    781   TestEncodeDecode(GetParam(), R"(
    782 OpCapability Shader
    783 %1 = OpExtInstImport "GLSL.std.450"
    784 OpMemoryModel Logical GLSL450
    785 OpEntryPoint Fragment %main "main" %gl_FragColor
    786 OpExecutionMode %main OriginUpperLeft
    787 OpSource GLSL 140
    788 OpName %main "main"
    789 OpName %gl_FragColor "gl_FragColor"
    790 %void = OpTypeVoid
    791 %5 = OpTypeFunction %void
    792 %bool = OpTypeBool
    793 %true = OpConstantTrue %bool
    794 %float = OpTypeFloat 32
    795 %v4float = OpTypeVector %float 4
    796 %_ptr_Function_v4float = OpTypePointer Function %v4float
    797 %float_0 = OpConstant %float 0
    798 %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
    799 %float_1 = OpConstant %float 1
    800 %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
    801 %_ptr_Output_v4float = OpTypePointer Output %v4float
    802 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
    803 %_ptr_Input_v4float = OpTypePointer Input %v4float
    804 %main = OpFunction %void None %5
    805 %17 = OpLabel
    806 OpSelectionMerge %18 None
    807 OpBranchConditional %true %19 %20
    808 %19 = OpLabel
    809 OpBranch %18
    810 %20 = OpLabel
    811 OpBranch %18
    812 %18 = OpLabel
    813 %21 = OpPhi %v4float %12 %19 %14 %20
    814 OpStore %gl_FragColor %21
    815 OpReturn
    816 OpFunctionEnd
    817 )");
    818 }
    819 
    820 INSTANTIATE_TEST_CASE_P(AllMarkvModels, MarkvTest,
    821                         ::testing::ValuesIn(std::vector<MarkvModelType>{
    822                             kMarkvModelShaderLite,
    823                             kMarkvModelShaderMid,
    824                             kMarkvModelShaderMax,
    825                         }), );
    826 
    827 }  // namespace
    828 }  // namespace comp
    829 }  // namespace spvtools
    830