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