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 validation rules of GLSL.450.std and OpenCL.std extended instructions.
     16 // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
     17 // by standard SPIR-V).
     18 
     19 #include <sstream>
     20 #include <string>
     21 #include <vector>
     22 
     23 #include "gmock/gmock.h"
     24 #include "test/unit_spirv.h"
     25 #include "test/val/val_fixtures.h"
     26 
     27 namespace spvtools {
     28 namespace val {
     29 namespace {
     30 
     31 using ::testing::Eq;
     32 using ::testing::HasSubstr;
     33 using ::testing::Not;
     34 
     35 using ValidateExtInst = spvtest::ValidateBase<bool>;
     36 using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>;
     37 using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>;
     38 using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>;
     39 using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>;
     40 using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>;
     41 using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>;
     42 using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>;
     43 using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>;
     44 using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>;
     45 using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>;
     46 using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>;
     47 using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>;
     48 using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>;
     49 using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>;
     50 using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>;
     51 using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>;
     52 using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>;
     53 using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>;
     54 using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>;
     55 using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>;
     56 using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>;
     57 using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>;
     58 using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>;
     59 using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>;
     60 using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>;
     61 using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>;
     62 using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>;
     63 
     64 // Returns number of components in Pack/Unpack extended instructions.
     65 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
     66 // Number of components is assumed to be single-digit.
     67 uint32_t GetPackedNumComponents(const std::string& ext_inst_name) {
     68   const size_t x_index = ext_inst_name.find_last_of('x');
     69   const std::string num_components_str =
     70       ext_inst_name.substr(x_index - 1, x_index);
     71   return uint32_t(std::stoul(num_components_str));
     72 }
     73 
     74 // Returns packed bit width in Pack/Unpack extended instructions.
     75 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
     76 uint32_t GetPackedBitWidth(const std::string& ext_inst_name) {
     77   const size_t x_index = ext_inst_name.find_last_of('x');
     78   const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1);
     79   return uint32_t(std::stoul(packed_bit_width_str));
     80 }
     81 
     82 std::string GenerateShaderCode(
     83     const std::string& body,
     84     const std::string& capabilities_and_extensions = "",
     85     const std::string& execution_model = "Fragment") {
     86   std::ostringstream ss;
     87   ss << R"(
     88 OpCapability Shader
     89 OpCapability Float16
     90 OpCapability Float64
     91 OpCapability Int16
     92 OpCapability Int64
     93 )";
     94 
     95   ss << capabilities_and_extensions;
     96   ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
     97   ss << "OpMemoryModel Logical GLSL450\n";
     98   ss << "OpEntryPoint " << execution_model << " %main \"main\""
     99      << " %f32_output"
    100      << " %f32vec2_output"
    101      << " %u32_output"
    102      << " %u32vec2_output"
    103      << " %u64_output"
    104      << " %f32_input"
    105      << " %f32vec2_input"
    106      << " %u32_input"
    107      << " %u32vec2_input"
    108      << " %u64_input"
    109      << "\n";
    110   if (execution_model == "Fragment") {
    111     ss << "OpExecutionMode %main OriginUpperLeft\n";
    112   }
    113 
    114   ss << R"(
    115 %void = OpTypeVoid
    116 %func = OpTypeFunction %void
    117 %bool = OpTypeBool
    118 %f16 = OpTypeFloat 16
    119 %f32 = OpTypeFloat 32
    120 %f64 = OpTypeFloat 64
    121 %u32 = OpTypeInt 32 0
    122 %s32 = OpTypeInt 32 1
    123 %u64 = OpTypeInt 64 0
    124 %s64 = OpTypeInt 64 1
    125 %u16 = OpTypeInt 16 0
    126 %s16 = OpTypeInt 16 1
    127 %f32vec2 = OpTypeVector %f32 2
    128 %f32vec3 = OpTypeVector %f32 3
    129 %f32vec4 = OpTypeVector %f32 4
    130 %f64vec2 = OpTypeVector %f64 2
    131 %f64vec3 = OpTypeVector %f64 3
    132 %f64vec4 = OpTypeVector %f64 4
    133 %u32vec2 = OpTypeVector %u32 2
    134 %u32vec3 = OpTypeVector %u32 3
    135 %s32vec2 = OpTypeVector %s32 2
    136 %u32vec4 = OpTypeVector %u32 4
    137 %s32vec4 = OpTypeVector %s32 4
    138 %u64vec2 = OpTypeVector %u64 2
    139 %s64vec2 = OpTypeVector %s64 2
    140 %f64mat22 = OpTypeMatrix %f64vec2 2
    141 %f32mat22 = OpTypeMatrix %f32vec2 2
    142 %f32mat23 = OpTypeMatrix %f32vec2 3
    143 %f32mat32 = OpTypeMatrix %f32vec3 2
    144 %f32mat33 = OpTypeMatrix %f32vec3 3
    145 
    146 %f32_0 = OpConstant %f32 0
    147 %f32_1 = OpConstant %f32 1
    148 %f32_2 = OpConstant %f32 2
    149 %f32_3 = OpConstant %f32 3
    150 %f32_4 = OpConstant %f32 4
    151 %f32_h = OpConstant %f32 0.5
    152 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
    153 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
    154 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
    155 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
    156 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
    157 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
    158 
    159 %f64_0 = OpConstant %f64 0
    160 %f64_1 = OpConstant %f64 1
    161 %f64_2 = OpConstant %f64 2
    162 %f64_3 = OpConstant %f64 3
    163 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
    164 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
    165 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
    166 
    167 %f16_0 = OpConstant %f16 0
    168 %f16_1 = OpConstant %f16 1
    169 %f16_h = OpConstant %f16 0.5
    170 
    171 %u32_0 = OpConstant %u32 0
    172 %u32_1 = OpConstant %u32 1
    173 %u32_2 = OpConstant %u32 2
    174 %u32_3 = OpConstant %u32 3
    175 
    176 %s32_0 = OpConstant %s32 0
    177 %s32_1 = OpConstant %s32 1
    178 %s32_2 = OpConstant %s32 2
    179 %s32_3 = OpConstant %s32 3
    180 
    181 %u64_0 = OpConstant %u64 0
    182 %u64_1 = OpConstant %u64 1
    183 %u64_2 = OpConstant %u64 2
    184 %u64_3 = OpConstant %u64 3
    185 
    186 %s64_0 = OpConstant %s64 0
    187 %s64_1 = OpConstant %s64 1
    188 %s64_2 = OpConstant %s64 2
    189 %s64_3 = OpConstant %s64 3
    190 
    191 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
    192 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
    193 
    194 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
    195 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
    196 
    197 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
    198 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
    199 
    200 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
    201 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
    202 
    203 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
    204 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
    205 
    206 %f32_ptr_output = OpTypePointer Output %f32
    207 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
    208 
    209 %u32_ptr_output = OpTypePointer Output %u32
    210 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
    211 
    212 %u64_ptr_output = OpTypePointer Output %u64
    213 
    214 %f32_output = OpVariable %f32_ptr_output Output
    215 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
    216 
    217 %u32_output = OpVariable %u32_ptr_output Output
    218 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
    219 
    220 %u64_output = OpVariable %u64_ptr_output Output
    221 
    222 %f32_ptr_input = OpTypePointer Input %f32
    223 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
    224 
    225 %u32_ptr_input = OpTypePointer Input %u32
    226 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
    227 
    228 %u64_ptr_input = OpTypePointer Input %u64
    229 
    230 %f32_input = OpVariable %f32_ptr_input Input
    231 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
    232 
    233 %u32_input = OpVariable %u32_ptr_input Input
    234 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
    235 
    236 %u64_input = OpVariable %u64_ptr_input Input
    237 
    238 %struct_f16_u16 = OpTypeStruct %f16 %u16
    239 %struct_f32_f32 = OpTypeStruct %f32 %f32
    240 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
    241 %struct_f32_u32 = OpTypeStruct %f32 %u32
    242 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
    243 %struct_u32_f32 = OpTypeStruct %u32 %f32
    244 %struct_u32_u32 = OpTypeStruct %u32 %u32
    245 %struct_f32_f64 = OpTypeStruct %f32 %f64
    246 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
    247 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
    248 
    249 %main = OpFunction %void None %func
    250 %main_entry = OpLabel
    251 )";
    252 
    253   ss << body;
    254 
    255   ss << R"(
    256 OpReturn
    257 OpFunctionEnd)";
    258 
    259   return ss.str();
    260 }
    261 
    262 std::string GenerateKernelCode(
    263     const std::string& body,
    264     const std::string& capabilities_and_extensions = "",
    265     const std::string& memory_model = "Physical32") {
    266   std::ostringstream ss;
    267   ss << R"(
    268 OpCapability Addresses
    269 OpCapability Kernel
    270 OpCapability Linkage
    271 OpCapability GenericPointer
    272 OpCapability Int8
    273 OpCapability Int16
    274 OpCapability Int64
    275 OpCapability Float16
    276 OpCapability Float64
    277 OpCapability Vector16
    278 OpCapability Matrix
    279 )";
    280 
    281   ss << capabilities_and_extensions;
    282   ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n";
    283   ss << "OpMemoryModel " << memory_model << " OpenCL\n";
    284 
    285   ss << R"(
    286 %void = OpTypeVoid
    287 %func = OpTypeFunction %void
    288 %bool = OpTypeBool
    289 %f16 = OpTypeFloat 16
    290 %f32 = OpTypeFloat 32
    291 %f64 = OpTypeFloat 64
    292 %u32 = OpTypeInt 32 0
    293 %u64 = OpTypeInt 64 0
    294 %u16 = OpTypeInt 16 0
    295 %u8 = OpTypeInt 8 0
    296 %f32vec2 = OpTypeVector %f32 2
    297 %f32vec3 = OpTypeVector %f32 3
    298 %f32vec4 = OpTypeVector %f32 4
    299 %f32vec8 = OpTypeVector %f32 8
    300 %f16vec8 = OpTypeVector %f16 8
    301 %f32vec16 = OpTypeVector %f32 16
    302 %f64vec2 = OpTypeVector %f64 2
    303 %f64vec3 = OpTypeVector %f64 3
    304 %f64vec4 = OpTypeVector %f64 4
    305 %u32vec2 = OpTypeVector %u32 2
    306 %u32vec3 = OpTypeVector %u32 3
    307 %u32vec4 = OpTypeVector %u32 4
    308 %u32vec8 = OpTypeVector %u32 8
    309 %u64vec2 = OpTypeVector %u64 2
    310 %f64mat22 = OpTypeMatrix %f64vec2 2
    311 %f32mat22 = OpTypeMatrix %f32vec2 2
    312 %f32mat23 = OpTypeMatrix %f32vec2 3
    313 %f32mat32 = OpTypeMatrix %f32vec3 2
    314 %f32mat33 = OpTypeMatrix %f32vec3 3
    315 
    316 %f32_0 = OpConstant %f32 0
    317 %f32_1 = OpConstant %f32 1
    318 %f32_2 = OpConstant %f32 2
    319 %f32_3 = OpConstant %f32 3
    320 %f32_4 = OpConstant %f32 4
    321 %f32_h = OpConstant %f32 0.5
    322 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
    323 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
    324 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
    325 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
    326 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
    327 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
    328 %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1
    329 
    330 %f64_0 = OpConstant %f64 0
    331 %f64_1 = OpConstant %f64 1
    332 %f64_2 = OpConstant %f64 2
    333 %f64_3 = OpConstant %f64 3
    334 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
    335 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
    336 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
    337 
    338 %f16_0 = OpConstant %f16 0
    339 %f16_1 = OpConstant %f16 1
    340 
    341 %u8_0 = OpConstant %u8 0
    342 %u8_1 = OpConstant %u8 1
    343 %u8_2 = OpConstant %u8 2
    344 %u8_3 = OpConstant %u8 3
    345 
    346 %u16_0 = OpConstant %u16 0
    347 %u16_1 = OpConstant %u16 1
    348 %u16_2 = OpConstant %u16 2
    349 %u16_3 = OpConstant %u16 3
    350 
    351 %u32_0 = OpConstant %u32 0
    352 %u32_1 = OpConstant %u32 1
    353 %u32_2 = OpConstant %u32 2
    354 %u32_3 = OpConstant %u32 3
    355 %u32_256 = OpConstant %u32 256
    356 
    357 %u64_0 = OpConstant %u64 0
    358 %u64_1 = OpConstant %u64 1
    359 %u64_2 = OpConstant %u64 2
    360 %u64_3 = OpConstant %u64 3
    361 %u64_256 = OpConstant %u64 256
    362 
    363 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
    364 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
    365 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
    366 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
    367 
    368 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
    369 
    370 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
    371 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
    372 
    373 %struct_f32_f32 = OpTypeStruct %f32 %f32
    374 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
    375 %struct_f32_u32 = OpTypeStruct %f32 %u32
    376 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
    377 %struct_u32_f32 = OpTypeStruct %u32 %f32
    378 %struct_u32_u32 = OpTypeStruct %u32 %u32
    379 %struct_f32_f64 = OpTypeStruct %f32 %f64
    380 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
    381 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
    382 
    383 %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8
    384 %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup
    385 %f16_ptr_workgroup = OpTypePointer Workgroup %f16
    386 
    387 %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8
    388 %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup
    389 %u32_ptr_workgroup = OpTypePointer Workgroup %u32
    390 
    391 %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8
    392 %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup
    393 %f32_ptr_workgroup = OpTypePointer Workgroup %f32
    394 
    395 %u32arr = OpTypeArray %u32 %u32_256
    396 %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr
    397 %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup
    398 %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32
    399 
    400 %f32arr = OpTypeArray %f32 %u32_256
    401 %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr
    402 %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup
    403 %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32
    404 
    405 %f32vec2arr = OpTypeArray %f32vec2 %u32_256
    406 %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr
    407 %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup
    408 %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2
    409 
    410 %struct_arr = OpTypeArray %struct_f32_f32 %u32_256
    411 %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr
    412 %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup
    413 %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32
    414 
    415 %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8
    416 %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant
    417 %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16
    418 
    419 %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8
    420 %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant
    421 %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32
    422 
    423 %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8
    424 %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant
    425 %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32
    426 
    427 %f16vec8_ptr_input = OpTypePointer Input %f16vec8
    428 %f16vec8_input = OpVariable %f16vec8_ptr_input Input
    429 %f16_ptr_input = OpTypePointer Input %f16
    430 
    431 %f32_ptr_generic = OpTypePointer Generic %f32
    432 %u32_ptr_generic = OpTypePointer Generic %u32
    433 
    434 %f32_ptr_function = OpTypePointer Function %f32
    435 %f32vec2_ptr_function = OpTypePointer Function %f32vec2
    436 %u32_ptr_function = OpTypePointer Function %u32
    437 %u64_ptr_function = OpTypePointer Function %u64
    438 %u32vec2_ptr_function = OpTypePointer Function %u32vec2
    439 
    440 %u8arr = OpTypeArray %u8 %u32_256
    441 %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr
    442 %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant
    443 %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8
    444 %u8_ptr_generic = OpTypePointer Generic %u8
    445 
    446 %main = OpFunction %void None %func
    447 %main_entry = OpLabel
    448 )";
    449 
    450   ss << body;
    451 
    452   ss << R"(
    453 OpReturn
    454 OpFunctionEnd)";
    455 
    456   return ss.str();
    457 }
    458 
    459 TEST_P(ValidateGlslStd450SqrtLike, Success) {
    460   const std::string ext_inst_name = GetParam();
    461   std::ostringstream ss;
    462   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
    463   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
    464      << " %f32vec2_01\n";
    465   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
    466   CompileSuccessfully(GenerateShaderCode(ss.str()));
    467   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    468 }
    469 
    470 TEST_P(ValidateGlslStd450SqrtLike, IntResultType) {
    471   const std::string ext_inst_name = GetParam();
    472   const std::string body =
    473       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
    474 
    475   CompileSuccessfully(GenerateShaderCode(body));
    476   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    477   EXPECT_THAT(getDiagnosticString(),
    478               HasSubstr("GLSL.std.450 " + ext_inst_name +
    479                         ": expected Result Type to be a float scalar "
    480                         "or vector type"));
    481 }
    482 
    483 TEST_P(ValidateGlslStd450SqrtLike, IntOperand) {
    484   const std::string ext_inst_name = GetParam();
    485   const std::string body =
    486       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
    487 
    488   CompileSuccessfully(GenerateShaderCode(body));
    489   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    490   EXPECT_THAT(getDiagnosticString(),
    491               HasSubstr("GLSL.std.450 " + ext_inst_name +
    492                         ": expected types of all operands to be equal to "
    493                         "Result Type"));
    494 }
    495 
    496 INSTANTIATE_TEST_CASE_P(AllSqrtLike, ValidateGlslStd450SqrtLike,
    497                         ::testing::ValuesIn(std::vector<std::string>{
    498                             "Round",
    499                             "RoundEven",
    500                             "FAbs",
    501                             "Trunc",
    502                             "FSign",
    503                             "Floor",
    504                             "Ceil",
    505                             "Fract",
    506                             "Sqrt",
    507                             "InverseSqrt",
    508                             "Normalize",
    509                         }), );
    510 
    511 TEST_P(ValidateGlslStd450FMinLike, Success) {
    512   const std::string ext_inst_name = GetParam();
    513   std::ostringstream ss;
    514   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
    515      << " %f32_0 %f32_1\n";
    516   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
    517      << " %f32vec2_01 %f32vec2_12\n";
    518   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
    519      << " %f64_0 %f64_0\n";
    520   CompileSuccessfully(GenerateShaderCode(ss.str()));
    521   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    522 }
    523 
    524 TEST_P(ValidateGlslStd450FMinLike, IntResultType) {
    525   const std::string ext_inst_name = GetParam();
    526   const std::string body =
    527       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
    528 
    529   CompileSuccessfully(GenerateShaderCode(body));
    530   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    531   EXPECT_THAT(getDiagnosticString(),
    532               HasSubstr("GLSL.std.450 " + ext_inst_name +
    533                         ": expected Result Type to be a float scalar "
    534                         "or vector type"));
    535 }
    536 
    537 TEST_P(ValidateGlslStd450FMinLike, IntOperand1) {
    538   const std::string ext_inst_name = GetParam();
    539   const std::string body =
    540       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
    541 
    542   CompileSuccessfully(GenerateShaderCode(body));
    543   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    544   EXPECT_THAT(getDiagnosticString(),
    545               HasSubstr("GLSL.std.450 " + ext_inst_name +
    546                         ": expected types of all operands to be equal to "
    547                         "Result Type"));
    548 }
    549 
    550 TEST_P(ValidateGlslStd450FMinLike, IntOperand2) {
    551   const std::string ext_inst_name = GetParam();
    552   const std::string body =
    553       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
    554 
    555   CompileSuccessfully(GenerateShaderCode(body));
    556   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    557   EXPECT_THAT(getDiagnosticString(),
    558               HasSubstr("GLSL.std.450 " + ext_inst_name +
    559                         ": expected types of all operands to be equal to "
    560                         "Result Type"));
    561 }
    562 
    563 INSTANTIATE_TEST_CASE_P(AllFMinLike, ValidateGlslStd450FMinLike,
    564                         ::testing::ValuesIn(std::vector<std::string>{
    565                             "FMin",
    566                             "FMax",
    567                             "Step",
    568                             "Reflect",
    569                             "NMin",
    570                             "NMax",
    571                         }), );
    572 
    573 TEST_P(ValidateGlslStd450FClampLike, Success) {
    574   const std::string ext_inst_name = GetParam();
    575   std::ostringstream ss;
    576   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
    577      << " %f32_0 %f32_1 %f32_2\n";
    578   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
    579      << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
    580   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
    581      << " %f64_0 %f64_0 %f64_1\n";
    582   CompileSuccessfully(GenerateShaderCode(ss.str()));
    583   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    584 }
    585 
    586 TEST_P(ValidateGlslStd450FClampLike, IntResultType) {
    587   const std::string ext_inst_name = GetParam();
    588   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
    589                            " %f32_0 %f32_1 %f32_2\n";
    590 
    591   CompileSuccessfully(GenerateShaderCode(body));
    592   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    593   EXPECT_THAT(getDiagnosticString(),
    594               HasSubstr("GLSL.std.450 " + ext_inst_name +
    595                         ": expected Result Type to be a float scalar "
    596                         "or vector type"));
    597 }
    598 
    599 TEST_P(ValidateGlslStd450FClampLike, IntOperand1) {
    600   const std::string ext_inst_name = GetParam();
    601   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
    602                            " %u32_0 %f32_0 %f32_1\n";
    603 
    604   CompileSuccessfully(GenerateShaderCode(body));
    605   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    606   EXPECT_THAT(getDiagnosticString(),
    607               HasSubstr("GLSL.std.450 " + ext_inst_name +
    608                         ": expected types of all operands to be equal to "
    609                         "Result Type"));
    610 }
    611 
    612 TEST_P(ValidateGlslStd450FClampLike, IntOperand2) {
    613   const std::string ext_inst_name = GetParam();
    614   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
    615                            " %f32_0 %u32_0 %f32_1\n";
    616 
    617   CompileSuccessfully(GenerateShaderCode(body));
    618   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    619   EXPECT_THAT(getDiagnosticString(),
    620               HasSubstr("GLSL.std.450 " + ext_inst_name +
    621                         ": expected types of all operands to be equal to "
    622                         "Result Type"));
    623 }
    624 
    625 TEST_P(ValidateGlslStd450FClampLike, IntOperand3) {
    626   const std::string ext_inst_name = GetParam();
    627   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
    628                            " %f32_1 %f32_0 %u32_2\n";
    629 
    630   CompileSuccessfully(GenerateShaderCode(body));
    631   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    632   EXPECT_THAT(getDiagnosticString(),
    633               HasSubstr("GLSL.std.450 " + ext_inst_name +
    634                         ": expected types of all operands to be equal to "
    635                         "Result Type"));
    636 }
    637 
    638 INSTANTIATE_TEST_CASE_P(AllFClampLike, ValidateGlslStd450FClampLike,
    639                         ::testing::ValuesIn(std::vector<std::string>{
    640                             "FClamp",
    641                             "FMix",
    642                             "SmoothStep",
    643                             "Fma",
    644                             "FaceForward",
    645                             "NClamp",
    646                         }), );
    647 
    648 TEST_P(ValidateGlslStd450SAbsLike, Success) {
    649   const std::string ext_inst_name = GetParam();
    650   std::ostringstream ss;
    651   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n";
    652   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n";
    653   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
    654   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n";
    655   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    656      << " %s32vec2_01\n";
    657   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    658      << " %u32vec2_01\n";
    659   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    660      << " %s32vec2_01\n";
    661   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    662      << " %u32vec2_01\n";
    663   CompileSuccessfully(GenerateShaderCode(ss.str()));
    664   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    665 }
    666 
    667 TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) {
    668   const std::string ext_inst_name = GetParam();
    669   const std::string body =
    670       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
    671 
    672   CompileSuccessfully(GenerateShaderCode(body));
    673   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    674   EXPECT_THAT(getDiagnosticString(),
    675               HasSubstr("GLSL.std.450 " + ext_inst_name +
    676                         ": expected Result Type to be an int scalar "
    677                         "or vector type"));
    678 }
    679 
    680 TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) {
    681   const std::string ext_inst_name = GetParam();
    682   const std::string body =
    683       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n";
    684 
    685   CompileSuccessfully(GenerateShaderCode(body));
    686   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    687   EXPECT_THAT(getDiagnosticString(),
    688               HasSubstr("GLSL.std.450 " + ext_inst_name +
    689                         ": expected all operands to be int scalars or "
    690                         "vectors"));
    691 }
    692 
    693 TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) {
    694   const std::string ext_inst_name = GetParam();
    695   const std::string body =
    696       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n";
    697 
    698   CompileSuccessfully(GenerateShaderCode(body));
    699   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    700   EXPECT_THAT(getDiagnosticString(),
    701               HasSubstr("GLSL.std.450 " + ext_inst_name +
    702                         ": expected all operands to have the same dimension as "
    703                         "Result Type"));
    704 }
    705 
    706 TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) {
    707   const std::string ext_inst_name = GetParam();
    708   const std::string body =
    709       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n";
    710 
    711   CompileSuccessfully(GenerateShaderCode(body));
    712   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    713   EXPECT_THAT(getDiagnosticString(),
    714               HasSubstr("GLSL.std.450 " + ext_inst_name +
    715                         ": expected all operands to have the same bit width as "
    716                         "Result Type"));
    717 }
    718 
    719 INSTANTIATE_TEST_CASE_P(AllSAbsLike, ValidateGlslStd450SAbsLike,
    720                         ::testing::ValuesIn(std::vector<std::string>{
    721                             "SAbs",
    722                             "SSign",
    723                             "FindILsb",
    724                             "FindUMsb",
    725                             "FindSMsb",
    726                         }), );
    727 
    728 TEST_F(ValidateExtInst, FindUMsbNot32Bit) {
    729   const std::string body = R"(
    730 %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1
    731 )";
    732 
    733   CompileSuccessfully(GenerateShaderCode(body));
    734   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    735   EXPECT_THAT(getDiagnosticString(),
    736               HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently "
    737                         "limited to 32-bit width components"));
    738 }
    739 
    740 TEST_F(ValidateExtInst, FindSMsbNot32Bit) {
    741   const std::string body = R"(
    742 %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1
    743 )";
    744 
    745   CompileSuccessfully(GenerateShaderCode(body));
    746   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    747   EXPECT_THAT(getDiagnosticString(),
    748               HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently "
    749                         "limited to 32-bit width components"));
    750 }
    751 
    752 TEST_P(ValidateGlslStd450UMinLike, Success) {
    753   const std::string ext_inst_name = GetParam();
    754   std::ostringstream ss;
    755   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
    756      << " %u32_1 %s32_2\n";
    757   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
    758      << " %s32_1 %u32_2\n";
    759   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
    760      << " %u32_1 %s32_2\n";
    761   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
    762      << " %s32_1 %u32_2\n";
    763   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    764      << " %s32vec2_01 %u32vec2_01\n";
    765   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    766      << " %u32vec2_01 %s32vec2_01\n";
    767   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    768      << " %s32vec2_01 %u32vec2_01\n";
    769   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    770      << " %u32vec2_01 %s32vec2_01\n";
    771   ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
    772      << " %u64_1 %s64_0\n";
    773   CompileSuccessfully(GenerateShaderCode(ss.str()));
    774   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    775 }
    776 
    777 TEST_P(ValidateGlslStd450UMinLike, FloatResultType) {
    778   const std::string ext_inst_name = GetParam();
    779   const std::string body =
    780       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
    781 
    782   CompileSuccessfully(GenerateShaderCode(body));
    783   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    784   EXPECT_THAT(getDiagnosticString(),
    785               HasSubstr("GLSL.std.450 " + ext_inst_name +
    786                         ": expected Result Type to be an int scalar "
    787                         "or vector type"));
    788 }
    789 
    790 TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) {
    791   const std::string ext_inst_name = GetParam();
    792   const std::string body =
    793       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
    794 
    795   CompileSuccessfully(GenerateShaderCode(body));
    796   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    797   EXPECT_THAT(getDiagnosticString(),
    798               HasSubstr("GLSL.std.450 " + ext_inst_name +
    799                         ": expected all operands to be int scalars or "
    800                         "vectors"));
    801 }
    802 
    803 TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) {
    804   const std::string ext_inst_name = GetParam();
    805   const std::string body =
    806       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
    807 
    808   CompileSuccessfully(GenerateShaderCode(body));
    809   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    810   EXPECT_THAT(getDiagnosticString(),
    811               HasSubstr("GLSL.std.450 " + ext_inst_name +
    812                         ": expected all operands to be int scalars or "
    813                         "vectors"));
    814 }
    815 
    816 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) {
    817   const std::string ext_inst_name = GetParam();
    818   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    819                            " %s32vec2_01 %s32_0\n";
    820 
    821   CompileSuccessfully(GenerateShaderCode(body));
    822   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    823   EXPECT_THAT(getDiagnosticString(),
    824               HasSubstr("GLSL.std.450 " + ext_inst_name +
    825                         ": expected all operands to have the same dimension as "
    826                         "Result Type"));
    827 }
    828 
    829 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) {
    830   const std::string ext_inst_name = GetParam();
    831   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    832                            " %s32_0 %s32vec2_01\n";
    833 
    834   CompileSuccessfully(GenerateShaderCode(body));
    835   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    836   EXPECT_THAT(getDiagnosticString(),
    837               HasSubstr("GLSL.std.450 " + ext_inst_name +
    838                         ": expected all operands to have the same dimension as "
    839                         "Result Type"));
    840 }
    841 
    842 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) {
    843   const std::string ext_inst_name = GetParam();
    844   const std::string body =
    845       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n";
    846 
    847   CompileSuccessfully(GenerateShaderCode(body));
    848   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    849   EXPECT_THAT(getDiagnosticString(),
    850               HasSubstr("GLSL.std.450 " + ext_inst_name +
    851                         ": expected all operands to have the same bit width as "
    852                         "Result Type"));
    853 }
    854 
    855 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) {
    856   const std::string ext_inst_name = GetParam();
    857   const std::string body =
    858       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n";
    859 
    860   CompileSuccessfully(GenerateShaderCode(body));
    861   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    862   EXPECT_THAT(getDiagnosticString(),
    863               HasSubstr("GLSL.std.450 " + ext_inst_name +
    864                         ": expected all operands to have the same bit width as "
    865                         "Result Type"));
    866 }
    867 
    868 INSTANTIATE_TEST_CASE_P(AllUMinLike, ValidateGlslStd450UMinLike,
    869                         ::testing::ValuesIn(std::vector<std::string>{
    870                             "UMin",
    871                             "SMin",
    872                             "UMax",
    873                             "SMax",
    874                         }), );
    875 
    876 TEST_P(ValidateGlslStd450UClampLike, Success) {
    877   const std::string ext_inst_name = GetParam();
    878   std::ostringstream ss;
    879   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
    880      << " %s32_0 %u32_1 %s32_2\n";
    881   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
    882      << " %u32_0 %s32_1 %u32_2\n";
    883   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
    884      << " %s32_0 %u32_1 %s32_2\n";
    885   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
    886      << " %u32_0 %s32_1 %u32_2\n";
    887   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    888      << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
    889   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    890      << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
    891   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
    892      << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
    893   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
    894      << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
    895   ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
    896      << " %u64_1 %s64_0 %s64_1\n";
    897   CompileSuccessfully(GenerateShaderCode(ss.str()));
    898   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    899 }
    900 
    901 TEST_P(ValidateGlslStd450UClampLike, FloatResultType) {
    902   const std::string ext_inst_name = GetParam();
    903   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
    904                            " %u32_0 %u32_0 %u32_1\n";
    905 
    906   CompileSuccessfully(GenerateShaderCode(body));
    907   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    908   EXPECT_THAT(getDiagnosticString(),
    909               HasSubstr("GLSL.std.450 " + ext_inst_name +
    910                         ": expected Result Type to be an int scalar "
    911                         "or vector type"));
    912 }
    913 
    914 TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) {
    915   const std::string ext_inst_name = GetParam();
    916   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    917                            " %f32_0 %u32_0 %u32_1\n";
    918 
    919   CompileSuccessfully(GenerateShaderCode(body));
    920   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    921   EXPECT_THAT(getDiagnosticString(),
    922               HasSubstr("GLSL.std.450 " + ext_inst_name +
    923                         ": expected all operands to be int scalars or "
    924                         "vectors"));
    925 }
    926 
    927 TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) {
    928   const std::string ext_inst_name = GetParam();
    929   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    930                            " %u32_0 %f32_0 %u32_1\n";
    931 
    932   CompileSuccessfully(GenerateShaderCode(body));
    933   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    934   EXPECT_THAT(getDiagnosticString(),
    935               HasSubstr("GLSL.std.450 " + ext_inst_name +
    936                         ": expected all operands to be int scalars or "
    937                         "vectors"));
    938 }
    939 
    940 TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) {
    941   const std::string ext_inst_name = GetParam();
    942   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    943                            " %u32_0 %u32_0 %f32_1\n";
    944 
    945   CompileSuccessfully(GenerateShaderCode(body));
    946   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    947   EXPECT_THAT(getDiagnosticString(),
    948               HasSubstr("GLSL.std.450 " + ext_inst_name +
    949                         ": expected all operands to be int scalars or "
    950                         "vectors"));
    951 }
    952 
    953 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) {
    954   const std::string ext_inst_name = GetParam();
    955   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    956                            " %s32vec2_01 %s32_0 %u32_1\n";
    957 
    958   CompileSuccessfully(GenerateShaderCode(body));
    959   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    960   EXPECT_THAT(getDiagnosticString(),
    961               HasSubstr("GLSL.std.450 " + ext_inst_name +
    962                         ": expected all operands to have the same dimension as "
    963                         "Result Type"));
    964 }
    965 
    966 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) {
    967   const std::string ext_inst_name = GetParam();
    968   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    969                            " %s32_0 %s32vec2_01 %u32_1\n";
    970 
    971   CompileSuccessfully(GenerateShaderCode(body));
    972   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    973   EXPECT_THAT(getDiagnosticString(),
    974               HasSubstr("GLSL.std.450 " + ext_inst_name +
    975                         ": expected all operands to have the same dimension as "
    976                         "Result Type"));
    977 }
    978 
    979 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) {
    980   const std::string ext_inst_name = GetParam();
    981   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
    982                            " %s32_0 %u32_1 %s32vec2_01\n";
    983 
    984   CompileSuccessfully(GenerateShaderCode(body));
    985   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    986   EXPECT_THAT(getDiagnosticString(),
    987               HasSubstr("GLSL.std.450 " + ext_inst_name +
    988                         ": expected all operands to have the same dimension as "
    989                         "Result Type"));
    990 }
    991 
    992 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) {
    993   const std::string ext_inst_name = GetParam();
    994   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
    995                            " %s32_0 %s64_0 %s64_1\n";
    996 
    997   CompileSuccessfully(GenerateShaderCode(body));
    998   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
    999   EXPECT_THAT(getDiagnosticString(),
   1000               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1001                         ": expected all operands to have the same bit width as "
   1002                         "Result Type"));
   1003 }
   1004 
   1005 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) {
   1006   const std::string ext_inst_name = GetParam();
   1007   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
   1008                            " %s64_0 %s32_0 %s64_1\n";
   1009 
   1010   CompileSuccessfully(GenerateShaderCode(body));
   1011   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1012   EXPECT_THAT(getDiagnosticString(),
   1013               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1014                         ": expected all operands to have the same bit width as "
   1015                         "Result Type"));
   1016 }
   1017 
   1018 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) {
   1019   const std::string ext_inst_name = GetParam();
   1020   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
   1021                            " %s64_0 %s64_0 %s32_1\n";
   1022 
   1023   CompileSuccessfully(GenerateShaderCode(body));
   1024   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1025   EXPECT_THAT(getDiagnosticString(),
   1026               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1027                         ": expected all operands to have the same bit width as "
   1028                         "Result Type"));
   1029 }
   1030 
   1031 INSTANTIATE_TEST_CASE_P(AllUClampLike, ValidateGlslStd450UClampLike,
   1032                         ::testing::ValuesIn(std::vector<std::string>{
   1033                             "UClamp",
   1034                             "SClamp",
   1035                         }), );
   1036 
   1037 TEST_P(ValidateGlslStd450SinLike, Success) {
   1038   const std::string ext_inst_name = GetParam();
   1039   std::ostringstream ss;
   1040   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
   1041   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   1042      << " %f32vec2_01\n";
   1043   CompileSuccessfully(GenerateShaderCode(ss.str()));
   1044   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1045 }
   1046 
   1047 TEST_P(ValidateGlslStd450SinLike, IntResultType) {
   1048   const std::string ext_inst_name = GetParam();
   1049   const std::string body =
   1050       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
   1051 
   1052   CompileSuccessfully(GenerateShaderCode(body));
   1053   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1054   EXPECT_THAT(getDiagnosticString(),
   1055               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1056                         ": expected Result Type to be a 16 or 32-bit scalar "
   1057                         "or vector float type"));
   1058 }
   1059 
   1060 TEST_P(ValidateGlslStd450SinLike, F64ResultType) {
   1061   const std::string ext_inst_name = GetParam();
   1062   const std::string body =
   1063       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n";
   1064 
   1065   CompileSuccessfully(GenerateShaderCode(body));
   1066   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1067   EXPECT_THAT(getDiagnosticString(),
   1068               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1069                         ": expected Result Type to be a 16 or 32-bit scalar "
   1070                         "or vector float type"));
   1071 }
   1072 
   1073 TEST_P(ValidateGlslStd450SinLike, IntOperand) {
   1074   const std::string ext_inst_name = GetParam();
   1075   const std::string body =
   1076       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
   1077 
   1078   CompileSuccessfully(GenerateShaderCode(body));
   1079   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1080   EXPECT_THAT(getDiagnosticString(),
   1081               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1082                         ": expected types of all operands to be equal to "
   1083                         "Result Type"));
   1084 }
   1085 
   1086 INSTANTIATE_TEST_CASE_P(AllSinLike, ValidateGlslStd450SinLike,
   1087                         ::testing::ValuesIn(std::vector<std::string>{
   1088                             "Radians",
   1089                             "Degrees",
   1090                             "Sin",
   1091                             "Cos",
   1092                             "Tan",
   1093                             "Asin",
   1094                             "Acos",
   1095                             "Atan",
   1096                             "Sinh",
   1097                             "Cosh",
   1098                             "Tanh",
   1099                             "Asinh",
   1100                             "Acosh",
   1101                             "Atanh",
   1102                             "Exp",
   1103                             "Exp2",
   1104                             "Log",
   1105                             "Log2",
   1106                         }), );
   1107 
   1108 TEST_P(ValidateGlslStd450PowLike, Success) {
   1109   const std::string ext_inst_name = GetParam();
   1110   std::ostringstream ss;
   1111   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   1112      << " %f32_1 %f32_1\n";
   1113   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   1114      << " %f32vec2_01 %f32vec2_12\n";
   1115   CompileSuccessfully(GenerateShaderCode(ss.str()));
   1116   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1117 }
   1118 
   1119 TEST_P(ValidateGlslStd450PowLike, IntResultType) {
   1120   const std::string ext_inst_name = GetParam();
   1121   const std::string body =
   1122       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
   1123 
   1124   CompileSuccessfully(GenerateShaderCode(body));
   1125   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1126   EXPECT_THAT(getDiagnosticString(),
   1127               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1128                         ": expected Result Type to be a 16 or 32-bit scalar "
   1129                         "or vector float type"));
   1130 }
   1131 
   1132 TEST_P(ValidateGlslStd450PowLike, F64ResultType) {
   1133   const std::string ext_inst_name = GetParam();
   1134   const std::string body =
   1135       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
   1136 
   1137   CompileSuccessfully(GenerateShaderCode(body));
   1138   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1139   EXPECT_THAT(getDiagnosticString(),
   1140               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1141                         ": expected Result Type to be a 16 or 32-bit scalar "
   1142                         "or vector float type"));
   1143 }
   1144 
   1145 TEST_P(ValidateGlslStd450PowLike, IntOperand1) {
   1146   const std::string ext_inst_name = GetParam();
   1147   const std::string body =
   1148       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
   1149 
   1150   CompileSuccessfully(GenerateShaderCode(body));
   1151   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1152   EXPECT_THAT(getDiagnosticString(),
   1153               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1154                         ": expected types of all operands to be equal to "
   1155                         "Result Type"));
   1156 }
   1157 
   1158 TEST_P(ValidateGlslStd450PowLike, IntOperand2) {
   1159   const std::string ext_inst_name = GetParam();
   1160   const std::string body =
   1161       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
   1162 
   1163   CompileSuccessfully(GenerateShaderCode(body));
   1164   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1165   EXPECT_THAT(getDiagnosticString(),
   1166               HasSubstr("GLSL.std.450 " + ext_inst_name +
   1167                         ": expected types of all operands to be equal to "
   1168                         "Result Type"));
   1169 }
   1170 
   1171 INSTANTIATE_TEST_CASE_P(AllPowLike, ValidateGlslStd450PowLike,
   1172                         ::testing::ValuesIn(std::vector<std::string>{
   1173                             "Atan2",
   1174                             "Pow",
   1175                         }), );
   1176 
   1177 TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) {
   1178   const std::string body = R"(
   1179 %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212
   1180 )";
   1181 
   1182   CompileSuccessfully(GenerateShaderCode(body));
   1183   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1184 }
   1185 
   1186 TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) {
   1187   const std::string body = R"(
   1188 %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212
   1189 )";
   1190 
   1191   CompileSuccessfully(GenerateShaderCode(body));
   1192   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1193   EXPECT_THAT(getDiagnosticString(),
   1194               HasSubstr("GLSL.std.450 Determinant: "
   1195                         "expected operand X component type to be equal to "
   1196                         "Result Type"));
   1197 }
   1198 
   1199 TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) {
   1200   const std::string body = R"(
   1201 %val1 = OpExtInst %f32 %extinst Determinant %f32_1
   1202 )";
   1203 
   1204   CompileSuccessfully(GenerateShaderCode(body));
   1205   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1206   EXPECT_THAT(getDiagnosticString(),
   1207               HasSubstr("GLSL.std.450 Determinant: "
   1208                         "expected operand X to be a square matrix"));
   1209 }
   1210 
   1211 TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) {
   1212   const std::string body = R"(
   1213 %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212
   1214 )";
   1215 
   1216   CompileSuccessfully(GenerateShaderCode(body));
   1217   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1218   EXPECT_THAT(getDiagnosticString(),
   1219               HasSubstr("GLSL.std.450 Determinant: "
   1220                         "expected operand X to be a square matrix"));
   1221 }
   1222 
   1223 TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) {
   1224   const std::string body = R"(
   1225 %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212
   1226 )";
   1227 
   1228   CompileSuccessfully(GenerateShaderCode(body));
   1229   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1230 }
   1231 
   1232 TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) {
   1233   const std::string body = R"(
   1234 %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212
   1235 )";
   1236 
   1237   CompileSuccessfully(GenerateShaderCode(body));
   1238   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1239   EXPECT_THAT(getDiagnosticString(),
   1240               HasSubstr("GLSL.std.450 MatrixInverse: "
   1241                         "expected operand X type to be equal to "
   1242                         "Result Type"));
   1243 }
   1244 
   1245 TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) {
   1246   const std::string body = R"(
   1247 %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212
   1248 )";
   1249 
   1250   CompileSuccessfully(GenerateShaderCode(body));
   1251   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1252   EXPECT_THAT(getDiagnosticString(),
   1253               HasSubstr("GLSL.std.450 MatrixInverse: "
   1254                         "expected Result Type to be a square matrix"));
   1255 }
   1256 
   1257 TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) {
   1258   const std::string body = R"(
   1259 %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212
   1260 )";
   1261 
   1262   CompileSuccessfully(GenerateShaderCode(body));
   1263   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1264   EXPECT_THAT(getDiagnosticString(),
   1265               HasSubstr("GLSL.std.450 MatrixInverse: "
   1266                         "expected Result Type to be a square matrix"));
   1267 }
   1268 
   1269 TEST_F(ValidateExtInst, GlslStd450ModfSuccess) {
   1270   const std::string body = R"(
   1271 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output
   1272 %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output
   1273 )";
   1274 
   1275   CompileSuccessfully(GenerateShaderCode(body));
   1276   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1277 }
   1278 
   1279 TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) {
   1280   const std::string body = R"(
   1281 %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output
   1282 )";
   1283 
   1284   CompileSuccessfully(GenerateShaderCode(body));
   1285   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1286   EXPECT_THAT(getDiagnosticString(),
   1287               HasSubstr("GLSL.std.450 Modf: "
   1288                         "expected Result Type to be a scalar or vector "
   1289                         "float type"));
   1290 }
   1291 
   1292 TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) {
   1293   const std::string body = R"(
   1294 %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output
   1295 )";
   1296 
   1297   CompileSuccessfully(GenerateShaderCode(body));
   1298   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1299   EXPECT_THAT(getDiagnosticString(),
   1300               HasSubstr("GLSL.std.450 Modf: "
   1301                         "expected operand X type to be equal to Result Type"));
   1302 }
   1303 
   1304 TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) {
   1305   const std::string body = R"(
   1306 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1
   1307 )";
   1308 
   1309   CompileSuccessfully(GenerateShaderCode(body));
   1310   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1311   EXPECT_THAT(getDiagnosticString(),
   1312               HasSubstr("GLSL.std.450 Modf: "
   1313                         "expected operand I to be a pointer"));
   1314 }
   1315 
   1316 TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) {
   1317   const std::string body = R"(
   1318 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output
   1319 )";
   1320 
   1321   CompileSuccessfully(GenerateShaderCode(body));
   1322   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1323   EXPECT_THAT(getDiagnosticString(),
   1324               HasSubstr("GLSL.std.450 Modf: "
   1325                         "expected operand I data type to be equal to "
   1326                         "Result Type"));
   1327 }
   1328 
   1329 TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) {
   1330   const std::string body = R"(
   1331 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h
   1332 %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01
   1333 )";
   1334 
   1335   CompileSuccessfully(GenerateShaderCode(body));
   1336   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1337 }
   1338 
   1339 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) {
   1340   const std::string body = R"(
   1341 %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h
   1342 )";
   1343 
   1344   CompileSuccessfully(GenerateShaderCode(body));
   1345   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1346   EXPECT_THAT(getDiagnosticString(),
   1347               HasSubstr("GLSL.std.450 ModfStruct: "
   1348                         "expected Result Type to be a struct with two "
   1349                         "identical scalar or vector float type members"));
   1350 }
   1351 
   1352 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) {
   1353   const std::string body = R"(
   1354 %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h
   1355 )";
   1356 
   1357   CompileSuccessfully(GenerateShaderCode(body));
   1358   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1359   EXPECT_THAT(getDiagnosticString(),
   1360               HasSubstr("GLSL.std.450 ModfStruct: "
   1361                         "expected Result Type to be a struct with two "
   1362                         "identical scalar or vector float type members"));
   1363 }
   1364 
   1365 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) {
   1366   const std::string body = R"(
   1367 %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h
   1368 )";
   1369 
   1370   CompileSuccessfully(GenerateShaderCode(body));
   1371   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1372   EXPECT_THAT(getDiagnosticString(),
   1373               HasSubstr("GLSL.std.450 ModfStruct: "
   1374                         "expected Result Type to be a struct with two "
   1375                         "identical scalar or vector float type members"));
   1376 }
   1377 
   1378 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) {
   1379   const std::string body = R"(
   1380 %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h
   1381 )";
   1382 
   1383   CompileSuccessfully(GenerateShaderCode(body));
   1384   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1385   EXPECT_THAT(getDiagnosticString(),
   1386               HasSubstr("GLSL.std.450 ModfStruct: "
   1387                         "expected Result Type to be a struct with two "
   1388                         "identical scalar or vector float type members"));
   1389 }
   1390 
   1391 TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) {
   1392   const std::string body = R"(
   1393 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0
   1394 )";
   1395 
   1396   CompileSuccessfully(GenerateShaderCode(body));
   1397   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1398   EXPECT_THAT(getDiagnosticString(),
   1399               HasSubstr("GLSL.std.450 ModfStruct: "
   1400                         "expected operand X type to be equal to members of "
   1401                         "Result Type struct"));
   1402 }
   1403 
   1404 TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) {
   1405   const std::string body = R"(
   1406 %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output
   1407 %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output
   1408 )";
   1409 
   1410   CompileSuccessfully(GenerateShaderCode(body));
   1411   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1412 }
   1413 
   1414 TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) {
   1415   const std::string body = R"(
   1416 %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output
   1417 )";
   1418 
   1419   CompileSuccessfully(GenerateShaderCode(body));
   1420   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1421   EXPECT_THAT(getDiagnosticString(),
   1422               HasSubstr("GLSL.std.450 Frexp: "
   1423                         "expected Result Type to be a scalar or vector "
   1424                         "float type"));
   1425 }
   1426 
   1427 TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) {
   1428   const std::string body = R"(
   1429 %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output
   1430 )";
   1431 
   1432   CompileSuccessfully(GenerateShaderCode(body));
   1433   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1434   EXPECT_THAT(getDiagnosticString(),
   1435               HasSubstr("GLSL.std.450 Frexp: "
   1436                         "expected operand X type to be equal to Result Type"));
   1437 }
   1438 
   1439 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) {
   1440   const std::string body = R"(
   1441 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1
   1442 )";
   1443 
   1444   CompileSuccessfully(GenerateShaderCode(body));
   1445   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1446   EXPECT_THAT(getDiagnosticString(),
   1447               HasSubstr("GLSL.std.450 Frexp: "
   1448                         "expected operand Exp to be a pointer"));
   1449 }
   1450 
   1451 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) {
   1452   const std::string body = R"(
   1453 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output
   1454 )";
   1455 
   1456   CompileSuccessfully(GenerateShaderCode(body));
   1457   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1458   EXPECT_THAT(getDiagnosticString(),
   1459               HasSubstr("GLSL.std.450 Frexp: "
   1460                         "expected operand Exp data type to be a 32-bit int "
   1461                         "scalar or vector type"));
   1462 }
   1463 
   1464 TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) {
   1465   const std::string body = R"(
   1466 %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output
   1467 )";
   1468 
   1469   CompileSuccessfully(GenerateShaderCode(body));
   1470   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1471   EXPECT_THAT(getDiagnosticString(),
   1472               HasSubstr("GLSL.std.450 Frexp: "
   1473                         "expected operand Exp data type to have the same "
   1474                         "component number as Result Type"));
   1475 }
   1476 
   1477 TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) {
   1478   const std::string body = R"(
   1479 %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2
   1480 %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12
   1481 %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1
   1482 )";
   1483 
   1484   CompileSuccessfully(GenerateShaderCode(body));
   1485   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1486 }
   1487 
   1488 TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) {
   1489   const std::string body = R"(
   1490 %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2
   1491 )";
   1492 
   1493   CompileSuccessfully(GenerateShaderCode(body));
   1494   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1495   EXPECT_THAT(getDiagnosticString(),
   1496               HasSubstr("GLSL.std.450 Ldexp: "
   1497                         "expected Result Type to be a scalar or vector "
   1498                         "float type"));
   1499 }
   1500 
   1501 TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) {
   1502   const std::string body = R"(
   1503 %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2
   1504 )";
   1505 
   1506   CompileSuccessfully(GenerateShaderCode(body));
   1507   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1508   EXPECT_THAT(getDiagnosticString(),
   1509               HasSubstr("GLSL.std.450 Ldexp: "
   1510                         "expected operand X type to be equal to Result Type"));
   1511 }
   1512 
   1513 TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) {
   1514   const std::string body = R"(
   1515 %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2
   1516 )";
   1517 
   1518   CompileSuccessfully(GenerateShaderCode(body));
   1519   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1520   EXPECT_THAT(getDiagnosticString(),
   1521               HasSubstr("GLSL.std.450 Ldexp: "
   1522                         "expected operand Exp to be a 32-bit int scalar "
   1523                         "or vector type"));
   1524 }
   1525 
   1526 TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) {
   1527   const std::string body = R"(
   1528 %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2
   1529 )";
   1530 
   1531   CompileSuccessfully(GenerateShaderCode(body));
   1532   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1533   EXPECT_THAT(getDiagnosticString(),
   1534               HasSubstr("GLSL.std.450 Ldexp: "
   1535                         "expected operand Exp to have the same component "
   1536                         "number as Result Type"));
   1537 }
   1538 
   1539 TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) {
   1540   const std::string body = R"(
   1541 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h
   1542 %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01
   1543 )";
   1544 
   1545   CompileSuccessfully(GenerateShaderCode(body));
   1546   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1547 }
   1548 
   1549 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) {
   1550   const std::string body = R"(
   1551 %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h
   1552 )";
   1553 
   1554   CompileSuccessfully(GenerateShaderCode(body));
   1555   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1556   EXPECT_THAT(getDiagnosticString(),
   1557               HasSubstr("GLSL.std.450 FrexpStruct: "
   1558                         "expected Result Type to be a struct with two members, "
   1559                         "first member a float scalar or vector, second member "
   1560                         "a 32-bit int scalar or vector with the same number of "
   1561                         "components as the first member"));
   1562 }
   1563 
   1564 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) {
   1565   const std::string body = R"(
   1566 %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h
   1567 )";
   1568 
   1569   CompileSuccessfully(GenerateShaderCode(body));
   1570   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1571   EXPECT_THAT(getDiagnosticString(),
   1572               HasSubstr("GLSL.std.450 FrexpStruct: "
   1573                         "expected Result Type to be a struct with two members, "
   1574                         "first member a float scalar or vector, second member "
   1575                         "a 32-bit int scalar or vector with the same number of "
   1576                         "components as the first member"));
   1577 }
   1578 
   1579 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) {
   1580   const std::string body = R"(
   1581 %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h
   1582 )";
   1583 
   1584   CompileSuccessfully(GenerateShaderCode(body));
   1585   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1586   EXPECT_THAT(getDiagnosticString(),
   1587               HasSubstr("GLSL.std.450 FrexpStruct: "
   1588                         "expected Result Type to be a struct with two members, "
   1589                         "first member a float scalar or vector, second member "
   1590                         "a 32-bit int scalar or vector with the same number of "
   1591                         "components as the first member"));
   1592 }
   1593 
   1594 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) {
   1595   const std::string body = R"(
   1596 %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h
   1597 )";
   1598 
   1599   CompileSuccessfully(GenerateShaderCode(body));
   1600   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1601   EXPECT_THAT(getDiagnosticString(),
   1602               HasSubstr("GLSL.std.450 FrexpStruct: "
   1603                         "expected Result Type to be a struct with two members, "
   1604                         "first member a float scalar or vector, second member "
   1605                         "a 32-bit int scalar or vector with the same number of "
   1606                         "components as the first member"));
   1607 }
   1608 
   1609 TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) {
   1610   const std::string body = R"(
   1611 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0
   1612 )";
   1613 
   1614   CompileSuccessfully(GenerateShaderCode(body));
   1615   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1616   EXPECT_THAT(getDiagnosticString(),
   1617               HasSubstr("GLSL.std.450 FrexpStruct: "
   1618                         "expected operand X type to be equal to the first "
   1619                         "member of Result Type struct"));
   1620 }
   1621 
   1622 TEST_F(ValidateExtInst,
   1623        GlslStd450FrexpStructResultTypeStructRightInt16Member2) {
   1624   const std::string body = R"(
   1625 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
   1626 )";
   1627 
   1628   const std::string extension = R"(
   1629 OpExtension  "SPV_AMD_gpu_shader_int16"
   1630 )";
   1631 
   1632   CompileSuccessfully(GenerateShaderCode(body, extension));
   1633   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1634 }
   1635 
   1636 TEST_F(ValidateExtInst,
   1637        GlslStd450FrexpStructResultTypeStructWrongInt16Member2) {
   1638   const std::string body = R"(
   1639 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
   1640 )";
   1641 
   1642   CompileSuccessfully(GenerateShaderCode(body));
   1643   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1644   EXPECT_THAT(getDiagnosticString(),
   1645               HasSubstr("GLSL.std.450 FrexpStruct: "
   1646                         "expected Result Type to be a struct with two members, "
   1647                         "first member a float scalar or vector, second member "
   1648                         "a 32-bit int scalar or vector with the same number of "
   1649                         "components as the first member"));
   1650 }
   1651 
   1652 TEST_P(ValidateGlslStd450Pack, Success) {
   1653   const std::string ext_inst_name = GetParam();
   1654   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1655   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1656   const uint32_t total_bit_width = num_components * packed_bit_width;
   1657   const std::string vec_str =
   1658       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
   1659 
   1660   std::ostringstream body;
   1661   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
   1662        << ext_inst_name << vec_str;
   1663   body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst "
   1664        << ext_inst_name << vec_str;
   1665   CompileSuccessfully(GenerateShaderCode(body.str()));
   1666   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1667 }
   1668 
   1669 TEST_P(ValidateGlslStd450Pack, Float32ResultType) {
   1670   const std::string ext_inst_name = GetParam();
   1671   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1672   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1673   const uint32_t total_bit_width = num_components * packed_bit_width;
   1674   const std::string vec_str =
   1675       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
   1676 
   1677   std::ostringstream body;
   1678   body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst "
   1679        << ext_inst_name << vec_str;
   1680 
   1681   std::ostringstream expected;
   1682   expected << "GLSL.std.450 " << ext_inst_name
   1683            << ": expected Result Type to be " << total_bit_width
   1684            << "-bit int scalar type";
   1685 
   1686   CompileSuccessfully(GenerateShaderCode(body.str()));
   1687   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1688   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1689 }
   1690 
   1691 TEST_P(ValidateGlslStd450Pack, Int16ResultType) {
   1692   const std::string ext_inst_name = GetParam();
   1693   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1694   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1695   const uint32_t total_bit_width = num_components * packed_bit_width;
   1696   const std::string vec_str =
   1697       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
   1698 
   1699   std::ostringstream body;
   1700   body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str;
   1701 
   1702   std::ostringstream expected;
   1703   expected << "GLSL.std.450 " << ext_inst_name
   1704            << ": expected Result Type to be " << total_bit_width
   1705            << "-bit int scalar type";
   1706 
   1707   CompileSuccessfully(GenerateShaderCode(body.str()));
   1708   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1709   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1710 }
   1711 
   1712 TEST_P(ValidateGlslStd450Pack, VNotVector) {
   1713   const std::string ext_inst_name = GetParam();
   1714   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1715   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1716   const uint32_t total_bit_width = num_components * packed_bit_width;
   1717 
   1718   std::ostringstream body;
   1719   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
   1720        << ext_inst_name << " %f32_1\n";
   1721 
   1722   std::ostringstream expected;
   1723   expected << "GLSL.std.450 " << ext_inst_name
   1724            << ": expected operand V to be a 32-bit float vector of size "
   1725            << num_components;
   1726 
   1727   CompileSuccessfully(GenerateShaderCode(body.str()));
   1728   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1729   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1730 }
   1731 
   1732 TEST_P(ValidateGlslStd450Pack, VNotFloatVector) {
   1733   const std::string ext_inst_name = GetParam();
   1734   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1735   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1736   const uint32_t total_bit_width = num_components * packed_bit_width;
   1737   const std::string vec_str =
   1738       num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n";
   1739 
   1740   std::ostringstream body;
   1741   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
   1742        << ext_inst_name << vec_str;
   1743 
   1744   std::ostringstream expected;
   1745   expected << "GLSL.std.450 " << ext_inst_name
   1746            << ": expected operand V to be a 32-bit float vector of size "
   1747            << num_components;
   1748 
   1749   CompileSuccessfully(GenerateShaderCode(body.str()));
   1750   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1751   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1752 }
   1753 
   1754 TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) {
   1755   const std::string ext_inst_name = GetParam();
   1756   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1757   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1758   const uint32_t total_bit_width = num_components * packed_bit_width;
   1759   const std::string vec_str =
   1760       num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n";
   1761 
   1762   std::ostringstream body;
   1763   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
   1764        << ext_inst_name << vec_str;
   1765 
   1766   std::ostringstream expected;
   1767   expected << "GLSL.std.450 " << ext_inst_name
   1768            << ": expected operand V to be a 32-bit float vector of size "
   1769            << num_components;
   1770 
   1771   CompileSuccessfully(GenerateShaderCode(body.str()));
   1772   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1773   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1774 }
   1775 
   1776 TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) {
   1777   const std::string ext_inst_name = GetParam();
   1778   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1779   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1780   const uint32_t total_bit_width = num_components * packed_bit_width;
   1781   const std::string vec_str =
   1782       num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
   1783 
   1784   std::ostringstream body;
   1785   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
   1786        << ext_inst_name << vec_str;
   1787 
   1788   std::ostringstream expected;
   1789   expected << "GLSL.std.450 " << ext_inst_name
   1790            << ": expected operand V to be a 32-bit float vector of size "
   1791            << num_components;
   1792 
   1793   CompileSuccessfully(GenerateShaderCode(body.str()));
   1794   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1795   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1796 }
   1797 
   1798 INSTANTIATE_TEST_CASE_P(AllPack, ValidateGlslStd450Pack,
   1799                         ::testing::ValuesIn(std::vector<std::string>{
   1800                             "PackSnorm4x8",
   1801                             "PackUnorm4x8",
   1802                             "PackSnorm2x16",
   1803                             "PackUnorm2x16",
   1804                             "PackHalf2x16",
   1805                         }), );
   1806 
   1807 TEST_F(ValidateExtInst, PackDouble2x32Success) {
   1808   const std::string body = R"(
   1809 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01
   1810 )";
   1811 
   1812   CompileSuccessfully(GenerateShaderCode(body));
   1813   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1814 }
   1815 
   1816 TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) {
   1817   const std::string body = R"(
   1818 %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01
   1819 )";
   1820 
   1821   CompileSuccessfully(GenerateShaderCode(body));
   1822   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1823   EXPECT_THAT(getDiagnosticString(),
   1824               HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
   1825                         "be 64-bit float scalar type"));
   1826 }
   1827 
   1828 TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) {
   1829   const std::string body = R"(
   1830 %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01
   1831 )";
   1832 
   1833   CompileSuccessfully(GenerateShaderCode(body));
   1834   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1835   EXPECT_THAT(getDiagnosticString(),
   1836               HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
   1837                         "be 64-bit float scalar type"));
   1838 }
   1839 
   1840 TEST_F(ValidateExtInst, PackDouble2x32VNotVector) {
   1841   const std::string body = R"(
   1842 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1
   1843 )";
   1844 
   1845   CompileSuccessfully(GenerateShaderCode(body));
   1846   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1847   EXPECT_THAT(getDiagnosticString(),
   1848               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
   1849                         "a 32-bit int vector of size 2"));
   1850 }
   1851 
   1852 TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) {
   1853   const std::string body = R"(
   1854 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01
   1855 )";
   1856 
   1857   CompileSuccessfully(GenerateShaderCode(body));
   1858   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1859   EXPECT_THAT(getDiagnosticString(),
   1860               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
   1861                         "a 32-bit int vector of size 2"));
   1862 }
   1863 
   1864 TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) {
   1865   const std::string body = R"(
   1866 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01
   1867 )";
   1868 
   1869   CompileSuccessfully(GenerateShaderCode(body));
   1870   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1871   EXPECT_THAT(getDiagnosticString(),
   1872               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
   1873                         "a 32-bit int vector of size 2"));
   1874 }
   1875 
   1876 TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) {
   1877   const std::string body = R"(
   1878 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123
   1879 )";
   1880 
   1881   CompileSuccessfully(GenerateShaderCode(body));
   1882   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1883   EXPECT_THAT(getDiagnosticString(),
   1884               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
   1885                         "a 32-bit int vector of size 2"));
   1886 }
   1887 
   1888 TEST_P(ValidateGlslStd450Unpack, Success) {
   1889   const std::string ext_inst_name = GetParam();
   1890   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1891   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1892   const uint32_t total_bit_width = num_components * packed_bit_width;
   1893   const std::string result_type_str =
   1894       num_components == 2 ? "%f32vec2" : " %f32vec4";
   1895 
   1896   std::ostringstream body;
   1897   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   1898        << ext_inst_name << " %u" << total_bit_width << "_1\n";
   1899   body << "%val2 = OpExtInst " << result_type_str << " %extinst "
   1900        << ext_inst_name << " %s" << total_bit_width << "_1\n";
   1901   CompileSuccessfully(GenerateShaderCode(body.str()));
   1902   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1903 }
   1904 
   1905 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) {
   1906   const std::string ext_inst_name = GetParam();
   1907   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1908   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1909   const uint32_t total_bit_width = num_components * packed_bit_width;
   1910   const std::string result_type_str = "%f32";
   1911 
   1912   std::ostringstream body;
   1913   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   1914        << ext_inst_name << " %u" << total_bit_width << "_1\n";
   1915 
   1916   std::ostringstream expected;
   1917   expected << "GLSL.std.450 " << ext_inst_name
   1918            << ": expected Result Type to be a 32-bit float vector of size "
   1919            << num_components;
   1920 
   1921   CompileSuccessfully(GenerateShaderCode(body.str()));
   1922   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1923   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1924 }
   1925 
   1926 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) {
   1927   const std::string ext_inst_name = GetParam();
   1928   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1929   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1930   const uint32_t total_bit_width = num_components * packed_bit_width;
   1931   const std::string result_type_str =
   1932       num_components == 2 ? "%u32vec2" : " %u32vec4";
   1933 
   1934   std::ostringstream body;
   1935   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   1936        << ext_inst_name << " %u" << total_bit_width << "_1\n";
   1937 
   1938   std::ostringstream expected;
   1939   expected << "GLSL.std.450 " << ext_inst_name
   1940            << ": expected Result Type to be a 32-bit float vector of size "
   1941            << num_components;
   1942 
   1943   CompileSuccessfully(GenerateShaderCode(body.str()));
   1944   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1945   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1946 }
   1947 
   1948 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) {
   1949   const std::string ext_inst_name = GetParam();
   1950   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1951   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1952   const uint32_t total_bit_width = num_components * packed_bit_width;
   1953   const std::string result_type_str =
   1954       num_components == 2 ? "%f64vec2" : " %f64vec4";
   1955 
   1956   std::ostringstream body;
   1957   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   1958        << ext_inst_name << " %u" << total_bit_width << "_1\n";
   1959 
   1960   std::ostringstream expected;
   1961   expected << "GLSL.std.450 " << ext_inst_name
   1962            << ": expected Result Type to be a 32-bit float vector of size "
   1963            << num_components;
   1964 
   1965   CompileSuccessfully(GenerateShaderCode(body.str()));
   1966   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1967   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1968 }
   1969 
   1970 TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) {
   1971   const std::string ext_inst_name = GetParam();
   1972   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1973   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1974   const uint32_t total_bit_width = num_components * packed_bit_width;
   1975   const std::string result_type_str =
   1976       num_components == 4 ? "%f32vec2" : " %f32vec4";
   1977 
   1978   std::ostringstream body;
   1979   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   1980        << ext_inst_name << " %u" << total_bit_width << "_1\n";
   1981 
   1982   std::ostringstream expected;
   1983   expected << "GLSL.std.450 " << ext_inst_name
   1984            << ": expected Result Type to be a 32-bit float vector of size "
   1985            << num_components;
   1986 
   1987   CompileSuccessfully(GenerateShaderCode(body.str()));
   1988   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   1989   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   1990 }
   1991 
   1992 TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) {
   1993   const std::string ext_inst_name = GetParam();
   1994   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   1995   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   1996   const uint32_t total_bit_width = num_components * packed_bit_width;
   1997   const std::string result_type_str =
   1998       num_components == 2 ? "%f32vec2" : " %f32vec4";
   1999 
   2000   std::ostringstream body;
   2001   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   2002        << ext_inst_name << " %f" << total_bit_width << "_1\n";
   2003 
   2004   std::ostringstream expected;
   2005   expected << "GLSL.std.450 " << ext_inst_name
   2006            << ": expected operand P to be a " << total_bit_width
   2007            << "-bit int scalar";
   2008 
   2009   CompileSuccessfully(GenerateShaderCode(body.str()));
   2010   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2011   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   2012 }
   2013 
   2014 TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) {
   2015   const std::string ext_inst_name = GetParam();
   2016   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
   2017   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
   2018   const uint32_t total_bit_width = num_components * packed_bit_width;
   2019   const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32;
   2020   const std::string result_type_str =
   2021       num_components == 2 ? "%f32vec2" : " %f32vec4";
   2022 
   2023   std::ostringstream body;
   2024   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
   2025        << ext_inst_name << " %u" << wrong_bit_width << "_1\n";
   2026 
   2027   std::ostringstream expected;
   2028   expected << "GLSL.std.450 " << ext_inst_name
   2029            << ": expected operand P to be a " << total_bit_width
   2030            << "-bit int scalar";
   2031 
   2032   CompileSuccessfully(GenerateShaderCode(body.str()));
   2033   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2034   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
   2035 }
   2036 
   2037 INSTANTIATE_TEST_CASE_P(AllUnpack, ValidateGlslStd450Unpack,
   2038                         ::testing::ValuesIn(std::vector<std::string>{
   2039                             "UnpackSnorm4x8",
   2040                             "UnpackUnorm4x8",
   2041                             "UnpackSnorm2x16",
   2042                             "UnpackUnorm2x16",
   2043                             "UnpackHalf2x16",
   2044                         }), );
   2045 
   2046 TEST_F(ValidateExtInst, UnpackDouble2x32Success) {
   2047   const std::string body = R"(
   2048 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1
   2049 )";
   2050 
   2051   CompileSuccessfully(GenerateShaderCode(body));
   2052   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2053 }
   2054 
   2055 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) {
   2056   const std::string body = R"(
   2057 %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1
   2058 )";
   2059 
   2060   CompileSuccessfully(GenerateShaderCode(body));
   2061   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2062   EXPECT_THAT(getDiagnosticString(),
   2063               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
   2064                         "to be a 32-bit int vector of size 2"));
   2065 }
   2066 
   2067 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) {
   2068   const std::string body = R"(
   2069 %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1
   2070 )";
   2071 
   2072   CompileSuccessfully(GenerateShaderCode(body));
   2073   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2074   EXPECT_THAT(getDiagnosticString(),
   2075               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
   2076                         "to be a 32-bit int vector of size 2"));
   2077 }
   2078 
   2079 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) {
   2080   const std::string body = R"(
   2081 %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1
   2082 )";
   2083 
   2084   CompileSuccessfully(GenerateShaderCode(body));
   2085   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2086   EXPECT_THAT(getDiagnosticString(),
   2087               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
   2088                         "to be a 32-bit int vector of size 2"));
   2089 }
   2090 
   2091 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) {
   2092   const std::string body = R"(
   2093 %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1
   2094 )";
   2095 
   2096   CompileSuccessfully(GenerateShaderCode(body));
   2097   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2098   EXPECT_THAT(getDiagnosticString(),
   2099               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
   2100                         "to be a 32-bit int vector of size 2"));
   2101 }
   2102 
   2103 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) {
   2104   const std::string body = R"(
   2105 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1
   2106 )";
   2107 
   2108   CompileSuccessfully(GenerateShaderCode(body));
   2109   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2110   EXPECT_THAT(getDiagnosticString(),
   2111               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
   2112                         "be a 64-bit float scalar"));
   2113 }
   2114 
   2115 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) {
   2116   const std::string body = R"(
   2117 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1
   2118 )";
   2119 
   2120   CompileSuccessfully(GenerateShaderCode(body));
   2121   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2122   EXPECT_THAT(getDiagnosticString(),
   2123               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
   2124                         "be a 64-bit float scalar"));
   2125 }
   2126 
   2127 TEST_F(ValidateExtInst, GlslStd450LengthSuccess) {
   2128   const std::string body = R"(
   2129 %val1 = OpExtInst %f32 %extinst Length %f32_1
   2130 %val2 = OpExtInst %f32 %extinst Length %f32vec2_01
   2131 %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123
   2132 )";
   2133 
   2134   CompileSuccessfully(GenerateShaderCode(body));
   2135   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2136 }
   2137 
   2138 TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) {
   2139   const std::string body = R"(
   2140 %val1 = OpExtInst %u32 %extinst Length %f32vec2_01
   2141 )";
   2142 
   2143   CompileSuccessfully(GenerateShaderCode(body));
   2144   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2145   EXPECT_THAT(getDiagnosticString(),
   2146               HasSubstr("GLSL.std.450 Length: "
   2147                         "expected Result Type to be a float scalar type"));
   2148 }
   2149 
   2150 TEST_F(ValidateExtInst, GlslStd450LengthIntX) {
   2151   const std::string body = R"(
   2152 %val1 = OpExtInst %f32 %extinst Length %u32vec2_01
   2153 )";
   2154 
   2155   CompileSuccessfully(GenerateShaderCode(body));
   2156   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2157   EXPECT_THAT(getDiagnosticString(),
   2158               HasSubstr("GLSL.std.450 Length: "
   2159                         "expected operand X to be of float scalar or "
   2160                         "vector type"));
   2161 }
   2162 
   2163 TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) {
   2164   const std::string body = R"(
   2165 %val1 = OpExtInst %f64 %extinst Length %f32vec2_01
   2166 )";
   2167 
   2168   CompileSuccessfully(GenerateShaderCode(body));
   2169   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2170   EXPECT_THAT(getDiagnosticString(),
   2171               HasSubstr("GLSL.std.450 Length: "
   2172                         "expected operand X component type to be equal to "
   2173                         "Result Type"));
   2174 }
   2175 
   2176 TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) {
   2177   const std::string body = R"(
   2178 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1
   2179 %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12
   2180 %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234
   2181 )";
   2182 
   2183   CompileSuccessfully(GenerateShaderCode(body));
   2184   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2185 }
   2186 
   2187 TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) {
   2188   const std::string body = R"(
   2189 %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12
   2190 )";
   2191 
   2192   CompileSuccessfully(GenerateShaderCode(body));
   2193   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2194   EXPECT_THAT(getDiagnosticString(),
   2195               HasSubstr("GLSL.std.450 Distance: "
   2196                         "expected Result Type to be a float scalar type"));
   2197 }
   2198 
   2199 TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) {
   2200   const std::string body = R"(
   2201 %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1
   2202 )";
   2203 
   2204   CompileSuccessfully(GenerateShaderCode(body));
   2205   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2206   EXPECT_THAT(getDiagnosticString(),
   2207               HasSubstr("GLSL.std.450 Distance: "
   2208                         "expected operand P0 to be of float scalar or "
   2209                         "vector type"));
   2210 }
   2211 
   2212 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) {
   2213   const std::string body = R"(
   2214 %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12
   2215 )";
   2216 
   2217   CompileSuccessfully(GenerateShaderCode(body));
   2218   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2219   EXPECT_THAT(getDiagnosticString(),
   2220               HasSubstr("GLSL.std.450 Distance: "
   2221                         "expected operand P0 component type to be equal to "
   2222                         "Result Type"));
   2223 }
   2224 
   2225 TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) {
   2226   const std::string body = R"(
   2227 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1
   2228 )";
   2229 
   2230   CompileSuccessfully(GenerateShaderCode(body));
   2231   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2232   EXPECT_THAT(getDiagnosticString(),
   2233               HasSubstr("GLSL.std.450 Distance: "
   2234                         "expected operand P1 to be of float scalar or "
   2235                         "vector type"));
   2236 }
   2237 
   2238 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) {
   2239   const std::string body = R"(
   2240 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01
   2241 )";
   2242 
   2243   CompileSuccessfully(GenerateShaderCode(body));
   2244   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2245   EXPECT_THAT(getDiagnosticString(),
   2246               HasSubstr("GLSL.std.450 Distance: "
   2247                         "expected operand P1 component type to be equal to "
   2248                         "Result Type"));
   2249 }
   2250 
   2251 TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) {
   2252   const std::string body = R"(
   2253 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123
   2254 )";
   2255 
   2256   CompileSuccessfully(GenerateShaderCode(body));
   2257   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2258   EXPECT_THAT(getDiagnosticString(),
   2259               HasSubstr("GLSL.std.450 Distance: "
   2260                         "expected operands P0 and P1 to have the same number "
   2261                         "of components"));
   2262 }
   2263 
   2264 TEST_F(ValidateExtInst, GlslStd450CrossSuccess) {
   2265   const std::string body = R"(
   2266 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
   2267 )";
   2268 
   2269   CompileSuccessfully(GenerateShaderCode(body));
   2270   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2271 }
   2272 
   2273 TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) {
   2274   const std::string body = R"(
   2275 %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
   2276 )";
   2277 
   2278   CompileSuccessfully(GenerateShaderCode(body));
   2279   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2280   EXPECT_THAT(getDiagnosticString(),
   2281               HasSubstr("GLSL.std.450 Cross: "
   2282                         "expected Result Type to be a float vector type"));
   2283 }
   2284 
   2285 TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) {
   2286   const std::string body = R"(
   2287 %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123
   2288 )";
   2289 
   2290   CompileSuccessfully(GenerateShaderCode(body));
   2291   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2292   EXPECT_THAT(getDiagnosticString(),
   2293               HasSubstr("GLSL.std.450 Cross: "
   2294                         "expected Result Type to have 3 components"));
   2295 }
   2296 
   2297 TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) {
   2298   const std::string body = R"(
   2299 %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123
   2300 )";
   2301 
   2302   CompileSuccessfully(GenerateShaderCode(body));
   2303   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2304   EXPECT_THAT(getDiagnosticString(),
   2305               HasSubstr("GLSL.std.450 Cross: "
   2306                         "expected operand X type to be equal to Result Type"));
   2307 }
   2308 
   2309 TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) {
   2310   const std::string body = R"(
   2311 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012
   2312 )";
   2313 
   2314   CompileSuccessfully(GenerateShaderCode(body));
   2315   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2316   EXPECT_THAT(getDiagnosticString(),
   2317               HasSubstr("GLSL.std.450 Cross: "
   2318                         "expected operand Y type to be equal to Result Type"));
   2319 }
   2320 
   2321 TEST_F(ValidateExtInst, GlslStd450RefractSuccess) {
   2322   const std::string body = R"(
   2323 %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1
   2324 %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1
   2325 )";
   2326 
   2327   CompileSuccessfully(GenerateShaderCode(body));
   2328   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2329 }
   2330 
   2331 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) {
   2332   const std::string body = R"(
   2333 %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1
   2334 )";
   2335 
   2336   CompileSuccessfully(GenerateShaderCode(body));
   2337   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2338   EXPECT_THAT(getDiagnosticString(),
   2339               HasSubstr("GLSL.std.450 Refract: "
   2340                         "expected Result Type to be a float scalar or "
   2341                         "vector type"));
   2342 }
   2343 
   2344 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) {
   2345   const std::string body = R"(
   2346 %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1
   2347 )";
   2348 
   2349   CompileSuccessfully(GenerateShaderCode(body));
   2350   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2351   EXPECT_THAT(getDiagnosticString(),
   2352               HasSubstr("GLSL.std.450 Refract: "
   2353                         "expected operand I to be of type equal to "
   2354                         "Result Type"));
   2355 }
   2356 
   2357 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) {
   2358   const std::string body = R"(
   2359 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1
   2360 )";
   2361 
   2362   CompileSuccessfully(GenerateShaderCode(body));
   2363   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2364   EXPECT_THAT(getDiagnosticString(),
   2365               HasSubstr("GLSL.std.450 Refract: "
   2366                         "expected operand N to be of type equal to "
   2367                         "Result Type"));
   2368 }
   2369 
   2370 TEST_F(ValidateExtInst, GlslStd450RefractIntEta) {
   2371   const std::string body = R"(
   2372 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1
   2373 )";
   2374 
   2375   CompileSuccessfully(GenerateShaderCode(body));
   2376   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2377   EXPECT_THAT(getDiagnosticString(),
   2378               HasSubstr("GLSL.std.450 Refract: "
   2379                         "expected operand Eta to be a float scalar"));
   2380 }
   2381 
   2382 TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) {
   2383   // SPIR-V issue 337: Eta can be 64-bit float scalar.
   2384   const std::string body = R"(
   2385 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1
   2386 )";
   2387 
   2388   CompileSuccessfully(GenerateShaderCode(body));
   2389   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2390   EXPECT_THAT(getDiagnosticString(), Eq(""));
   2391 }
   2392 
   2393 TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) {
   2394   const std::string body = R"(
   2395 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01
   2396 )";
   2397 
   2398   CompileSuccessfully(GenerateShaderCode(body));
   2399   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2400   EXPECT_THAT(getDiagnosticString(),
   2401               HasSubstr("GLSL.std.450 Refract: "
   2402                         "expected operand Eta to be a float scalar"));
   2403 }
   2404 
   2405 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) {
   2406   const std::string body = R"(
   2407 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
   2408 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input
   2409 )";
   2410 
   2411   CompileSuccessfully(
   2412       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2413   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2414 }
   2415 
   2416 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
   2417   const std::string body = R"(
   2418 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
   2419 )";
   2420 
   2421   CompileSuccessfully(GenerateShaderCode(body));
   2422   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
   2423   EXPECT_THAT(getDiagnosticString(),
   2424               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
   2425                         "capability InterpolationFunction"));
   2426 }
   2427 
   2428 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
   2429   const std::string body = R"(
   2430 %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
   2431 )";
   2432 
   2433   CompileSuccessfully(
   2434       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2435   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2436   EXPECT_THAT(getDiagnosticString(),
   2437               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
   2438                         "expected Result Type to be a 32-bit float scalar "
   2439                         "or vector type"));
   2440 }
   2441 
   2442 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
   2443   const std::string body = R"(
   2444 %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
   2445 )";
   2446 
   2447   CompileSuccessfully(
   2448       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2449   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2450   EXPECT_THAT(getDiagnosticString(),
   2451               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
   2452                         "expected Result Type to be a 32-bit float scalar "
   2453                         "or vector type"));
   2454 }
   2455 
   2456 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
   2457   const std::string body = R"(
   2458 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
   2459 )";
   2460 
   2461   CompileSuccessfully(
   2462       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2463   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2464   EXPECT_THAT(getDiagnosticString(),
   2465               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
   2466                         "expected Interpolant to be a pointer"));
   2467 }
   2468 
   2469 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
   2470   const std::string body = R"(
   2471 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
   2472 )";
   2473 
   2474   CompileSuccessfully(
   2475       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2476   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2477   EXPECT_THAT(getDiagnosticString(),
   2478               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
   2479                         "expected Interpolant data type to be equal to "
   2480                         "Result Type"));
   2481 }
   2482 
   2483 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
   2484   const std::string body = R"(
   2485 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
   2486 )";
   2487 
   2488   CompileSuccessfully(
   2489       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2490   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2491   EXPECT_THAT(getDiagnosticString(),
   2492               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
   2493                         "expected Interpolant storage class to be Input"));
   2494 }
   2495 
   2496 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
   2497   const std::string body = R"(
   2498 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
   2499 )";
   2500 
   2501   CompileSuccessfully(GenerateShaderCode(
   2502       body, "OpCapability InterpolationFunction\n", "Vertex"));
   2503   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   2504   EXPECT_THAT(getDiagnosticString(),
   2505               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
   2506                         "Fragment execution model"));
   2507 }
   2508 
   2509 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
   2510   const std::string body = R"(
   2511 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
   2512 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
   2513 )";
   2514 
   2515   CompileSuccessfully(
   2516       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2517   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2518 }
   2519 
   2520 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
   2521   const std::string body = R"(
   2522 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
   2523 )";
   2524 
   2525   CompileSuccessfully(GenerateShaderCode(body));
   2526   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
   2527   EXPECT_THAT(getDiagnosticString(),
   2528               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
   2529                         "capability InterpolationFunction"));
   2530 }
   2531 
   2532 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
   2533   const std::string body = R"(
   2534 %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
   2535 )";
   2536 
   2537   CompileSuccessfully(
   2538       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2539   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2540   EXPECT_THAT(getDiagnosticString(),
   2541               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2542                         "expected Result Type to be a 32-bit float scalar "
   2543                         "or vector type"));
   2544 }
   2545 
   2546 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
   2547   const std::string body = R"(
   2548 %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
   2549 )";
   2550 
   2551   CompileSuccessfully(
   2552       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2553   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2554   EXPECT_THAT(getDiagnosticString(),
   2555               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2556                         "expected Result Type to be a 32-bit float scalar "
   2557                         "or vector type"));
   2558 }
   2559 
   2560 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
   2561   const std::string body = R"(
   2562 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
   2563 )";
   2564 
   2565   CompileSuccessfully(
   2566       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2567   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2568   EXPECT_THAT(getDiagnosticString(),
   2569               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2570                         "expected Interpolant to be a pointer"));
   2571 }
   2572 
   2573 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
   2574   const std::string body = R"(
   2575 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
   2576 )";
   2577 
   2578   CompileSuccessfully(
   2579       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2580   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2581   EXPECT_THAT(getDiagnosticString(),
   2582               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2583                         "expected Interpolant data type to be equal to "
   2584                         "Result Type"));
   2585 }
   2586 
   2587 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
   2588   const std::string body = R"(
   2589 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
   2590 )";
   2591 
   2592   CompileSuccessfully(
   2593       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2594   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2595   EXPECT_THAT(getDiagnosticString(),
   2596               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2597                         "expected Interpolant storage class to be Input"));
   2598 }
   2599 
   2600 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
   2601   const std::string body = R"(
   2602 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
   2603 )";
   2604 
   2605   CompileSuccessfully(
   2606       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2607   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2608   EXPECT_THAT(getDiagnosticString(),
   2609               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2610                         "expected Sample to be 32-bit integer"));
   2611 }
   2612 
   2613 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
   2614   const std::string body = R"(
   2615 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
   2616 )";
   2617 
   2618   CompileSuccessfully(
   2619       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2620   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2621   EXPECT_THAT(getDiagnosticString(),
   2622               HasSubstr("GLSL.std.450 InterpolateAtSample: "
   2623                         "expected Sample to be 32-bit integer"));
   2624 }
   2625 
   2626 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
   2627   const std::string body = R"(
   2628 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
   2629 )";
   2630 
   2631   CompileSuccessfully(GenerateShaderCode(
   2632       body, "OpCapability InterpolationFunction\n", "Vertex"));
   2633   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   2634   EXPECT_THAT(getDiagnosticString(),
   2635               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
   2636                         "Fragment execution model"));
   2637 }
   2638 
   2639 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
   2640   const std::string body = R"(
   2641 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
   2642 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
   2643 )";
   2644 
   2645   CompileSuccessfully(
   2646       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2647   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2648 }
   2649 
   2650 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
   2651   const std::string body = R"(
   2652 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
   2653 )";
   2654 
   2655   CompileSuccessfully(GenerateShaderCode(body));
   2656   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
   2657   EXPECT_THAT(getDiagnosticString(),
   2658               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
   2659                         "capability InterpolationFunction"));
   2660 }
   2661 
   2662 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
   2663   const std::string body = R"(
   2664 %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
   2665 )";
   2666 
   2667   CompileSuccessfully(
   2668       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2669   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2670   EXPECT_THAT(getDiagnosticString(),
   2671               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2672                         "expected Result Type to be a 32-bit float scalar "
   2673                         "or vector type"));
   2674 }
   2675 
   2676 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
   2677   const std::string body = R"(
   2678 %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
   2679 )";
   2680 
   2681   CompileSuccessfully(
   2682       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2683   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2684   EXPECT_THAT(getDiagnosticString(),
   2685               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2686                         "expected Result Type to be a 32-bit float scalar "
   2687                         "or vector type"));
   2688 }
   2689 
   2690 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
   2691   const std::string body = R"(
   2692 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
   2693 )";
   2694 
   2695   CompileSuccessfully(
   2696       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2697   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2698   EXPECT_THAT(getDiagnosticString(),
   2699               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2700                         "expected Interpolant to be a pointer"));
   2701 }
   2702 
   2703 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
   2704   const std::string body = R"(
   2705 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
   2706 )";
   2707 
   2708   CompileSuccessfully(
   2709       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2710   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2711   EXPECT_THAT(getDiagnosticString(),
   2712               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2713                         "expected Interpolant data type to be equal to "
   2714                         "Result Type"));
   2715 }
   2716 
   2717 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
   2718   const std::string body = R"(
   2719 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
   2720 )";
   2721 
   2722   CompileSuccessfully(
   2723       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2724   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2725   EXPECT_THAT(getDiagnosticString(),
   2726               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2727                         "expected Interpolant storage class to be Input"));
   2728 }
   2729 
   2730 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
   2731   const std::string body = R"(
   2732 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
   2733 )";
   2734 
   2735   CompileSuccessfully(
   2736       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2737   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2738   EXPECT_THAT(getDiagnosticString(),
   2739               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2740                         "expected Offset to be a vector of 2 32-bit floats"));
   2741 }
   2742 
   2743 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
   2744   const std::string body = R"(
   2745 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
   2746 )";
   2747 
   2748   CompileSuccessfully(
   2749       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2750   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2751   EXPECT_THAT(getDiagnosticString(),
   2752               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2753                         "expected Offset to be a vector of 2 32-bit floats"));
   2754 }
   2755 
   2756 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
   2757   const std::string body = R"(
   2758 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
   2759 )";
   2760 
   2761   CompileSuccessfully(
   2762       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2763   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2764   EXPECT_THAT(getDiagnosticString(),
   2765               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2766                         "expected Offset to be a vector of 2 32-bit floats"));
   2767 }
   2768 
   2769 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
   2770   const std::string body = R"(
   2771 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
   2772 )";
   2773 
   2774   CompileSuccessfully(
   2775       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
   2776   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2777   EXPECT_THAT(getDiagnosticString(),
   2778               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
   2779                         "expected Offset to be a vector of 2 32-bit floats"));
   2780 }
   2781 
   2782 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
   2783   const std::string body = R"(
   2784 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
   2785 )";
   2786 
   2787   CompileSuccessfully(GenerateShaderCode(
   2788       body, "OpCapability InterpolationFunction\n", "Vertex"));
   2789   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   2790   EXPECT_THAT(getDiagnosticString(),
   2791               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
   2792                         "Fragment execution model"));
   2793 }
   2794 
   2795 TEST_P(ValidateOpenCLStdSqrtLike, Success) {
   2796   const std::string ext_inst_name = GetParam();
   2797   std::ostringstream ss;
   2798   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
   2799   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   2800      << " %f32vec2_01\n";
   2801   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
   2802      << " %f32vec4_0123\n";
   2803   ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
   2804   CompileSuccessfully(GenerateKernelCode(ss.str()));
   2805   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2806 }
   2807 
   2808 TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
   2809   const std::string ext_inst_name = GetParam();
   2810   const std::string body =
   2811       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
   2812 
   2813   CompileSuccessfully(GenerateKernelCode(body));
   2814   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2815   EXPECT_THAT(getDiagnosticString(),
   2816               HasSubstr("OpenCL.std " + ext_inst_name +
   2817                         ": expected Result Type to be a float scalar "
   2818                         "or vector type"));
   2819 }
   2820 
   2821 TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
   2822   const std::string ext_inst_name = GetParam();
   2823   const std::string body =
   2824       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
   2825 
   2826   CompileSuccessfully(GenerateKernelCode(body));
   2827   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2828   EXPECT_THAT(getDiagnosticString(),
   2829               HasSubstr("OpenCL.std " + ext_inst_name +
   2830                         ": expected types of all operands to be equal to "
   2831                         "Result Type"));
   2832 }
   2833 
   2834 INSTANTIATE_TEST_CASE_P(
   2835     AllSqrtLike, ValidateOpenCLStdSqrtLike,
   2836     ::testing::ValuesIn(std::vector<std::string>{
   2837         "acos",         "acosh",       "acospi",       "asin",
   2838         "asinh",        "asinpi",      "atan",         "atanh",
   2839         "atanpi",       "cbrt",        "ceil",         "cos",
   2840         "cosh",         "cospi",       "erfc",         "erf",
   2841         "exp",          "exp2",        "exp10",        "expm1",
   2842         "fabs",         "floor",       "log",          "log2",
   2843         "log10",        "log1p",       "logb",         "rint",
   2844         "round",        "rsqrt",       "sin",          "sinh",
   2845         "sinpi",        "sqrt",        "tan",          "tanh",
   2846         "tanpi",        "tgamma",      "trunc",        "half_cos",
   2847         "half_exp",     "half_exp2",   "half_exp10",   "half_log",
   2848         "half_log2",    "half_log10",  "half_recip",   "half_rsqrt",
   2849         "half_sin",     "half_sqrt",   "half_tan",     "lgamma",
   2850         "native_cos",   "native_exp",  "native_exp2",  "native_exp10",
   2851         "native_log",   "native_log2", "native_log10", "native_recip",
   2852         "native_rsqrt", "native_sin",  "native_sqrt",  "native_tan",
   2853         "degrees",      "radians",     "sign",
   2854     }), );
   2855 
   2856 TEST_P(ValidateOpenCLStdFMinLike, Success) {
   2857   const std::string ext_inst_name = GetParam();
   2858   std::ostringstream ss;
   2859   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   2860      << " %f32_0 %f32_1\n";
   2861   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   2862      << " %f32vec2_01 %f32vec2_12\n";
   2863   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
   2864      << " %f64_0 %f64_0\n";
   2865   CompileSuccessfully(GenerateKernelCode(ss.str()));
   2866   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2867 }
   2868 
   2869 TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
   2870   const std::string ext_inst_name = GetParam();
   2871   const std::string body =
   2872       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
   2873 
   2874   CompileSuccessfully(GenerateKernelCode(body));
   2875   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2876   EXPECT_THAT(getDiagnosticString(),
   2877               HasSubstr("OpenCL.std " + ext_inst_name +
   2878                         ": expected Result Type to be a float scalar "
   2879                         "or vector type"));
   2880 }
   2881 
   2882 TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
   2883   const std::string ext_inst_name = GetParam();
   2884   const std::string body =
   2885       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
   2886 
   2887   CompileSuccessfully(GenerateKernelCode(body));
   2888   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2889   EXPECT_THAT(getDiagnosticString(),
   2890               HasSubstr("OpenCL.std " + ext_inst_name +
   2891                         ": expected types of all operands to be equal to "
   2892                         "Result Type"));
   2893 }
   2894 
   2895 TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
   2896   const std::string ext_inst_name = GetParam();
   2897   const std::string body =
   2898       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
   2899 
   2900   CompileSuccessfully(GenerateKernelCode(body));
   2901   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2902   EXPECT_THAT(getDiagnosticString(),
   2903               HasSubstr("OpenCL.std " + ext_inst_name +
   2904                         ": expected types of all operands to be equal to "
   2905                         "Result Type"));
   2906 }
   2907 
   2908 INSTANTIATE_TEST_CASE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
   2909                         ::testing::ValuesIn(std::vector<std::string>{
   2910                             "atan2",     "atan2pi",       "copysign",
   2911                             "fdim",      "fmax",          "fmin",
   2912                             "fmod",      "maxmag",        "minmag",
   2913                             "hypot",     "nextafter",     "pow",
   2914                             "powr",      "remainder",     "half_divide",
   2915                             "half_powr", "native_divide", "native_powr",
   2916                             "step",      "fmax_common",   "fmin_common",
   2917                         }), );
   2918 
   2919 TEST_P(ValidateOpenCLStdFClampLike, Success) {
   2920   const std::string ext_inst_name = GetParam();
   2921   std::ostringstream ss;
   2922   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   2923      << " %f32_0 %f32_1 %f32_2\n";
   2924   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   2925      << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
   2926   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
   2927      << " %f64_0 %f64_0 %f64_1\n";
   2928   CompileSuccessfully(GenerateKernelCode(ss.str()));
   2929   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   2930 }
   2931 
   2932 TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
   2933   const std::string ext_inst_name = GetParam();
   2934   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   2935                            " %f32_0 %f32_1 %f32_2\n";
   2936 
   2937   CompileSuccessfully(GenerateKernelCode(body));
   2938   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2939   EXPECT_THAT(getDiagnosticString(),
   2940               HasSubstr("OpenCL.std " + ext_inst_name +
   2941                         ": expected Result Type to be a float scalar "
   2942                         "or vector type"));
   2943 }
   2944 
   2945 TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
   2946   const std::string ext_inst_name = GetParam();
   2947   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   2948                            " %u32_0 %f32_0 %f32_1\n";
   2949 
   2950   CompileSuccessfully(GenerateKernelCode(body));
   2951   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2952   EXPECT_THAT(getDiagnosticString(),
   2953               HasSubstr("OpenCL.std " + ext_inst_name +
   2954                         ": expected types of all operands to be equal to "
   2955                         "Result Type"));
   2956 }
   2957 
   2958 TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
   2959   const std::string ext_inst_name = GetParam();
   2960   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   2961                            " %f32_0 %u32_0 %f32_1\n";
   2962 
   2963   CompileSuccessfully(GenerateKernelCode(body));
   2964   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2965   EXPECT_THAT(getDiagnosticString(),
   2966               HasSubstr("OpenCL.std " + ext_inst_name +
   2967                         ": expected types of all operands to be equal to "
   2968                         "Result Type"));
   2969 }
   2970 
   2971 TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
   2972   const std::string ext_inst_name = GetParam();
   2973   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   2974                            " %f32_1 %f32_0 %u32_2\n";
   2975 
   2976   CompileSuccessfully(GenerateKernelCode(body));
   2977   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   2978   EXPECT_THAT(getDiagnosticString(),
   2979               HasSubstr("OpenCL.std " + ext_inst_name +
   2980                         ": expected types of all operands to be equal to "
   2981                         "Result Type"));
   2982 }
   2983 
   2984 INSTANTIATE_TEST_CASE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
   2985                         ::testing::ValuesIn(std::vector<std::string>{
   2986                             "fma",
   2987                             "mad",
   2988                             "fclamp",
   2989                             "mix",
   2990                             "smoothstep",
   2991                         }), );
   2992 
   2993 TEST_P(ValidateOpenCLStdSAbsLike, Success) {
   2994   const std::string ext_inst_name = GetParam();
   2995   std::ostringstream ss;
   2996   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
   2997   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
   2998   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
   2999   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
   3000   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3001      << " %u32vec2_01\n";
   3002   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3003      << " %u32vec2_01\n";
   3004   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3005      << " %u32vec2_01\n";
   3006   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3007      << " %u32vec2_01\n";
   3008   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3009   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3010 }
   3011 
   3012 TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
   3013   const std::string ext_inst_name = GetParam();
   3014   const std::string body =
   3015       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
   3016 
   3017   CompileSuccessfully(GenerateKernelCode(body));
   3018   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3019   EXPECT_THAT(getDiagnosticString(),
   3020               HasSubstr("OpenCL.std " + ext_inst_name +
   3021                         ": expected Result Type to be an int scalar "
   3022                         "or vector type"));
   3023 }
   3024 
   3025 TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
   3026   const std::string ext_inst_name = GetParam();
   3027   const std::string body =
   3028       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
   3029 
   3030   CompileSuccessfully(GenerateKernelCode(body));
   3031   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3032   EXPECT_THAT(
   3033       getDiagnosticString(),
   3034       HasSubstr("OpenCL.std " + ext_inst_name +
   3035                 ": expected types of all operands to be equal to Result Type"));
   3036 }
   3037 
   3038 TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
   3039   const std::string ext_inst_name = GetParam();
   3040   const std::string body =
   3041       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
   3042 
   3043   CompileSuccessfully(GenerateKernelCode(body));
   3044   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3045   EXPECT_THAT(
   3046       getDiagnosticString(),
   3047       HasSubstr("OpenCL.std " + ext_inst_name +
   3048                 ": expected types of all operands to be equal to Result Type"));
   3049 }
   3050 
   3051 INSTANTIATE_TEST_CASE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
   3052                         ::testing::ValuesIn(std::vector<std::string>{
   3053                             "s_abs",
   3054                             "clz",
   3055                             "ctz",
   3056                             "popcount",
   3057                             "u_abs",
   3058                         }), );
   3059 
   3060 TEST_P(ValidateOpenCLStdUMinLike, Success) {
   3061   const std::string ext_inst_name = GetParam();
   3062   std::ostringstream ss;
   3063   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   3064      << " %u32_1 %u32_2\n";
   3065   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
   3066      << " %u32_1 %u32_2\n";
   3067   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
   3068      << " %u32_1 %u32_2\n";
   3069   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
   3070      << " %u32_1 %u32_2\n";
   3071   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3072      << " %u32vec2_01 %u32vec2_01\n";
   3073   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3074      << " %u32vec2_01 %u32vec2_01\n";
   3075   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3076      << " %u32vec2_01 %u32vec2_01\n";
   3077   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3078      << " %u32vec2_01 %u32vec2_01\n";
   3079   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
   3080      << " %u64_1 %u64_0\n";
   3081   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3082   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3083 }
   3084 
   3085 TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
   3086   const std::string ext_inst_name = GetParam();
   3087   const std::string body =
   3088       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
   3089 
   3090   CompileSuccessfully(GenerateKernelCode(body));
   3091   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3092   EXPECT_THAT(getDiagnosticString(),
   3093               HasSubstr("OpenCL.std " + ext_inst_name +
   3094                         ": expected Result Type to be an int scalar "
   3095                         "or vector type"));
   3096 }
   3097 
   3098 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
   3099   const std::string ext_inst_name = GetParam();
   3100   const std::string body =
   3101       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
   3102 
   3103   CompileSuccessfully(GenerateKernelCode(body));
   3104   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3105   EXPECT_THAT(
   3106       getDiagnosticString(),
   3107       HasSubstr("OpenCL.std " + ext_inst_name +
   3108                 ": expected types of all operands to be equal to Result Type"));
   3109 }
   3110 
   3111 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
   3112   const std::string ext_inst_name = GetParam();
   3113   const std::string body =
   3114       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
   3115 
   3116   CompileSuccessfully(GenerateKernelCode(body));
   3117   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3118   EXPECT_THAT(
   3119       getDiagnosticString(),
   3120       HasSubstr("OpenCL.std " + ext_inst_name +
   3121                 ": expected types of all operands to be equal to Result Type"));
   3122 }
   3123 
   3124 TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
   3125   const std::string ext_inst_name = GetParam();
   3126   const std::string body =
   3127       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
   3128 
   3129   CompileSuccessfully(GenerateKernelCode(body));
   3130   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3131   EXPECT_THAT(
   3132       getDiagnosticString(),
   3133       HasSubstr("OpenCL.std " + ext_inst_name +
   3134                 ": expected types of all operands to be equal to Result Type"));
   3135 }
   3136 
   3137 TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
   3138   const std::string ext_inst_name = GetParam();
   3139   const std::string body =
   3140       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
   3141 
   3142   CompileSuccessfully(GenerateKernelCode(body));
   3143   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3144   EXPECT_THAT(
   3145       getDiagnosticString(),
   3146       HasSubstr("OpenCL.std " + ext_inst_name +
   3147                 ": expected types of all operands to be equal to Result Type"));
   3148 }
   3149 
   3150 INSTANTIATE_TEST_CASE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
   3151                         ::testing::ValuesIn(std::vector<std::string>{
   3152                             "s_max",
   3153                             "u_max",
   3154                             "s_min",
   3155                             "u_min",
   3156                             "s_abs_diff",
   3157                             "s_add_sat",
   3158                             "u_add_sat",
   3159                             "s_mul_hi",
   3160                             "rotate",
   3161                             "s_sub_sat",
   3162                             "u_sub_sat",
   3163                             "s_hadd",
   3164                             "u_hadd",
   3165                             "s_rhadd",
   3166                             "u_rhadd",
   3167                             "u_abs_diff",
   3168                             "u_mul_hi",
   3169                         }), );
   3170 
   3171 TEST_P(ValidateOpenCLStdUClampLike, Success) {
   3172   const std::string ext_inst_name = GetParam();
   3173   std::ostringstream ss;
   3174   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   3175      << " %u32_0 %u32_1 %u32_2\n";
   3176   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
   3177      << " %u32_0 %u32_1 %u32_2\n";
   3178   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
   3179      << " %u32_0 %u32_1 %u32_2\n";
   3180   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
   3181      << " %u32_0 %u32_1 %u32_2\n";
   3182   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3183      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3184   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3185      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3186   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3187      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3188   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3189      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3190   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
   3191      << " %u64_1 %u64_0 %u64_1\n";
   3192   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3193   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3194 }
   3195 
   3196 TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
   3197   const std::string ext_inst_name = GetParam();
   3198   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3199                            " %u32_0 %u32_0 %u32_1\n";
   3200 
   3201   CompileSuccessfully(GenerateKernelCode(body));
   3202   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3203   EXPECT_THAT(getDiagnosticString(),
   3204               HasSubstr("OpenCL.std " + ext_inst_name +
   3205                         ": expected Result Type to be an int scalar "
   3206                         "or vector type"));
   3207 }
   3208 
   3209 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
   3210   const std::string ext_inst_name = GetParam();
   3211   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3212                            " %f32_0 %u32_0 %u32_1\n";
   3213 
   3214   CompileSuccessfully(GenerateKernelCode(body));
   3215   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3216   EXPECT_THAT(
   3217       getDiagnosticString(),
   3218       HasSubstr("OpenCL.std " + ext_inst_name +
   3219                 ": expected types of all operands to be equal to Result Type"));
   3220 }
   3221 
   3222 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
   3223   const std::string ext_inst_name = GetParam();
   3224   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3225                            " %u32_0 %f32_0 %u32_1\n";
   3226 
   3227   CompileSuccessfully(GenerateKernelCode(body));
   3228   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3229   EXPECT_THAT(
   3230       getDiagnosticString(),
   3231       HasSubstr("OpenCL.std " + ext_inst_name +
   3232                 ": expected types of all operands to be equal to Result Type"));
   3233 }
   3234 
   3235 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
   3236   const std::string ext_inst_name = GetParam();
   3237   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3238                            " %u32_0 %u32_0 %f32_1\n";
   3239 
   3240   CompileSuccessfully(GenerateKernelCode(body));
   3241   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3242   EXPECT_THAT(
   3243       getDiagnosticString(),
   3244       HasSubstr("OpenCL.std " + ext_inst_name +
   3245                 ": expected types of all operands to be equal to Result Type"));
   3246 }
   3247 
   3248 TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
   3249   const std::string ext_inst_name = GetParam();
   3250   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3251                            " %f32_0 %u32_0 %u64_1\n";
   3252 
   3253   CompileSuccessfully(GenerateKernelCode(body));
   3254   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3255   EXPECT_THAT(
   3256       getDiagnosticString(),
   3257       HasSubstr("OpenCL.std " + ext_inst_name +
   3258                 ": expected types of all operands to be equal to Result Type"));
   3259 }
   3260 
   3261 TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
   3262   const std::string ext_inst_name = GetParam();
   3263   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3264                            " %u32_0 %f32_0 %u64_1\n";
   3265 
   3266   CompileSuccessfully(GenerateKernelCode(body));
   3267   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3268   EXPECT_THAT(
   3269       getDiagnosticString(),
   3270       HasSubstr("OpenCL.std " + ext_inst_name +
   3271                 ": expected types of all operands to be equal to Result Type"));
   3272 }
   3273 
   3274 TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
   3275   const std::string ext_inst_name = GetParam();
   3276   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3277                            " %u32_0 %u32_0 %u64_1\n";
   3278 
   3279   CompileSuccessfully(GenerateKernelCode(body));
   3280   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3281   EXPECT_THAT(
   3282       getDiagnosticString(),
   3283       HasSubstr("OpenCL.std " + ext_inst_name +
   3284                 ": expected types of all operands to be equal to Result Type"));
   3285 }
   3286 
   3287 INSTANTIATE_TEST_CASE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
   3288                         ::testing::ValuesIn(std::vector<std::string>{
   3289                             "s_clamp",
   3290                             "u_clamp",
   3291                             "s_mad_hi",
   3292                             "u_mad_sat",
   3293                             "s_mad_sat",
   3294                             "u_mad_hi",
   3295                         }), );
   3296 
   3297 // -------------------------------------------------------------
   3298 TEST_P(ValidateOpenCLStdUMul24Like, Success) {
   3299   const std::string ext_inst_name = GetParam();
   3300   std::ostringstream ss;
   3301   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   3302      << " %u32_1 %u32_2\n";
   3303   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
   3304      << " %u32_1 %u32_2\n";
   3305   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
   3306      << " %u32_1 %u32_2\n";
   3307   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
   3308      << " %u32_1 %u32_2\n";
   3309   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3310      << " %u32vec2_01 %u32vec2_01\n";
   3311   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3312      << " %u32vec2_01 %u32vec2_01\n";
   3313   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3314      << " %u32vec2_01 %u32vec2_01\n";
   3315   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3316      << " %u32vec2_01 %u32vec2_01\n";
   3317   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3318   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3319 }
   3320 
   3321 TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
   3322   const std::string ext_inst_name = GetParam();
   3323   const std::string body =
   3324       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
   3325 
   3326   CompileSuccessfully(GenerateKernelCode(body));
   3327   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3328   EXPECT_THAT(
   3329       getDiagnosticString(),
   3330       HasSubstr(
   3331           "OpenCL.std " + ext_inst_name +
   3332           ": expected Result Type to be a 32-bit int scalar or vector type"));
   3333 }
   3334 
   3335 TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
   3336   const std::string ext_inst_name = GetParam();
   3337   const std::string body =
   3338       "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
   3339 
   3340   CompileSuccessfully(GenerateKernelCode(body));
   3341   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3342   EXPECT_THAT(
   3343       getDiagnosticString(),
   3344       HasSubstr(
   3345           "OpenCL.std " + ext_inst_name +
   3346           ": expected Result Type to be a 32-bit int scalar or vector type"));
   3347 }
   3348 
   3349 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
   3350   const std::string ext_inst_name = GetParam();
   3351   const std::string body =
   3352       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
   3353 
   3354   CompileSuccessfully(GenerateKernelCode(body));
   3355   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3356   EXPECT_THAT(
   3357       getDiagnosticString(),
   3358       HasSubstr("OpenCL.std " + ext_inst_name +
   3359                 ": expected types of all operands to be equal to Result Type"));
   3360 }
   3361 
   3362 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
   3363   const std::string ext_inst_name = GetParam();
   3364   const std::string body =
   3365       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
   3366 
   3367   CompileSuccessfully(GenerateKernelCode(body));
   3368   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3369   EXPECT_THAT(
   3370       getDiagnosticString(),
   3371       HasSubstr("OpenCL.std " + ext_inst_name +
   3372                 ": expected types of all operands to be equal to Result Type"));
   3373 }
   3374 
   3375 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
   3376   const std::string ext_inst_name = GetParam();
   3377   const std::string body =
   3378       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
   3379 
   3380   CompileSuccessfully(GenerateKernelCode(body));
   3381   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3382   EXPECT_THAT(
   3383       getDiagnosticString(),
   3384       HasSubstr("OpenCL.std " + ext_inst_name +
   3385                 ": expected types of all operands to be equal to Result Type"));
   3386 }
   3387 
   3388 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
   3389   const std::string ext_inst_name = GetParam();
   3390   const std::string body =
   3391       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
   3392 
   3393   CompileSuccessfully(GenerateKernelCode(body));
   3394   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3395   EXPECT_THAT(
   3396       getDiagnosticString(),
   3397       HasSubstr("OpenCL.std " + ext_inst_name +
   3398                 ": expected types of all operands to be equal to Result Type"));
   3399 }
   3400 
   3401 INSTANTIATE_TEST_CASE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
   3402                         ::testing::ValuesIn(std::vector<std::string>{
   3403                             "s_mul24",
   3404                             "u_mul24",
   3405                         }), );
   3406 
   3407 TEST_P(ValidateOpenCLStdUMad24Like, Success) {
   3408   const std::string ext_inst_name = GetParam();
   3409   std::ostringstream ss;
   3410   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   3411      << " %u32_0 %u32_1 %u32_2\n";
   3412   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
   3413      << " %u32_0 %u32_1 %u32_2\n";
   3414   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
   3415      << " %u32_0 %u32_1 %u32_2\n";
   3416   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
   3417      << " %u32_0 %u32_1 %u32_2\n";
   3418   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3419      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3420   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3421      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3422   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3423      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3424   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
   3425      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
   3426   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3427   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3428 }
   3429 
   3430 TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
   3431   const std::string ext_inst_name = GetParam();
   3432   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3433                            " %u32_0 %u32_0 %u32_1\n";
   3434 
   3435   CompileSuccessfully(GenerateKernelCode(body));
   3436   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3437   EXPECT_THAT(
   3438       getDiagnosticString(),
   3439       HasSubstr(
   3440           "OpenCL.std " + ext_inst_name +
   3441           ": expected Result Type to be a 32-bit int scalar or vector type"));
   3442 }
   3443 
   3444 TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
   3445   const std::string ext_inst_name = GetParam();
   3446   const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
   3447                            " %u64_0 %u64_0 %u64_1\n";
   3448 
   3449   CompileSuccessfully(GenerateKernelCode(body));
   3450   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3451   EXPECT_THAT(
   3452       getDiagnosticString(),
   3453       HasSubstr(
   3454           "OpenCL.std " + ext_inst_name +
   3455           ": expected Result Type to be a 32-bit int scalar or vector type"));
   3456 }
   3457 
   3458 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
   3459   const std::string ext_inst_name = GetParam();
   3460   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3461                            " %f32_0 %u32_0 %u32_1\n";
   3462 
   3463   CompileSuccessfully(GenerateKernelCode(body));
   3464   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3465   EXPECT_THAT(
   3466       getDiagnosticString(),
   3467       HasSubstr("OpenCL.std " + ext_inst_name +
   3468                 ": expected types of all operands to be equal to Result Type"));
   3469 }
   3470 
   3471 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
   3472   const std::string ext_inst_name = GetParam();
   3473   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3474                            " %u32_0 %f32_0 %u32_1\n";
   3475 
   3476   CompileSuccessfully(GenerateKernelCode(body));
   3477   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3478   EXPECT_THAT(
   3479       getDiagnosticString(),
   3480       HasSubstr("OpenCL.std " + ext_inst_name +
   3481                 ": expected types of all operands to be equal to Result Type"));
   3482 }
   3483 
   3484 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
   3485   const std::string ext_inst_name = GetParam();
   3486   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3487                            " %u32_0 %u32_0 %f32_1\n";
   3488 
   3489   CompileSuccessfully(GenerateKernelCode(body));
   3490   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3491   EXPECT_THAT(
   3492       getDiagnosticString(),
   3493       HasSubstr("OpenCL.std " + ext_inst_name +
   3494                 ": expected types of all operands to be equal to Result Type"));
   3495 }
   3496 
   3497 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
   3498   const std::string ext_inst_name = GetParam();
   3499   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3500                            " %f32_0 %u32_0 %u64_1\n";
   3501 
   3502   CompileSuccessfully(GenerateKernelCode(body));
   3503   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3504   EXPECT_THAT(
   3505       getDiagnosticString(),
   3506       HasSubstr("OpenCL.std " + ext_inst_name +
   3507                 ": expected types of all operands to be equal to Result Type"));
   3508 }
   3509 
   3510 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
   3511   const std::string ext_inst_name = GetParam();
   3512   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3513                            " %u32_0 %f32_0 %u64_1\n";
   3514 
   3515   CompileSuccessfully(GenerateKernelCode(body));
   3516   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3517   EXPECT_THAT(
   3518       getDiagnosticString(),
   3519       HasSubstr("OpenCL.std " + ext_inst_name +
   3520                 ": expected types of all operands to be equal to Result Type"));
   3521 }
   3522 
   3523 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
   3524   const std::string ext_inst_name = GetParam();
   3525   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3526                            " %u32_0 %u32_0 %u64_1\n";
   3527 
   3528   CompileSuccessfully(GenerateKernelCode(body));
   3529   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3530   EXPECT_THAT(
   3531       getDiagnosticString(),
   3532       HasSubstr("OpenCL.std " + ext_inst_name +
   3533                 ": expected types of all operands to be equal to Result Type"));
   3534 }
   3535 
   3536 INSTANTIATE_TEST_CASE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
   3537                         ::testing::ValuesIn(std::vector<std::string>{
   3538                             "s_mad24",
   3539                             "u_mad24",
   3540                         }), );
   3541 
   3542 TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
   3543   const std::string body = R"(
   3544 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
   3545 %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
   3546 )";
   3547 
   3548   CompileSuccessfully(GenerateKernelCode(body));
   3549   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3550 }
   3551 
   3552 TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
   3553   const std::string body = R"(
   3554 %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
   3555 )";
   3556 
   3557   CompileSuccessfully(GenerateKernelCode(body));
   3558   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3559   EXPECT_THAT(getDiagnosticString(),
   3560               HasSubstr("OpenCL.std cross: "
   3561                         "expected Result Type to be a float vector type"));
   3562 }
   3563 
   3564 TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
   3565   const std::string body = R"(
   3566 %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
   3567 )";
   3568 
   3569   CompileSuccessfully(GenerateKernelCode(body));
   3570   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3571   EXPECT_THAT(getDiagnosticString(),
   3572               HasSubstr("OpenCL.std cross: "
   3573                         "expected Result Type to have 3 or 4 components"));
   3574 }
   3575 
   3576 TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
   3577   const std::string body = R"(
   3578 %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
   3579 )";
   3580 
   3581   CompileSuccessfully(GenerateKernelCode(body));
   3582   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3583   EXPECT_THAT(getDiagnosticString(),
   3584               HasSubstr("OpenCL.std cross: "
   3585                         "expected operand X type to be equal to Result Type"));
   3586 }
   3587 
   3588 TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
   3589   const std::string body = R"(
   3590 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
   3591 )";
   3592 
   3593   CompileSuccessfully(GenerateKernelCode(body));
   3594   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3595   EXPECT_THAT(getDiagnosticString(),
   3596               HasSubstr("OpenCL.std cross: "
   3597                         "expected operand Y type to be equal to Result Type"));
   3598 }
   3599 
   3600 TEST_P(ValidateOpenCLStdLengthLike, Success) {
   3601   const std::string ext_inst_name = GetParam();
   3602   std::ostringstream ss;
   3603   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
   3604   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
   3605      << " %f32vec4_0123\n";
   3606 
   3607   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3608   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3609 }
   3610 
   3611 TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
   3612   const std::string ext_inst_name = GetParam();
   3613   const std::string body =
   3614       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
   3615 
   3616   CompileSuccessfully(GenerateKernelCode(body));
   3617   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3618   EXPECT_THAT(getDiagnosticString(),
   3619               HasSubstr("OpenCL.std " + ext_inst_name +
   3620                         ": "
   3621                         "expected Result Type to be a float scalar type"));
   3622 }
   3623 
   3624 TEST_P(ValidateOpenCLStdLengthLike, IntX) {
   3625   const std::string ext_inst_name = GetParam();
   3626   const std::string body =
   3627       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
   3628 
   3629   CompileSuccessfully(GenerateKernelCode(body));
   3630   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3631   EXPECT_THAT(getDiagnosticString(),
   3632               HasSubstr("OpenCL.std " + ext_inst_name +
   3633                         ": "
   3634                         "expected operand P to be a float scalar or vector"));
   3635 }
   3636 
   3637 TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
   3638   const std::string ext_inst_name = GetParam();
   3639   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3640                            " %f32vec8_01010101\n";
   3641 
   3642   CompileSuccessfully(GenerateKernelCode(body));
   3643   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3644   EXPECT_THAT(
   3645       getDiagnosticString(),
   3646       HasSubstr("OpenCL.std " + ext_inst_name +
   3647                 ": "
   3648                 "expected operand P to have no more than 4 components"));
   3649 }
   3650 
   3651 TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
   3652   const std::string ext_inst_name = GetParam();
   3653   const std::string body =
   3654       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
   3655 
   3656   CompileSuccessfully(GenerateKernelCode(body));
   3657   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3658   EXPECT_THAT(getDiagnosticString(),
   3659               HasSubstr("OpenCL.std " + ext_inst_name +
   3660                         ": "
   3661                         "expected operand P component type to be equal to "
   3662                         "Result Type"));
   3663 }
   3664 
   3665 INSTANTIATE_TEST_CASE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
   3666                         ::testing::ValuesIn(std::vector<std::string>{
   3667                             "length",
   3668                             "fast_length",
   3669                         }), );
   3670 
   3671 TEST_P(ValidateOpenCLStdDistanceLike, Success) {
   3672   const std::string ext_inst_name = GetParam();
   3673   std::ostringstream ss;
   3674   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   3675      << " %f32vec2_01 %f32vec2_01\n";
   3676   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
   3677      << " %f32vec4_0123 %f32vec4_1234\n";
   3678   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
   3679      << " %f32_0 %f32_1\n";
   3680 
   3681   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3682   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3683 }
   3684 
   3685 TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
   3686   const std::string ext_inst_name = GetParam();
   3687   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
   3688                            " %f32vec2_01 %f32vec2_12\n";
   3689 
   3690   CompileSuccessfully(GenerateKernelCode(body));
   3691   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3692   EXPECT_THAT(getDiagnosticString(),
   3693               HasSubstr("OpenCL.std " + ext_inst_name +
   3694                         ": "
   3695                         "expected Result Type to be a float scalar type"));
   3696 }
   3697 
   3698 TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
   3699   const std::string ext_inst_name = GetParam();
   3700   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3701                            " %u32vec2_01 %f32vec2_12\n";
   3702 
   3703   CompileSuccessfully(GenerateKernelCode(body));
   3704   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3705   EXPECT_THAT(
   3706       getDiagnosticString(),
   3707       HasSubstr("OpenCL.std " + ext_inst_name +
   3708                 ": "
   3709                 "expected operand P0 to be of float scalar or vector type"));
   3710 }
   3711 
   3712 TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
   3713   const std::string ext_inst_name = GetParam();
   3714   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3715                            " %f32vec8_01010101 %f32vec8_01010101\n";
   3716 
   3717   CompileSuccessfully(GenerateKernelCode(body));
   3718   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3719   EXPECT_THAT(
   3720       getDiagnosticString(),
   3721       HasSubstr("OpenCL.std " + ext_inst_name +
   3722                 ": "
   3723                 "expected operand P0 to have no more than 4 components"));
   3724 }
   3725 
   3726 TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
   3727   const std::string ext_inst_name = GetParam();
   3728   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
   3729                            " %f64vec2_01 %f32vec2_12\n";
   3730 
   3731   CompileSuccessfully(GenerateKernelCode(body));
   3732   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3733   EXPECT_THAT(
   3734       getDiagnosticString(),
   3735       HasSubstr(
   3736           "OpenCL.std " + ext_inst_name +
   3737           ": "
   3738           "expected operand P0 component type to be equal to Result Type"));
   3739 }
   3740 
   3741 TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
   3742   const std::string ext_inst_name = GetParam();
   3743   const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
   3744                            " %f64vec2_01 %f32vec2_12\n";
   3745 
   3746   CompileSuccessfully(GenerateKernelCode(body));
   3747   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3748   EXPECT_THAT(getDiagnosticString(),
   3749               HasSubstr("OpenCL.std " + ext_inst_name +
   3750                         ": "
   3751                         "expected operands P0 and P1 to be of the same type"));
   3752 }
   3753 
   3754 INSTANTIATE_TEST_CASE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
   3755                         ::testing::ValuesIn(std::vector<std::string>{
   3756                             "distance",
   3757                             "fast_distance",
   3758                         }), );
   3759 
   3760 TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
   3761   const std::string ext_inst_name = GetParam();
   3762   std::ostringstream ss;
   3763   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   3764      << " %f32vec2_01\n";
   3765   ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
   3766      << " %f32vec4_0123\n";
   3767   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
   3768 
   3769   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3770   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3771 }
   3772 
   3773 TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
   3774   const std::string ext_inst_name = GetParam();
   3775   const std::string body =
   3776       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
   3777 
   3778   CompileSuccessfully(GenerateKernelCode(body));
   3779   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3780   EXPECT_THAT(
   3781       getDiagnosticString(),
   3782       HasSubstr("OpenCL.std " + ext_inst_name +
   3783                 ": "
   3784                 "expected Result Type to be a float scalar or vector type"));
   3785 }
   3786 
   3787 TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
   3788   const std::string ext_inst_name = GetParam();
   3789   const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
   3790                            ext_inst_name + " %f32vec8_01010101\n";
   3791 
   3792   CompileSuccessfully(GenerateKernelCode(body));
   3793   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3794   EXPECT_THAT(
   3795       getDiagnosticString(),
   3796       HasSubstr("OpenCL.std " + ext_inst_name +
   3797                 ": "
   3798                 "expected Result Type to have no more than 4 components"));
   3799 }
   3800 
   3801 TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
   3802   const std::string ext_inst_name = GetParam();
   3803   const std::string body =
   3804       "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
   3805 
   3806   CompileSuccessfully(GenerateKernelCode(body));
   3807   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3808   EXPECT_THAT(getDiagnosticString(),
   3809               HasSubstr("OpenCL.std " + ext_inst_name +
   3810                         ": "
   3811                         "expected operand P type to be equal to Result Type"));
   3812 }
   3813 
   3814 INSTANTIATE_TEST_CASE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
   3815                         ::testing::ValuesIn(std::vector<std::string>{
   3816                             "normalize",
   3817                             "fast_normalize",
   3818                         }), );
   3819 
   3820 TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
   3821   const std::string body = R"(
   3822 %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
   3823 %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
   3824 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
   3825 %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
   3826 %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
   3827 )";
   3828 
   3829   CompileSuccessfully(GenerateKernelCode(body));
   3830   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3831 }
   3832 
   3833 TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
   3834   const std::string body = R"(
   3835 %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
   3836 )";
   3837 
   3838   CompileSuccessfully(GenerateKernelCode(body));
   3839   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3840   EXPECT_THAT(
   3841       getDiagnosticString(),
   3842       HasSubstr(
   3843           "OpenCL.std bitselect: "
   3844           "expected Result Type to be an int or float scalar or vector type"));
   3845 }
   3846 
   3847 TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
   3848   const std::string body = R"(
   3849 %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
   3850 )";
   3851 
   3852   CompileSuccessfully(GenerateKernelCode(body));
   3853   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3854   EXPECT_THAT(
   3855       getDiagnosticString(),
   3856       HasSubstr("OpenCL.std bitselect: "
   3857                 "expected types of all operands to be equal to Result Type"));
   3858 }
   3859 
   3860 TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
   3861   const std::string body = R"(
   3862 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
   3863 )";
   3864 
   3865   CompileSuccessfully(GenerateKernelCode(body));
   3866   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3867   EXPECT_THAT(
   3868       getDiagnosticString(),
   3869       HasSubstr("OpenCL.std bitselect: "
   3870                 "expected types of all operands to be equal to Result Type"));
   3871 }
   3872 
   3873 TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
   3874   const std::string body = R"(
   3875 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
   3876 )";
   3877 
   3878   CompileSuccessfully(GenerateKernelCode(body));
   3879   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3880   EXPECT_THAT(
   3881       getDiagnosticString(),
   3882       HasSubstr("OpenCL.std bitselect: "
   3883                 "expected types of all operands to be equal to Result Type"));
   3884 }
   3885 
   3886 TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
   3887   const std::string body = R"(
   3888 %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
   3889 %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
   3890 %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
   3891 %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
   3892 %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
   3893 )";
   3894 
   3895   CompileSuccessfully(GenerateKernelCode(body));
   3896   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3897 }
   3898 
   3899 TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
   3900   const std::string body = R"(
   3901 %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
   3902 )";
   3903 
   3904   CompileSuccessfully(GenerateKernelCode(body));
   3905   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3906   EXPECT_THAT(
   3907       getDiagnosticString(),
   3908       HasSubstr(
   3909           "OpenCL.std select: "
   3910           "expected Result Type to be an int or float scalar or vector type"));
   3911 }
   3912 
   3913 TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
   3914   const std::string body = R"(
   3915 %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
   3916 )";
   3917 
   3918   CompileSuccessfully(GenerateKernelCode(body));
   3919   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3920   EXPECT_THAT(getDiagnosticString(),
   3921               HasSubstr("OpenCL.std select: "
   3922                         "expected operand A type to be equal to Result Type"));
   3923 }
   3924 
   3925 TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
   3926   const std::string body = R"(
   3927 %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
   3928 )";
   3929 
   3930   CompileSuccessfully(GenerateKernelCode(body));
   3931   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3932   EXPECT_THAT(getDiagnosticString(),
   3933               HasSubstr("OpenCL.std select: "
   3934                         "expected operand B type to be equal to Result Type"));
   3935 }
   3936 
   3937 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
   3938   const std::string body = R"(
   3939 %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
   3940 )";
   3941 
   3942   CompileSuccessfully(GenerateKernelCode(body));
   3943   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3944   EXPECT_THAT(getDiagnosticString(),
   3945               HasSubstr("OpenCL.std select: "
   3946                         "expected operand C to be an int scalar or vector"));
   3947 }
   3948 
   3949 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
   3950   const std::string body = R"(
   3951 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
   3952 )";
   3953 
   3954   CompileSuccessfully(GenerateKernelCode(body));
   3955   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3956   EXPECT_THAT(getDiagnosticString(),
   3957               HasSubstr("OpenCL.std select: "
   3958                         "expected operand C to have the same number of "
   3959                         "components as Result Type"));
   3960 }
   3961 
   3962 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
   3963   const std::string body = R"(
   3964 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
   3965 )";
   3966 
   3967   CompileSuccessfully(GenerateKernelCode(body));
   3968   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   3969   EXPECT_THAT(
   3970       getDiagnosticString(),
   3971       HasSubstr(
   3972           "OpenCL.std select: "
   3973           "expected operand C to have the same bit width as Result Type"));
   3974 }
   3975 
   3976 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
   3977   const std::string ext_inst_name = GetParam();
   3978   const std::string rounding_mode =
   3979       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   3980 
   3981   std::ostringstream ss;
   3982   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   3983   if (std::string::npos == ext_inst_name.find("halfn")) {
   3984     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   3985        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
   3986     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
   3987        << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
   3988   } else {
   3989     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   3990        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   3991     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
   3992        << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
   3993     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
   3994        << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
   3995   }
   3996 
   3997   CompileSuccessfully(GenerateKernelCode(ss.str()));
   3998   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   3999 }
   4000 
   4001 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
   4002   const std::string ext_inst_name = GetParam();
   4003   const std::string rounding_mode =
   4004       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4005 
   4006   std::ostringstream ss;
   4007   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4008   if (std::string::npos == ext_inst_name.find("halfn")) {
   4009     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4010        << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
   4011     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
   4012        << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
   4013   } else {
   4014     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4015        << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
   4016     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
   4017        << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
   4018     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
   4019        << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
   4020   }
   4021 
   4022   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4023   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4024 }
   4025 
   4026 TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
   4027   const std::string ext_inst_name = GetParam();
   4028   const std::string rounding_mode =
   4029       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4030 
   4031   std::ostringstream ss;
   4032   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4033   if (std::string::npos == ext_inst_name.find("halfn")) {
   4034     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   4035        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
   4036   } else {
   4037     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   4038        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4039   }
   4040 
   4041   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4042   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4043   EXPECT_THAT(getDiagnosticString(),
   4044               HasSubstr("OpenCL.std " + ext_inst_name +
   4045                         ": expected Result Type to be void"));
   4046 }
   4047 
   4048 TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
   4049   const std::string ext_inst_name = GetParam();
   4050   const std::string rounding_mode =
   4051       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4052 
   4053   std::ostringstream ss;
   4054   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4055   if (std::string::npos == ext_inst_name.find("halfn")) {
   4056     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4057        << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4058     CompileSuccessfully(GenerateKernelCode(ss.str()));
   4059     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4060     EXPECT_THAT(getDiagnosticString(),
   4061                 HasSubstr("OpenCL.std " + ext_inst_name +
   4062                           ": expected Data to be a 32 or 64-bit float scalar"));
   4063   } else {
   4064     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4065        << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
   4066     CompileSuccessfully(GenerateKernelCode(ss.str()));
   4067     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4068     EXPECT_THAT(getDiagnosticString(),
   4069                 HasSubstr("OpenCL.std " + ext_inst_name +
   4070                           ": expected Data to be a 32 or 64-bit float vector"));
   4071   }
   4072 }
   4073 
   4074 TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
   4075   const std::string ext_inst_name = GetParam();
   4076   const std::string rounding_mode =
   4077       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4078 
   4079   std::ostringstream ss;
   4080   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4081   if (std::string::npos == ext_inst_name.find("halfn")) {
   4082     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4083        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
   4084   } else {
   4085     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4086        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4087   }
   4088 
   4089   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
   4090   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4091   EXPECT_THAT(getDiagnosticString(),
   4092               HasSubstr("OpenCL.std " + ext_inst_name +
   4093                         " can only be used with physical addressing models"));
   4094 }
   4095 
   4096 TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
   4097   const std::string ext_inst_name = GetParam();
   4098   const std::string rounding_mode =
   4099       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4100 
   4101   std::ostringstream ss;
   4102   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4103   if (std::string::npos == ext_inst_name.find("halfn")) {
   4104     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4105        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
   4106   } else {
   4107     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4108        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4109   }
   4110 
   4111   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4112   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4113   EXPECT_THAT(
   4114       getDiagnosticString(),
   4115       HasSubstr("OpenCL.std " + ext_inst_name +
   4116                 ": "
   4117                 "expected operand Offset to be of type size_t (64-bit integer "
   4118                 "for the addressing model used in the module)"));
   4119 }
   4120 
   4121 TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
   4122   const std::string ext_inst_name = GetParam();
   4123   const std::string rounding_mode =
   4124       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4125 
   4126   std::ostringstream ss;
   4127   if (std::string::npos == ext_inst_name.find("halfn")) {
   4128     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4129        << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
   4130   } else {
   4131     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4132        << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
   4133   }
   4134 
   4135   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4136   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   4137   EXPECT_THAT(getDiagnosticString(),
   4138               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
   4139 }
   4140 
   4141 TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
   4142   const std::string ext_inst_name = GetParam();
   4143   const std::string rounding_mode =
   4144       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4145 
   4146   std::ostringstream ss;
   4147   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4148         "%f16vec8_uniform_constant %u32_1\n";
   4149   if (std::string::npos == ext_inst_name.find("halfn")) {
   4150     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4151        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
   4152   } else {
   4153     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4154        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4155   }
   4156 
   4157   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4158   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4159   EXPECT_THAT(getDiagnosticString(),
   4160               HasSubstr("OpenCL.std " + ext_inst_name +
   4161                         ": expected operand P storage class to be Generic, "
   4162                         "CrossWorkgroup, Workgroup or Function"));
   4163 }
   4164 
   4165 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
   4166   const std::string ext_inst_name = GetParam();
   4167   const std::string rounding_mode =
   4168       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4169 
   4170   std::ostringstream ss;
   4171   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
   4172   if (std::string::npos == ext_inst_name.find("halfn")) {
   4173     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4174        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
   4175   } else {
   4176     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4177        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4178   }
   4179 
   4180   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4181   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4182   EXPECT_THAT(
   4183       getDiagnosticString(),
   4184       HasSubstr("OpenCL.std " + ext_inst_name +
   4185                 ": expected operand P data type to be 16-bit float scalar"));
   4186 }
   4187 
   4188 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
   4189   const std::string ext_inst_name = GetParam();
   4190   const std::string rounding_mode =
   4191       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
   4192 
   4193   std::ostringstream ss;
   4194   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4195   if (std::string::npos == ext_inst_name.find("halfn")) {
   4196     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4197        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
   4198   } else {
   4199     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
   4200        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
   4201   }
   4202 
   4203   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4204   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4205   EXPECT_THAT(
   4206       getDiagnosticString(),
   4207       HasSubstr("OpenCL.std " + ext_inst_name +
   4208                 ": expected operand P data type to be 16-bit float scalar"));
   4209 }
   4210 
   4211 INSTANTIATE_TEST_CASE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
   4212                         ::testing::ValuesIn(std::vector<std::string>{
   4213                             "vstore_half",
   4214                             "vstore_half_r",
   4215                             "vstore_halfn",
   4216                             "vstore_halfn_r",
   4217                             "vstorea_halfn",
   4218                             "vstorea_halfn_r",
   4219                         }), );
   4220 
   4221 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
   4222   const std::string ext_inst_name = GetParam();
   4223 
   4224   std::ostringstream ss;
   4225   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4226   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4227      << " %u32_1 %ptr 2\n";
   4228   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
   4229      << " %u32_1 %ptr 3\n";
   4230   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
   4231      << " %u32_1 %ptr 4\n";
   4232 
   4233   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4234   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4235 }
   4236 
   4237 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
   4238   const std::string ext_inst_name = GetParam();
   4239 
   4240   std::ostringstream ss;
   4241   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4242   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4243      << " %u64_1 %ptr 2\n";
   4244   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
   4245      << " %u64_1 %ptr 3\n";
   4246   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
   4247      << " %u64_1 %ptr 4\n";
   4248 
   4249   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4250   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4251 }
   4252 
   4253 TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
   4254   const std::string ext_inst_name = GetParam();
   4255 
   4256   std::ostringstream ss;
   4257   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4258   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   4259      << " %u32_1 %ptr 1\n";
   4260 
   4261   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4262   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4263   EXPECT_THAT(getDiagnosticString(),
   4264               HasSubstr("OpenCL.std " + ext_inst_name +
   4265                         ": expected Result Type to be a float vector type"));
   4266 }
   4267 
   4268 TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
   4269   const std::string ext_inst_name = GetParam();
   4270 
   4271   std::ostringstream ss;
   4272   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4273   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4274      << " %u32_1 %ptr 2\n";
   4275 
   4276   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
   4277   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4278   EXPECT_THAT(getDiagnosticString(),
   4279               HasSubstr("OpenCL.std " + ext_inst_name +
   4280                         " can only be used with physical addressing models"));
   4281 }
   4282 
   4283 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
   4284   const std::string ext_inst_name = GetParam();
   4285 
   4286   std::ostringstream ss;
   4287   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4288   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4289      << " %u64_1 %ptr 2\n";
   4290 
   4291   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4292   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4293   EXPECT_THAT(
   4294       getDiagnosticString(),
   4295       HasSubstr("OpenCL.std " + ext_inst_name +
   4296                 ": expected operand Offset to be of type size_t (32-bit "
   4297                 "integer for the addressing model used in the module)"));
   4298 }
   4299 
   4300 TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
   4301   const std::string ext_inst_name = GetParam();
   4302 
   4303   std::ostringstream ss;
   4304   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4305      << " %u32_1 %f16_ptr_workgroup 2\n";
   4306 
   4307   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4308   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   4309   EXPECT_THAT(getDiagnosticString(),
   4310               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
   4311 }
   4312 
   4313 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
   4314   const std::string ext_inst_name = GetParam();
   4315 
   4316   std::ostringstream ss;
   4317   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
   4318   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4319      << " %u32_1 %ptr 2\n";
   4320 
   4321   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4322   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4323   EXPECT_THAT(
   4324       getDiagnosticString(),
   4325       HasSubstr("OpenCL.std " + ext_inst_name +
   4326                 ": expected operand P storage class to be UniformConstant, "
   4327                 "Generic, CrossWorkgroup, Workgroup or Function"));
   4328 }
   4329 
   4330 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
   4331   const std::string ext_inst_name = GetParam();
   4332 
   4333   std::ostringstream ss;
   4334   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
   4335   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4336      << " %u32_1 %ptr 2\n";
   4337 
   4338   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4339   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4340   EXPECT_THAT(
   4341       getDiagnosticString(),
   4342       HasSubstr("OpenCL.std " + ext_inst_name +
   4343                 ": expected operand P data type to be 16-bit float scalar"));
   4344 }
   4345 
   4346 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
   4347   const std::string ext_inst_name = GetParam();
   4348 
   4349   std::ostringstream ss;
   4350   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4351   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4352      << " %u32_1 %ptr 2\n";
   4353 
   4354   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4355   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4356   EXPECT_THAT(
   4357       getDiagnosticString(),
   4358       HasSubstr("OpenCL.std " + ext_inst_name +
   4359                 ": expected operand P data type to be 16-bit float scalar"));
   4360 }
   4361 
   4362 TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
   4363   const std::string ext_inst_name = GetParam();
   4364 
   4365   std::ostringstream ss;
   4366   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
   4367   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   4368      << " %u32_1 %ptr 3\n";
   4369 
   4370   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4371   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4372   EXPECT_THAT(getDiagnosticString(),
   4373               HasSubstr("OpenCL.std " + ext_inst_name +
   4374                         ": expected literal N to be equal to the number of "
   4375                         "components of Result Type"));
   4376 }
   4377 
   4378 INSTANTIATE_TEST_CASE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
   4379                         ::testing::ValuesIn(std::vector<std::string>{
   4380                             "vload_halfn",
   4381                             "vloada_halfn",
   4382                         }), );
   4383 
   4384 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
   4385   std::ostringstream ss;
   4386   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4387         "%f32vec8_uniform_constant %u32_1\n";
   4388   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
   4389   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
   4390   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
   4391 
   4392   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4393   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4394 }
   4395 
   4396 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
   4397   std::ostringstream ss;
   4398   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
   4399         "%u32vec8_uniform_constant %u32_1\n";
   4400   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
   4401   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
   4402   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
   4403 
   4404   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4405   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4406 }
   4407 
   4408 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
   4409   std::ostringstream ss;
   4410   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4411         "%f32vec8_uniform_constant %u32_1\n";
   4412   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
   4413   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
   4414   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
   4415 
   4416   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4417   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4418 }
   4419 
   4420 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
   4421   std::ostringstream ss;
   4422   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
   4423         "%u32vec8_uniform_constant %u32_1\n";
   4424   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
   4425   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
   4426   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
   4427 
   4428   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4429   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4430 }
   4431 
   4432 TEST_F(ValidateExtInst, VLoadNWrongResultType) {
   4433   std::ostringstream ss;
   4434   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4435         "%f32vec8_uniform_constant %u32_1\n";
   4436   ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
   4437 
   4438   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4439   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4440   EXPECT_THAT(
   4441       getDiagnosticString(),
   4442       HasSubstr("OpenCL.std vloadn: "
   4443                 "expected Result Type to be an int or float vector type"));
   4444 }
   4445 
   4446 TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
   4447   std::ostringstream ss;
   4448   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4449         "%f32vec8_uniform_constant %u32_1\n";
   4450   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
   4451 
   4452   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
   4453   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4454   EXPECT_THAT(getDiagnosticString(),
   4455               HasSubstr("OpenCL.std vloadn can only be used with physical "
   4456                         "addressing models"));
   4457 }
   4458 
   4459 TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
   4460   std::ostringstream ss;
   4461   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4462         "%f32vec8_uniform_constant %u32_1\n";
   4463   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
   4464 
   4465   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4466   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4467   EXPECT_THAT(
   4468       getDiagnosticString(),
   4469       HasSubstr(
   4470           "OpenCL.std vloadn: expected operand Offset to be of type size_t "
   4471           "(32-bit integer for the addressing model used in the module)"));
   4472 }
   4473 
   4474 TEST_F(ValidateExtInst, VLoadNPNotPointer) {
   4475   std::ostringstream ss;
   4476   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
   4477         "%f32_ptr_uniform_constant 2\n";
   4478 
   4479   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4480   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   4481   EXPECT_THAT(getDiagnosticString(),
   4482               HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
   4483                         "type"));
   4484 }
   4485 
   4486 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
   4487   std::ostringstream ss;
   4488   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
   4489   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
   4490 
   4491   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4492   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4493   EXPECT_THAT(getDiagnosticString(),
   4494               HasSubstr("OpenCL.std vloadn: expected operand P storage class "
   4495                         "to be UniformConstant or Generic"));
   4496 }
   4497 
   4498 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
   4499   std::ostringstream ss;
   4500   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4501         "%f32vec8_uniform_constant %u32_1\n";
   4502   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
   4503 
   4504   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4505   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4506   EXPECT_THAT(getDiagnosticString(),
   4507               HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
   4508                         "equal to component type of Result Type"));
   4509 }
   4510 
   4511 TEST_F(ValidateExtInst, VLoadNWrongN) {
   4512   std::ostringstream ss;
   4513   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4514         "%f32vec8_uniform_constant %u32_1\n";
   4515   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
   4516 
   4517   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4518   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4519   EXPECT_THAT(getDiagnosticString(),
   4520               HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
   4521                         "the number of components of Result Type"));
   4522 }
   4523 
   4524 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
   4525   std::ostringstream ss;
   4526   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4527         "%f16vec8_uniform_constant %u32_1\n";
   4528   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
   4529   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
   4530 
   4531   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4532   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4533 }
   4534 
   4535 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
   4536   std::ostringstream ss;
   4537   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4538         "%f16vec8_uniform_constant %u32_1\n";
   4539   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
   4540   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
   4541 
   4542   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4543   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4544 }
   4545 
   4546 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
   4547   std::ostringstream ss;
   4548   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4549         "%f16vec8_uniform_constant %u32_1\n";
   4550   ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
   4551 
   4552   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4553   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4554   EXPECT_THAT(getDiagnosticString(),
   4555               HasSubstr("OpenCL.std vload_half: "
   4556                         "expected Result Type to be a float scalar type"));
   4557 }
   4558 
   4559 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
   4560   std::ostringstream ss;
   4561   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4562         "%f16vec8_uniform_constant %u32_1\n";
   4563   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
   4564 
   4565   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
   4566   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4567   EXPECT_THAT(getDiagnosticString(),
   4568               HasSubstr("OpenCL.std vload_half can only be used with physical "
   4569                         "addressing models"));
   4570 }
   4571 
   4572 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
   4573   std::ostringstream ss;
   4574   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
   4575         "%f16vec8_uniform_constant %u32_1\n";
   4576   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
   4577 
   4578   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4579   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4580   EXPECT_THAT(
   4581       getDiagnosticString(),
   4582       HasSubstr(
   4583           "OpenCL.std vload_half: expected operand Offset to be of type size_t "
   4584           "(32-bit integer for the addressing model used in the module)"));
   4585 }
   4586 
   4587 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
   4588   std::ostringstream ss;
   4589   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
   4590         "%f16_ptr_uniform_constant\n";
   4591 
   4592   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4593   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   4594   EXPECT_THAT(getDiagnosticString(),
   4595               HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
   4596                         "type"));
   4597 }
   4598 
   4599 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
   4600   std::ostringstream ss;
   4601   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
   4602   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
   4603 
   4604   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4605   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4606   EXPECT_THAT(
   4607       getDiagnosticString(),
   4608       HasSubstr(
   4609           "OpenCL.std vload_half: expected operand P storage class to be "
   4610           "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
   4611 }
   4612 
   4613 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
   4614   std::ostringstream ss;
   4615   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
   4616         "%u32vec8_uniform_constant %u32_1\n";
   4617   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
   4618 
   4619   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4620   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4621   EXPECT_THAT(getDiagnosticString(),
   4622               HasSubstr("OpenCL.std vload_half: expected operand P data type "
   4623                         "to be 16-bit float scalar"));
   4624 }
   4625 
   4626 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
   4627   std::ostringstream ss;
   4628   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   4629         "%f32vec8_uniform_constant %u32_1\n";
   4630   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
   4631 
   4632   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4633   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4634   EXPECT_THAT(getDiagnosticString(),
   4635               HasSubstr("OpenCL.std vload_half: expected operand P data type "
   4636                         "to be 16-bit float scalar"));
   4637 }
   4638 
   4639 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
   4640   std::ostringstream ss;
   4641   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4642   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4643   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
   4644   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
   4645         "%ptr_g\n";
   4646 
   4647   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4648   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4649 }
   4650 
   4651 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
   4652   std::ostringstream ss;
   4653   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4654   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4655   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
   4656   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
   4657         "%ptr_g\n";
   4658 
   4659   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4660   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4661 }
   4662 
   4663 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
   4664   std::ostringstream ss;
   4665   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
   4666   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
   4667   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
   4668   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
   4669         "%ptr_g\n";
   4670 
   4671   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4672   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4673 }
   4674 
   4675 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
   4676   std::ostringstream ss;
   4677   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
   4678   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
   4679   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
   4680   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
   4681         "%ptr_g\n";
   4682 
   4683   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4684   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4685 }
   4686 
   4687 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
   4688   std::ostringstream ss;
   4689   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4690   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4691   ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
   4692 
   4693   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4694   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4695   EXPECT_THAT(getDiagnosticString(),
   4696               HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
   4697 }
   4698 
   4699 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
   4700   std::ostringstream ss;
   4701   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4702   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4703   ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
   4704 
   4705   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4706   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4707   EXPECT_THAT(
   4708       getDiagnosticString(),
   4709       HasSubstr(
   4710           "OpenCL.std vstoren: expected Data to be an int or float vector"));
   4711 }
   4712 
   4713 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
   4714   std::ostringstream ss;
   4715   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4716   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4717   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
   4718 
   4719   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
   4720   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4721   EXPECT_THAT(getDiagnosticString(),
   4722               HasSubstr("OpenCL.std vstoren can only be used with physical "
   4723                         "addressing models"));
   4724 }
   4725 
   4726 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
   4727   std::ostringstream ss;
   4728   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4729   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4730   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
   4731 
   4732   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
   4733   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4734   EXPECT_THAT(
   4735       getDiagnosticString(),
   4736       HasSubstr(
   4737           "OpenCL.std vstoren: expected operand Offset to be of type size_t "
   4738           "(64-bit integer for the addressing model used in the module)"));
   4739 }
   4740 
   4741 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
   4742   std::ostringstream ss;
   4743   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
   4744         "%f32_ptr_generic\n";
   4745 
   4746   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4747   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   4748   EXPECT_THAT(getDiagnosticString(),
   4749               HasSubstr("Operand 124[%_ptr_Generic_float] cannot be a type"));
   4750 }
   4751 
   4752 TEST_F(ValidateExtInst, VStoreNPNotGeneric) {
   4753   std::ostringstream ss;
   4754   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4755   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
   4756 
   4757   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4758   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4759   EXPECT_THAT(getDiagnosticString(),
   4760               HasSubstr("OpenCL.std vstoren: expected operand P storage class "
   4761                         "to be Generic"));
   4762 }
   4763 
   4764 TEST_F(ValidateExtInst, VStorePWrongDataType) {
   4765   std::ostringstream ss;
   4766   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
   4767   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
   4768   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
   4769 
   4770   CompileSuccessfully(GenerateKernelCode(ss.str()));
   4771   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4772   EXPECT_THAT(getDiagnosticString(),
   4773               HasSubstr("OpenCL.std vstoren: expected operand P data type to "
   4774                         "be equal to the type of operand Data components"));
   4775 }
   4776 
   4777 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
   4778   const std::string body = R"(
   4779 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
   4780 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
   4781 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
   4782 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
   4783 )";
   4784 
   4785   CompileSuccessfully(GenerateKernelCode(body));
   4786   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4787 }
   4788 
   4789 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
   4790   const std::string body = R"(
   4791 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
   4792 )";
   4793 
   4794   CompileSuccessfully(GenerateKernelCode(body));
   4795   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4796   EXPECT_THAT(
   4797       getDiagnosticString(),
   4798       HasSubstr("OpenCL.std shuffle: "
   4799                 "expected Result Type to be an int or float vector type"));
   4800 }
   4801 
   4802 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
   4803   const std::string body = R"(
   4804 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
   4805 )";
   4806 
   4807   CompileSuccessfully(GenerateKernelCode(body));
   4808   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4809   EXPECT_THAT(
   4810       getDiagnosticString(),
   4811       HasSubstr("OpenCL.std shuffle: "
   4812                 "expected Result Type to have 2, 4, 8 or 16 components"));
   4813 }
   4814 
   4815 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
   4816   const std::string body = R"(
   4817 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
   4818 )";
   4819 
   4820   CompileSuccessfully(GenerateKernelCode(body));
   4821   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4822   EXPECT_THAT(getDiagnosticString(),
   4823               HasSubstr("OpenCL.std shuffle: "
   4824                         "expected operand X to be an int or float vector"));
   4825 }
   4826 
   4827 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
   4828   const std::string body = R"(
   4829 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
   4830 )";
   4831 
   4832   CompileSuccessfully(GenerateKernelCode(body));
   4833   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4834   EXPECT_THAT(getDiagnosticString(),
   4835               HasSubstr("OpenCL.std shuffle: "
   4836                         "expected operand X to have 2, 4, 8 or 16 components"));
   4837 }
   4838 
   4839 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
   4840   const std::string body = R"(
   4841 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
   4842 )";
   4843 
   4844   CompileSuccessfully(GenerateKernelCode(body));
   4845   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4846   EXPECT_THAT(
   4847       getDiagnosticString(),
   4848       HasSubstr(
   4849           "OpenCL.std shuffle: "
   4850           "expected operand X and Result Type to have equal component types"));
   4851 }
   4852 
   4853 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
   4854   const std::string body = R"(
   4855 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
   4856 )";
   4857 
   4858   CompileSuccessfully(GenerateKernelCode(body));
   4859   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4860   EXPECT_THAT(getDiagnosticString(),
   4861               HasSubstr("OpenCL.std shuffle: "
   4862                         "expected operand Shuffle Mask to be an int vector"));
   4863 }
   4864 
   4865 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
   4866   const std::string body = R"(
   4867 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
   4868 )";
   4869 
   4870   CompileSuccessfully(GenerateKernelCode(body));
   4871   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4872   EXPECT_THAT(getDiagnosticString(),
   4873               HasSubstr("OpenCL.std shuffle: "
   4874                         "expected operand Shuffle Mask to have the same number "
   4875                         "of components as Result Type"));
   4876 }
   4877 
   4878 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
   4879   const std::string body = R"(
   4880 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
   4881 )";
   4882 
   4883   CompileSuccessfully(GenerateKernelCode(body));
   4884   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4885   EXPECT_THAT(getDiagnosticString(),
   4886               HasSubstr("OpenCL.std shuffle: "
   4887                         "expected operand Shuffle Mask components to have the "
   4888                         "same bit width as Result Type components"));
   4889 }
   4890 
   4891 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
   4892   const std::string body = R"(
   4893 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
   4894 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
   4895 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
   4896 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
   4897 )";
   4898 
   4899   CompileSuccessfully(GenerateKernelCode(body));
   4900   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   4901 }
   4902 
   4903 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
   4904   const std::string body = R"(
   4905 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
   4906 )";
   4907 
   4908   CompileSuccessfully(GenerateKernelCode(body));
   4909   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4910   EXPECT_THAT(
   4911       getDiagnosticString(),
   4912       HasSubstr("OpenCL.std shuffle2: "
   4913                 "expected Result Type to be an int or float vector type"));
   4914 }
   4915 
   4916 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
   4917   const std::string body = R"(
   4918 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
   4919 )";
   4920 
   4921   CompileSuccessfully(GenerateKernelCode(body));
   4922   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4923   EXPECT_THAT(
   4924       getDiagnosticString(),
   4925       HasSubstr("OpenCL.std shuffle2: "
   4926                 "expected Result Type to have 2, 4, 8 or 16 components"));
   4927 }
   4928 
   4929 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
   4930   const std::string body = R"(
   4931 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
   4932 )";
   4933 
   4934   CompileSuccessfully(GenerateKernelCode(body));
   4935   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4936   EXPECT_THAT(getDiagnosticString(),
   4937               HasSubstr("OpenCL.std shuffle2: "
   4938                         "expected operand X to be an int or float vector"));
   4939 }
   4940 
   4941 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
   4942   const std::string body = R"(
   4943 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
   4944 )";
   4945 
   4946   CompileSuccessfully(GenerateKernelCode(body));
   4947   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4948   EXPECT_THAT(getDiagnosticString(),
   4949               HasSubstr("OpenCL.std shuffle2: "
   4950                         "expected operands X and Y to be of the same type"));
   4951 }
   4952 
   4953 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
   4954   const std::string body = R"(
   4955 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
   4956 )";
   4957 
   4958   CompileSuccessfully(GenerateKernelCode(body));
   4959   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4960   EXPECT_THAT(getDiagnosticString(),
   4961               HasSubstr("OpenCL.std shuffle2: "
   4962                         "expected operand X to have 2, 4, 8 or 16 components"));
   4963 }
   4964 
   4965 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
   4966   const std::string body = R"(
   4967 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
   4968 )";
   4969 
   4970   CompileSuccessfully(GenerateKernelCode(body));
   4971   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4972   EXPECT_THAT(
   4973       getDiagnosticString(),
   4974       HasSubstr(
   4975           "OpenCL.std shuffle2: "
   4976           "expected operand X and Result Type to have equal component types"));
   4977 }
   4978 
   4979 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
   4980   const std::string body = R"(
   4981 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
   4982 )";
   4983 
   4984   CompileSuccessfully(GenerateKernelCode(body));
   4985   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4986   EXPECT_THAT(getDiagnosticString(),
   4987               HasSubstr("OpenCL.std shuffle2: "
   4988                         "expected operand Shuffle Mask to be an int vector"));
   4989 }
   4990 
   4991 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
   4992   const std::string body = R"(
   4993 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
   4994 )";
   4995 
   4996   CompileSuccessfully(GenerateKernelCode(body));
   4997   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   4998   EXPECT_THAT(getDiagnosticString(),
   4999               HasSubstr("OpenCL.std shuffle2: "
   5000                         "expected operand Shuffle Mask to have the same number "
   5001                         "of components as Result Type"));
   5002 }
   5003 
   5004 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
   5005   const std::string body = R"(
   5006 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
   5007 )";
   5008 
   5009   CompileSuccessfully(GenerateKernelCode(body));
   5010   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5011   EXPECT_THAT(getDiagnosticString(),
   5012               HasSubstr("OpenCL.std shuffle2: "
   5013                         "expected operand Shuffle Mask components to have the "
   5014                         "same bit width as Result Type components"));
   5015 }
   5016 
   5017 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
   5018   const std::string body = R"(
   5019 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
   5020 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
   5021 )";
   5022 
   5023   CompileSuccessfully(GenerateKernelCode(body));
   5024   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5025 }
   5026 
   5027 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
   5028   const std::string body = R"(
   5029 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
   5030 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
   5031 )";
   5032 
   5033   CompileSuccessfully(GenerateKernelCode(body));
   5034   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5035   EXPECT_THAT(
   5036       getDiagnosticString(),
   5037       HasSubstr(
   5038           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
   5039 }
   5040 
   5041 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
   5042   const std::string body = R"(
   5043 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
   5044 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
   5045 )";
   5046 
   5047   CompileSuccessfully(GenerateKernelCode(body));
   5048   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5049   EXPECT_THAT(
   5050       getDiagnosticString(),
   5051       HasSubstr(
   5052           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
   5053 }
   5054 
   5055 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
   5056   const std::string body = R"(
   5057 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
   5058 )";
   5059 
   5060   CompileSuccessfully(GenerateKernelCode(body));
   5061   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   5062   EXPECT_THAT(getDiagnosticString(),
   5063               HasSubstr("Operand 134[%_ptr_UniformConstant_uchar] cannot be a "
   5064                         "type"));
   5065 }
   5066 
   5067 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
   5068   const std::string body = R"(
   5069 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
   5070 %format = OpBitcast %u8_ptr_generic %format_const
   5071 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
   5072 )";
   5073 
   5074   CompileSuccessfully(GenerateKernelCode(body));
   5075   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5076   EXPECT_THAT(getDiagnosticString(),
   5077               HasSubstr("OpenCL.std printf: expected Format storage class to "
   5078                         "be UniformConstant"));
   5079 }
   5080 
   5081 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
   5082   const std::string body = R"(
   5083 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
   5084 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
   5085 )";
   5086 
   5087   CompileSuccessfully(GenerateKernelCode(body));
   5088   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5089   EXPECT_THAT(
   5090       getDiagnosticString(),
   5091       HasSubstr(
   5092           "OpenCL.std printf: expected Format data type to be 8-bit int"));
   5093 }
   5094 
   5095 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
   5096   const std::string body = R"(
   5097 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
   5098 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5099 )";
   5100 
   5101   CompileSuccessfully(GenerateKernelCode(body));
   5102   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5103 }
   5104 
   5105 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
   5106   const std::string body = R"(
   5107 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
   5108 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
   5109 )";
   5110 
   5111   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
   5112   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5113 }
   5114 
   5115 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
   5116   const std::string body = R"(
   5117 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
   5118 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5119 )";
   5120 
   5121   CompileSuccessfully(GenerateKernelCode(body));
   5122   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5123 }
   5124 
   5125 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
   5126   const std::string body = R"(
   5127 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
   5128 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5129 )";
   5130 
   5131   CompileSuccessfully(GenerateKernelCode(body));
   5132   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5133 }
   5134 
   5135 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
   5136   const std::string body = R"(
   5137 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
   5138 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
   5139 )";
   5140 
   5141   CompileSuccessfully(GenerateKernelCode(body));
   5142   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5143   EXPECT_THAT(
   5144       getDiagnosticString(),
   5145       HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
   5146 }
   5147 
   5148 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
   5149   const std::string body = R"(
   5150 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
   5151 )";
   5152 
   5153   CompileSuccessfully(GenerateKernelCode(body));
   5154   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   5155   EXPECT_THAT(getDiagnosticString(),
   5156               HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
   5157                         "type"));
   5158 }
   5159 
   5160 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
   5161   const std::string body = R"(
   5162 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
   5163 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5164 )";
   5165 
   5166   CompileSuccessfully(GenerateKernelCode(body));
   5167   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5168   EXPECT_THAT(getDiagnosticString(),
   5169               HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
   5170                         "class to be CrossWorkgroup"));
   5171 }
   5172 
   5173 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
   5174   const std::string body = R"(
   5175 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
   5176 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5177 )";
   5178 
   5179   CompileSuccessfully(GenerateKernelCode(body));
   5180   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5181   EXPECT_THAT(getDiagnosticString(),
   5182               HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
   5183                         "or float scalar or vector"));
   5184 }
   5185 
   5186 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
   5187   const std::string body = R"(
   5188 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
   5189 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5190 )";
   5191 
   5192   CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
   5193   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5194   EXPECT_THAT(getDiagnosticString(),
   5195               HasSubstr("OpenCL.std prefetch can only be used with physical "
   5196                         "addressing models"));
   5197 }
   5198 
   5199 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
   5200   const std::string body = R"(
   5201 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
   5202 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
   5203 )";
   5204 
   5205   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
   5206   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5207   EXPECT_THAT(getDiagnosticString(),
   5208               HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
   5209                         "be of type size_t (64-bit integer for the addressing "
   5210                         "model used in the module)"));
   5211 }
   5212 
   5213 TEST_P(ValidateOpenCLStdFractLike, Success) {
   5214   const std::string ext_inst_name = GetParam();
   5215   std::ostringstream ss;
   5216   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
   5217   ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
   5218   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5219      << " %f32_0 %var_f32\n";
   5220   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   5221      << " %f32vec2_01 %var_f32vec2\n";
   5222 
   5223   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5224   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5225 }
   5226 
   5227 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
   5228   const std::string ext_inst_name = GetParam();
   5229   std::ostringstream ss;
   5230   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
   5231   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   5232      << " %f32_0 %var_f32\n";
   5233 
   5234   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5235   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5236   EXPECT_THAT(
   5237       getDiagnosticString(),
   5238       HasSubstr("OpenCL.std " + ext_inst_name +
   5239                 ": expected Result Type to be a float scalar or vector type"));
   5240 }
   5241 
   5242 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
   5243   const std::string ext_inst_name = GetParam();
   5244   std::ostringstream ss;
   5245   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
   5246   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5247      << " %f64_0 %var_f32\n";
   5248 
   5249   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5250   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5251   EXPECT_THAT(
   5252       getDiagnosticString(),
   5253       HasSubstr("OpenCL.std " + ext_inst_name +
   5254                 ": expected type of operand X to be equal to Result Type"));
   5255 }
   5256 
   5257 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
   5258   const std::string ext_inst_name = GetParam();
   5259   std::ostringstream ss;
   5260   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
   5261   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5262      << " %f32_0 %f32_1\n";
   5263 
   5264   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5265   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5266   EXPECT_THAT(getDiagnosticString(),
   5267               HasSubstr("OpenCL.std " + ext_inst_name +
   5268                         ": expected the last operand to be a pointer"));
   5269 }
   5270 
   5271 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
   5272   const std::string ext_inst_name = GetParam();
   5273   std::ostringstream ss;
   5274   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   5275         "%f32vec8_uniform_constant %u32_1\n";
   5276   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
   5277 
   5278   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5279   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5280   EXPECT_THAT(getDiagnosticString(),
   5281               HasSubstr("OpenCL.std " + ext_inst_name +
   5282                         ": expected storage class of the pointer to be "
   5283                         "Generic, CrossWorkgroup, Workgroup or Function"));
   5284 }
   5285 
   5286 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
   5287   const std::string ext_inst_name = GetParam();
   5288   std::ostringstream ss;
   5289   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
   5290   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5291      << " %f32_0 %var_u32\n";
   5292 
   5293   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5294   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5295   EXPECT_THAT(
   5296       getDiagnosticString(),
   5297       HasSubstr(
   5298           "OpenCL.std " + ext_inst_name +
   5299           ": expected data type of the pointer to be equal to Result Type"));
   5300 }
   5301 
   5302 INSTANTIATE_TEST_CASE_P(AllFractLike, ValidateOpenCLStdFractLike,
   5303                         ::testing::ValuesIn(std::vector<std::string>{
   5304                             "fract",
   5305                             "modf",
   5306                             "sincos",
   5307                         }), );
   5308 
   5309 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
   5310   const std::string body = R"(
   5311 %var_f32 = OpVariable %f32_ptr_function Function
   5312 %var_f32vec2 = OpVariable %f32vec2_ptr_function Function
   5313 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
   5314 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_f32vec2
   5315 )";
   5316 
   5317   CompileSuccessfully(GenerateKernelCode(body));
   5318   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5319 }
   5320 
   5321 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
   5322   const std::string body = R"(
   5323 %var_f32 = OpVariable %f32_ptr_function Function
   5324 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_f32
   5325 )";
   5326 
   5327   CompileSuccessfully(GenerateKernelCode(body));
   5328   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5329   EXPECT_THAT(
   5330       getDiagnosticString(),
   5331       HasSubstr("OpenCL.std remquo: "
   5332                 "expected Result Type to be a float scalar or vector type"));
   5333 }
   5334 
   5335 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
   5336   const std::string body = R"(
   5337 %var_f32 = OpVariable %f32_ptr_function Function
   5338 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_f32
   5339 )";
   5340 
   5341   CompileSuccessfully(GenerateKernelCode(body));
   5342   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5343   EXPECT_THAT(
   5344       getDiagnosticString(),
   5345       HasSubstr("OpenCL.std remquo: "
   5346                 "expected type of operand X to be equal to Result Type"));
   5347 }
   5348 
   5349 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
   5350   const std::string body = R"(
   5351 %var_f32 = OpVariable %f32_ptr_function Function
   5352 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_f32
   5353 )";
   5354 
   5355   CompileSuccessfully(GenerateKernelCode(body));
   5356   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5357   EXPECT_THAT(
   5358       getDiagnosticString(),
   5359       HasSubstr("OpenCL.std remquo: "
   5360                 "expected type of operand Y to be equal to Result Type"));
   5361 }
   5362 
   5363 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
   5364   const std::string body = R"(
   5365 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
   5366 )";
   5367 
   5368   CompileSuccessfully(GenerateKernelCode(body));
   5369   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5370   EXPECT_THAT(getDiagnosticString(),
   5371               HasSubstr("OpenCL.std remquo: "
   5372                         "expected the last operand to be a pointer"));
   5373 }
   5374 
   5375 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
   5376   const std::string body = R"(
   5377 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
   5378 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
   5379 )";
   5380 
   5381   CompileSuccessfully(GenerateKernelCode(body));
   5382   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5383   EXPECT_THAT(getDiagnosticString(),
   5384               HasSubstr("OpenCL.std remquo: "
   5385                         "expected storage class of the pointer to be Generic, "
   5386                         "CrossWorkgroup, Workgroup or Function"));
   5387 }
   5388 
   5389 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
   5390   const std::string body = R"(
   5391 %var_u32 = OpVariable %u32_ptr_function Function
   5392 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
   5393 )";
   5394 
   5395   CompileSuccessfully(GenerateKernelCode(body));
   5396   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5397   EXPECT_THAT(
   5398       getDiagnosticString(),
   5399       HasSubstr(
   5400           "OpenCL.std remquo: "
   5401           "expected data type of the pointer to be equal to Result Type"));
   5402 }
   5403 
   5404 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
   5405   const std::string ext_inst_name = GetParam();
   5406   std::ostringstream ss;
   5407   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
   5408   ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
   5409   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5410      << " %f32_0 %var_u32\n";
   5411   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   5412      << " %f32vec2_01 %var_u32vec2\n";
   5413 
   5414   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5415   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5416 }
   5417 
   5418 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
   5419   const std::string ext_inst_name = GetParam();
   5420   std::ostringstream ss;
   5421   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
   5422   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   5423      << " %f32_0 %var_u32\n";
   5424 
   5425   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5426   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5427   EXPECT_THAT(
   5428       getDiagnosticString(),
   5429       HasSubstr("OpenCL.std " + ext_inst_name +
   5430                 ": expected Result Type to be a float scalar or vector type"));
   5431 }
   5432 
   5433 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
   5434   const std::string ext_inst_name = GetParam();
   5435   std::ostringstream ss;
   5436   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
   5437   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5438      << " %f64_0 %var_u32\n";
   5439 
   5440   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5441   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5442   EXPECT_THAT(
   5443       getDiagnosticString(),
   5444       HasSubstr("OpenCL.std " + ext_inst_name +
   5445                 ": expected type of operand X to be equal to Result Type"));
   5446 }
   5447 
   5448 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
   5449   const std::string ext_inst_name = GetParam();
   5450   std::ostringstream ss;
   5451   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5452      << " %f32_0 %u32_1\n";
   5453 
   5454   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5455   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5456   EXPECT_THAT(getDiagnosticString(),
   5457               HasSubstr("OpenCL.std " + ext_inst_name +
   5458                         ": expected the last operand to be a pointer"));
   5459 }
   5460 
   5461 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
   5462   const std::string ext_inst_name = GetParam();
   5463   std::ostringstream ss;
   5464   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
   5465         "%f32vec8_uniform_constant %u32_1\n";
   5466   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
   5467 
   5468   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5469   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5470   EXPECT_THAT(getDiagnosticString(),
   5471               HasSubstr("OpenCL.std " + ext_inst_name +
   5472                         ": expected storage class of the pointer to be "
   5473                         "Generic, CrossWorkgroup, Workgroup or Function"));
   5474 }
   5475 
   5476 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
   5477   const std::string ext_inst_name = GetParam();
   5478   std::ostringstream ss;
   5479   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
   5480   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5481      << " %f32_0 %var_f32\n";
   5482 
   5483   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5484   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5485   EXPECT_THAT(getDiagnosticString(),
   5486               HasSubstr("OpenCL.std " + ext_inst_name +
   5487                         ": expected data type of the pointer to be a 32-bit "
   5488                         "int scalar or vector type"));
   5489 }
   5490 
   5491 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
   5492   const std::string ext_inst_name = GetParam();
   5493   std::ostringstream ss;
   5494   ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
   5495   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5496      << " %f32_0 %var_u64\n";
   5497 
   5498   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5499   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5500   EXPECT_THAT(getDiagnosticString(),
   5501               HasSubstr("OpenCL.std " + ext_inst_name +
   5502                         ": expected data type of the pointer to be a 32-bit "
   5503                         "int scalar or vector type"));
   5504 }
   5505 
   5506 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
   5507   const std::string ext_inst_name = GetParam();
   5508   std::ostringstream ss;
   5509   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
   5510   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   5511      << " %f32vec2_01 %var_u32\n";
   5512 
   5513   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5514   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5515   EXPECT_THAT(getDiagnosticString(),
   5516               HasSubstr("OpenCL.std " + ext_inst_name +
   5517                         ": expected data type of the pointer to have the same "
   5518                         "number of components as Result Type"));
   5519 }
   5520 
   5521 INSTANTIATE_TEST_CASE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
   5522                         ::testing::ValuesIn(std::vector<std::string>{
   5523                             "frexp",
   5524                             "lgamma_r",
   5525                         }), );
   5526 
   5527 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
   5528   const std::string body = R"(
   5529 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
   5530 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
   5531 )";
   5532 
   5533   CompileSuccessfully(GenerateKernelCode(body));
   5534   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5535 }
   5536 
   5537 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
   5538   const std::string body = R"(
   5539 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
   5540 )";
   5541 
   5542   CompileSuccessfully(GenerateKernelCode(body));
   5543   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5544   EXPECT_THAT(
   5545       getDiagnosticString(),
   5546       HasSubstr(
   5547           "OpenCL.std ilogb: "
   5548           "expected Result Type to be a 32-bit int scalar or vector type"));
   5549 }
   5550 
   5551 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
   5552   const std::string body = R"(
   5553 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
   5554 )";
   5555 
   5556   CompileSuccessfully(GenerateKernelCode(body));
   5557   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5558   EXPECT_THAT(getDiagnosticString(),
   5559               HasSubstr("OpenCL.std ilogb: "
   5560                         "expected operand X to be a float scalar or vector"));
   5561 }
   5562 
   5563 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
   5564   const std::string body = R"(
   5565 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
   5566 )";
   5567 
   5568   CompileSuccessfully(GenerateKernelCode(body));
   5569   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5570   EXPECT_THAT(getDiagnosticString(),
   5571               HasSubstr("OpenCL.std ilogb: "
   5572                         "expected operand X to have the same number of "
   5573                         "components as Result Type"));
   5574 }
   5575 
   5576 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
   5577   const std::string body = R"(
   5578 %val1 = OpExtInst %f32 %extinst nan %u32_3
   5579 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
   5580 )";
   5581 
   5582   CompileSuccessfully(GenerateKernelCode(body));
   5583   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5584 }
   5585 
   5586 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
   5587   const std::string body = R"(
   5588 %val1 = OpExtInst %u32 %extinst nan %u32_3
   5589 )";
   5590 
   5591   CompileSuccessfully(GenerateKernelCode(body));
   5592   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5593   EXPECT_THAT(
   5594       getDiagnosticString(),
   5595       HasSubstr("OpenCL.std nan: "
   5596                 "expected Result Type to be a float scalar or vector type"));
   5597 }
   5598 
   5599 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
   5600   const std::string body = R"(
   5601 %val1 = OpExtInst %f32 %extinst nan %f32_3
   5602 )";
   5603 
   5604   CompileSuccessfully(GenerateKernelCode(body));
   5605   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5606   EXPECT_THAT(getDiagnosticString(),
   5607               HasSubstr("OpenCL.std nan: "
   5608                         "expected Nancode to be an int scalar or vector type"));
   5609 }
   5610 
   5611 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
   5612   const std::string body = R"(
   5613 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
   5614 )";
   5615 
   5616   CompileSuccessfully(GenerateKernelCode(body));
   5617   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5618   EXPECT_THAT(getDiagnosticString(),
   5619               HasSubstr("OpenCL.std nan: "
   5620                         "expected Nancode to have the same number of "
   5621                         "components as Result Type"));
   5622 }
   5623 
   5624 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
   5625   const std::string body = R"(
   5626 %val1 = OpExtInst %f64 %extinst nan %u32_2
   5627 )";
   5628 
   5629   CompileSuccessfully(GenerateKernelCode(body));
   5630   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5631   EXPECT_THAT(
   5632       getDiagnosticString(),
   5633       HasSubstr("OpenCL.std nan: "
   5634                 "expected Nancode to have the same bit width as Result Type"));
   5635 }
   5636 
   5637 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
   5638   const std::string ext_inst_name = GetParam();
   5639   std::ostringstream ss;
   5640   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5641      << " %f32_0 %u32_1\n";
   5642   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
   5643      << " %f32vec2_12 %u32vec2_12\n";
   5644 
   5645   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5646   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5647 }
   5648 
   5649 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
   5650   const std::string ext_inst_name = GetParam();
   5651   std::ostringstream ss;
   5652   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
   5653      << " %f32_0 %u32_1\n";
   5654 
   5655   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5656   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5657   EXPECT_THAT(
   5658       getDiagnosticString(),
   5659       HasSubstr("OpenCL.std " + ext_inst_name +
   5660                 ": expected Result Type to be a float scalar or vector type"));
   5661 }
   5662 
   5663 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
   5664   const std::string ext_inst_name = GetParam();
   5665   std::ostringstream ss;
   5666   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5667      << " %u32_0 %u32_1\n";
   5668 
   5669   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5670   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5671   EXPECT_THAT(
   5672       getDiagnosticString(),
   5673       HasSubstr("OpenCL.std " + ext_inst_name +
   5674                 ": expected type of operand X to be equal to Result Type"));
   5675 }
   5676 
   5677 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
   5678   const std::string ext_inst_name = GetParam();
   5679   std::ostringstream ss;
   5680   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5681      << " %f32_0 %f32_1\n";
   5682 
   5683   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5684   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5685   EXPECT_THAT(
   5686       getDiagnosticString(),
   5687       HasSubstr("OpenCL.std " + ext_inst_name +
   5688                 ": expected the exponent to be a 32-bit int scalar or vector"));
   5689 }
   5690 
   5691 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
   5692   const std::string ext_inst_name = GetParam();
   5693   std::ostringstream ss;
   5694   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5695      << " %f32_0 %u64_1\n";
   5696 
   5697   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5698   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5699   EXPECT_THAT(
   5700       getDiagnosticString(),
   5701       HasSubstr("OpenCL.std " + ext_inst_name +
   5702                 ": expected the exponent to be a 32-bit int scalar or vector"));
   5703 }
   5704 
   5705 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
   5706   const std::string ext_inst_name = GetParam();
   5707   std::ostringstream ss;
   5708   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
   5709      << " %f32_0 %u32vec2_01\n";
   5710 
   5711   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5712   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5713   EXPECT_THAT(getDiagnosticString(),
   5714               HasSubstr("OpenCL.std " + ext_inst_name +
   5715                         ": expected the exponent to have the same number of "
   5716                         "components as Result Type"));
   5717 }
   5718 
   5719 INSTANTIATE_TEST_CASE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
   5720                         ::testing::ValuesIn(std::vector<std::string>{
   5721                             "ldexp",
   5722                             "pown",
   5723                             "rootn",
   5724                         }), );
   5725 
   5726 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
   5727   const std::string ext_inst_name = GetParam();
   5728   std::ostringstream ss;
   5729   ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
   5730   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
   5731      << " %u16_1 %u16_2\n";
   5732   ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
   5733      << " %u32_1 %u32_2\n";
   5734   ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
   5735      << " %u32vec2_01 %u32vec2_01\n";
   5736 
   5737   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5738   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   5739 }
   5740 
   5741 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
   5742   const std::string ext_inst_name = GetParam();
   5743   std::ostringstream ss;
   5744   ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
   5745      << " %u32_1 %u32_2\n";
   5746 
   5747   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5748   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5749   EXPECT_THAT(
   5750       getDiagnosticString(),
   5751       HasSubstr("OpenCL.std " + ext_inst_name +
   5752                 ": expected Result Type to be an int scalar or vector type"));
   5753 }
   5754 
   5755 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
   5756   const std::string ext_inst_name = GetParam();
   5757   std::ostringstream ss;
   5758   ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
   5759 
   5760   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5761   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5762   EXPECT_THAT(
   5763       getDiagnosticString(),
   5764       HasSubstr(
   5765           "OpenCL.std " + ext_inst_name +
   5766           ": expected bit width of Result Type components to be 16, 32 or 64"));
   5767 }
   5768 
   5769 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
   5770   const std::string ext_inst_name = GetParam();
   5771   std::ostringstream ss;
   5772   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
   5773      << " %u32_1 %u16_2\n";
   5774 
   5775   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5776   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5777   EXPECT_THAT(getDiagnosticString(),
   5778               HasSubstr("OpenCL.std " + ext_inst_name +
   5779                         ": expected Hi and Lo operands to have the same type"));
   5780 }
   5781 
   5782 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
   5783   const std::string ext_inst_name = GetParam();
   5784   std::ostringstream ss;
   5785   ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
   5786      << " %u32_1 %u32_2\n";
   5787 
   5788   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5789   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5790   EXPECT_THAT(getDiagnosticString(),
   5791               HasSubstr("OpenCL.std " + ext_inst_name +
   5792                         ": expected Hi and Lo operands to have the same number "
   5793                         "of components as Result Type"));
   5794 }
   5795 
   5796 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
   5797   const std::string ext_inst_name = GetParam();
   5798   std::ostringstream ss;
   5799   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
   5800      << " %u16_1 %u16_2\n";
   5801 
   5802   CompileSuccessfully(GenerateKernelCode(ss.str()));
   5803   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   5804   EXPECT_THAT(
   5805       getDiagnosticString(),
   5806       HasSubstr("OpenCL.std " + ext_inst_name +
   5807                 ": expected bit width of components of Hi and Lo operands to "
   5808                 "be half of the bit width of components of Result Type"));
   5809 }
   5810 
   5811 INSTANTIATE_TEST_CASE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
   5812                         ::testing::ValuesIn(std::vector<std::string>{
   5813                             "u_upsample",
   5814                             "s_upsample",
   5815                         }), );
   5816 
   5817 }  // namespace
   5818 }  // namespace val
   5819 }  // namespace spvtools
   5820