• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ValidateOldDebugInfo = spvtest::ValidateBase<std::string>;
37 using ValidateOpenCL100DebugInfo = spvtest::ValidateBase<std::string>;
38 using ValidateLocalDebugInfoOutOfFunction = spvtest::ValidateBase<std::string>;
39 using ValidateOpenCL100DebugInfoDebugTypedef =
40     spvtest::ValidateBase<std::pair<std::string, std::string>>;
41 using ValidateOpenCL100DebugInfoDebugTypeEnum =
42     spvtest::ValidateBase<std::pair<std::string, std::string>>;
43 using ValidateOpenCL100DebugInfoDebugTypeComposite =
44     spvtest::ValidateBase<std::pair<std::string, std::string>>;
45 using ValidateOpenCL100DebugInfoDebugTypeMember =
46     spvtest::ValidateBase<std::pair<std::string, std::string>>;
47 using ValidateOpenCL100DebugInfoDebugTypeInheritance =
48     spvtest::ValidateBase<std::pair<std::string, std::string>>;
49 using ValidateOpenCL100DebugInfoDebugFunction =
50     spvtest::ValidateBase<std::pair<std::string, std::string>>;
51 using ValidateOpenCL100DebugInfoDebugFunctionDeclaration =
52     spvtest::ValidateBase<std::pair<std::string, std::string>>;
53 using ValidateOpenCL100DebugInfoDebugLexicalBlock =
54     spvtest::ValidateBase<std::pair<std::string, std::string>>;
55 using ValidateOpenCL100DebugInfoDebugLocalVariable =
56     spvtest::ValidateBase<std::pair<std::string, std::string>>;
57 using ValidateOpenCL100DebugInfoDebugDeclare =
58     spvtest::ValidateBase<std::pair<std::string, std::string>>;
59 using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>;
60 using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>;
61 using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>;
62 using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>;
63 using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>;
64 using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>;
65 using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>;
66 using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>;
67 using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>;
68 using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>;
69 using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>;
70 using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>;
71 using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>;
72 using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>;
73 using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>;
74 using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>;
75 using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>;
76 using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>;
77 using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>;
78 using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>;
79 using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>;
80 using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>;
81 using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>;
82 using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>;
83 using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>;
84 using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>;
85 using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>;
86 
87 // Returns number of components in Pack/Unpack extended instructions.
88 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
89 // Number of components is assumed to be single-digit.
GetPackedNumComponents(const std::string & ext_inst_name)90 uint32_t GetPackedNumComponents(const std::string& ext_inst_name) {
91   const size_t x_index = ext_inst_name.find_last_of('x');
92   const std::string num_components_str =
93       ext_inst_name.substr(x_index - 1, x_index);
94   return uint32_t(std::stoul(num_components_str));
95 }
96 
97 // Returns packed bit width in Pack/Unpack extended instructions.
98 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
GetPackedBitWidth(const std::string & ext_inst_name)99 uint32_t GetPackedBitWidth(const std::string& ext_inst_name) {
100   const size_t x_index = ext_inst_name.find_last_of('x');
101   const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1);
102   return uint32_t(std::stoul(packed_bit_width_str));
103 }
104 
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")105 std::string GenerateShaderCode(
106     const std::string& body,
107     const std::string& capabilities_and_extensions = "",
108     const std::string& execution_model = "Fragment") {
109   std::ostringstream ss;
110   ss << R"(
111 OpCapability Shader
112 OpCapability Float16
113 OpCapability Float64
114 OpCapability Int16
115 OpCapability Int64
116 )";
117 
118   ss << capabilities_and_extensions;
119   ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
120   ss << "OpMemoryModel Logical GLSL450\n";
121   ss << "OpEntryPoint " << execution_model << " %main \"main\""
122      << " %f32_output"
123      << " %f32vec2_output"
124      << " %u32_output"
125      << " %u32vec2_output"
126      << " %u64_output"
127      << " %f32_input"
128      << " %f32vec2_input"
129      << " %u32_input"
130      << " %u32vec2_input"
131      << " %u64_input"
132      << "\n";
133   if (execution_model == "Fragment") {
134     ss << "OpExecutionMode %main OriginUpperLeft\n";
135   }
136 
137   ss << R"(
138 %void = OpTypeVoid
139 %func = OpTypeFunction %void
140 %bool = OpTypeBool
141 %f16 = OpTypeFloat 16
142 %f32 = OpTypeFloat 32
143 %f64 = OpTypeFloat 64
144 %u32 = OpTypeInt 32 0
145 %s32 = OpTypeInt 32 1
146 %u64 = OpTypeInt 64 0
147 %s64 = OpTypeInt 64 1
148 %u16 = OpTypeInt 16 0
149 %s16 = OpTypeInt 16 1
150 %f32vec2 = OpTypeVector %f32 2
151 %f32vec3 = OpTypeVector %f32 3
152 %f32vec4 = OpTypeVector %f32 4
153 %f64vec2 = OpTypeVector %f64 2
154 %f64vec3 = OpTypeVector %f64 3
155 %f64vec4 = OpTypeVector %f64 4
156 %u32vec2 = OpTypeVector %u32 2
157 %u32vec3 = OpTypeVector %u32 3
158 %s32vec2 = OpTypeVector %s32 2
159 %u32vec4 = OpTypeVector %u32 4
160 %s32vec4 = OpTypeVector %s32 4
161 %u64vec2 = OpTypeVector %u64 2
162 %s64vec2 = OpTypeVector %s64 2
163 %f64mat22 = OpTypeMatrix %f64vec2 2
164 %f32mat22 = OpTypeMatrix %f32vec2 2
165 %f32mat23 = OpTypeMatrix %f32vec2 3
166 %f32mat32 = OpTypeMatrix %f32vec3 2
167 %f32mat33 = OpTypeMatrix %f32vec3 3
168 
169 %f32_0 = OpConstant %f32 0
170 %f32_1 = OpConstant %f32 1
171 %f32_2 = OpConstant %f32 2
172 %f32_3 = OpConstant %f32 3
173 %f32_4 = OpConstant %f32 4
174 %f32_h = OpConstant %f32 0.5
175 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
176 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
177 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
178 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
179 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
180 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
181 
182 %f64_0 = OpConstant %f64 0
183 %f64_1 = OpConstant %f64 1
184 %f64_2 = OpConstant %f64 2
185 %f64_3 = OpConstant %f64 3
186 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
187 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
188 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
189 
190 %f16_0 = OpConstant %f16 0
191 %f16_1 = OpConstant %f16 1
192 %f16_h = OpConstant %f16 0.5
193 
194 %u32_0 = OpConstant %u32 0
195 %u32_1 = OpConstant %u32 1
196 %u32_2 = OpConstant %u32 2
197 %u32_3 = OpConstant %u32 3
198 
199 %s32_0 = OpConstant %s32 0
200 %s32_1 = OpConstant %s32 1
201 %s32_2 = OpConstant %s32 2
202 %s32_3 = OpConstant %s32 3
203 
204 %u64_0 = OpConstant %u64 0
205 %u64_1 = OpConstant %u64 1
206 %u64_2 = OpConstant %u64 2
207 %u64_3 = OpConstant %u64 3
208 
209 %s64_0 = OpConstant %s64 0
210 %s64_1 = OpConstant %s64 1
211 %s64_2 = OpConstant %s64 2
212 %s64_3 = OpConstant %s64 3
213 
214 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
215 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
216 
217 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
218 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
219 
220 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
221 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
222 
223 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
224 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
225 
226 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
227 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
228 
229 %f32_ptr_output = OpTypePointer Output %f32
230 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
231 
232 %u32_ptr_output = OpTypePointer Output %u32
233 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
234 
235 %u64_ptr_output = OpTypePointer Output %u64
236 
237 %f32_output = OpVariable %f32_ptr_output Output
238 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
239 
240 %u32_output = OpVariable %u32_ptr_output Output
241 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
242 
243 %u64_output = OpVariable %u64_ptr_output Output
244 
245 %f32_ptr_input = OpTypePointer Input %f32
246 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
247 
248 %u32_ptr_input = OpTypePointer Input %u32
249 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
250 
251 %u64_ptr_input = OpTypePointer Input %u64
252 
253 %f32_input = OpVariable %f32_ptr_input Input
254 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
255 
256 %u32_input = OpVariable %u32_ptr_input Input
257 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
258 
259 %u64_input = OpVariable %u64_ptr_input Input
260 
261 %struct_f16_u16 = OpTypeStruct %f16 %u16
262 %struct_f32_f32 = OpTypeStruct %f32 %f32
263 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
264 %struct_f32_u32 = OpTypeStruct %f32 %u32
265 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
266 %struct_u32_f32 = OpTypeStruct %u32 %f32
267 %struct_u32_u32 = OpTypeStruct %u32 %u32
268 %struct_f32_f64 = OpTypeStruct %f32 %f64
269 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
270 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
271 
272 %main = OpFunction %void None %func
273 %main_entry = OpLabel
274 )";
275 
276   ss << body;
277 
278   ss << R"(
279 OpReturn
280 OpFunctionEnd)";
281 
282   return ss.str();
283 }
284 
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & memory_model="Physical32")285 std::string GenerateKernelCode(
286     const std::string& body,
287     const std::string& capabilities_and_extensions = "",
288     const std::string& memory_model = "Physical32") {
289   std::ostringstream ss;
290   ss << R"(
291 OpCapability Addresses
292 OpCapability Kernel
293 OpCapability Linkage
294 OpCapability GenericPointer
295 OpCapability Int8
296 OpCapability Int16
297 OpCapability Int64
298 OpCapability Float16
299 OpCapability Float64
300 OpCapability Vector16
301 OpCapability Matrix
302 )";
303 
304   ss << capabilities_and_extensions;
305   ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n";
306   ss << "OpMemoryModel " << memory_model << " OpenCL\n";
307 
308   ss << R"(
309 %void = OpTypeVoid
310 %func = OpTypeFunction %void
311 %bool = OpTypeBool
312 %f16 = OpTypeFloat 16
313 %f32 = OpTypeFloat 32
314 %f64 = OpTypeFloat 64
315 %u32 = OpTypeInt 32 0
316 %u64 = OpTypeInt 64 0
317 %u16 = OpTypeInt 16 0
318 %u8 = OpTypeInt 8 0
319 %f32vec2 = OpTypeVector %f32 2
320 %f32vec3 = OpTypeVector %f32 3
321 %f32vec4 = OpTypeVector %f32 4
322 %f32vec8 = OpTypeVector %f32 8
323 %f16vec8 = OpTypeVector %f16 8
324 %f32vec16 = OpTypeVector %f32 16
325 %f64vec2 = OpTypeVector %f64 2
326 %f64vec3 = OpTypeVector %f64 3
327 %f64vec4 = OpTypeVector %f64 4
328 %u32vec2 = OpTypeVector %u32 2
329 %u32vec3 = OpTypeVector %u32 3
330 %u32vec4 = OpTypeVector %u32 4
331 %u32vec8 = OpTypeVector %u32 8
332 %u64vec2 = OpTypeVector %u64 2
333 %f64mat22 = OpTypeMatrix %f64vec2 2
334 %f32mat22 = OpTypeMatrix %f32vec2 2
335 %f32mat23 = OpTypeMatrix %f32vec2 3
336 %f32mat32 = OpTypeMatrix %f32vec3 2
337 %f32mat33 = OpTypeMatrix %f32vec3 3
338 
339 %f32_0 = OpConstant %f32 0
340 %f32_1 = OpConstant %f32 1
341 %f32_2 = OpConstant %f32 2
342 %f32_3 = OpConstant %f32 3
343 %f32_4 = OpConstant %f32 4
344 %f32_h = OpConstant %f32 0.5
345 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
346 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
347 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
348 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
349 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
350 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
351 %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1
352 
353 %f64_0 = OpConstant %f64 0
354 %f64_1 = OpConstant %f64 1
355 %f64_2 = OpConstant %f64 2
356 %f64_3 = OpConstant %f64 3
357 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
358 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
359 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
360 
361 %f16_0 = OpConstant %f16 0
362 %f16_1 = OpConstant %f16 1
363 
364 %u8_0 = OpConstant %u8 0
365 %u8_1 = OpConstant %u8 1
366 %u8_2 = OpConstant %u8 2
367 %u8_3 = OpConstant %u8 3
368 
369 %u16_0 = OpConstant %u16 0
370 %u16_1 = OpConstant %u16 1
371 %u16_2 = OpConstant %u16 2
372 %u16_3 = OpConstant %u16 3
373 
374 %u32_0 = OpConstant %u32 0
375 %u32_1 = OpConstant %u32 1
376 %u32_2 = OpConstant %u32 2
377 %u32_3 = OpConstant %u32 3
378 %u32_256 = OpConstant %u32 256
379 
380 %u64_0 = OpConstant %u64 0
381 %u64_1 = OpConstant %u64 1
382 %u64_2 = OpConstant %u64 2
383 %u64_3 = OpConstant %u64 3
384 %u64_256 = OpConstant %u64 256
385 
386 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
387 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
388 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
389 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
390 
391 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
392 
393 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
394 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
395 
396 %struct_f32_f32 = OpTypeStruct %f32 %f32
397 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
398 %struct_f32_u32 = OpTypeStruct %f32 %u32
399 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
400 %struct_u32_f32 = OpTypeStruct %u32 %f32
401 %struct_u32_u32 = OpTypeStruct %u32 %u32
402 %struct_f32_f64 = OpTypeStruct %f32 %f64
403 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
404 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
405 
406 %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8
407 %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup
408 %f16_ptr_workgroup = OpTypePointer Workgroup %f16
409 
410 %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8
411 %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup
412 %u32_ptr_workgroup = OpTypePointer Workgroup %u32
413 
414 %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8
415 %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup
416 %f32_ptr_workgroup = OpTypePointer Workgroup %f32
417 
418 %u32arr = OpTypeArray %u32 %u32_256
419 %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr
420 %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup
421 %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32
422 
423 %f32arr = OpTypeArray %f32 %u32_256
424 %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr
425 %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup
426 %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32
427 
428 %f32vec2arr = OpTypeArray %f32vec2 %u32_256
429 %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr
430 %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup
431 %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2
432 
433 %struct_arr = OpTypeArray %struct_f32_f32 %u32_256
434 %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr
435 %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup
436 %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32
437 
438 %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8
439 %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant
440 %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16
441 
442 %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8
443 %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant
444 %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32
445 
446 %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8
447 %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant
448 %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32
449 
450 %f16vec8_ptr_input = OpTypePointer Input %f16vec8
451 %f16vec8_input = OpVariable %f16vec8_ptr_input Input
452 %f16_ptr_input = OpTypePointer Input %f16
453 
454 %u32vec8_ptr_input = OpTypePointer Input %u32vec8
455 %u32vec8_input = OpVariable %u32vec8_ptr_input Input
456 %u32_ptr_input = OpTypePointer Input %u32
457 
458 %f32_ptr_generic = OpTypePointer Generic %f32
459 %u32_ptr_generic = OpTypePointer Generic %u32
460 
461 %f32_ptr_function = OpTypePointer Function %f32
462 %f32vec2_ptr_function = OpTypePointer Function %f32vec2
463 %u32_ptr_function = OpTypePointer Function %u32
464 %u64_ptr_function = OpTypePointer Function %u64
465 %u32vec2_ptr_function = OpTypePointer Function %u32vec2
466 
467 %u8arr = OpTypeArray %u8 %u32_256
468 %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr
469 %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant
470 %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8
471 %u8_ptr_generic = OpTypePointer Generic %u8
472 
473 %main = OpFunction %void None %func
474 %main_entry = OpLabel
475 )";
476 
477   ss << body;
478 
479   ss << R"(
480 OpReturn
481 OpFunctionEnd)";
482 
483   return ss.str();
484 }
485 
GenerateShaderCodeForDebugInfo(const std::string & op_string_instructions,const std::string & op_const_instructions,const std::string & debug_instructions_before_main,const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")486 std::string GenerateShaderCodeForDebugInfo(
487     const std::string& op_string_instructions,
488     const std::string& op_const_instructions,
489     const std::string& debug_instructions_before_main, const std::string& body,
490     const std::string& capabilities_and_extensions = "",
491     const std::string& execution_model = "Fragment") {
492   std::ostringstream ss;
493   ss << R"(
494 OpCapability Shader
495 OpCapability Float16
496 OpCapability Float64
497 OpCapability Int16
498 OpCapability Int64
499 )";
500 
501   ss << capabilities_and_extensions;
502   ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
503   ss << "OpMemoryModel Logical GLSL450\n";
504   ss << "OpEntryPoint " << execution_model << " %main \"main\""
505      << " %f32_output"
506      << " %f32vec2_output"
507      << " %u32_output"
508      << " %u32vec2_output"
509      << " %u64_output"
510      << " %f32_input"
511      << " %f32vec2_input"
512      << " %u32_input"
513      << " %u32vec2_input"
514      << " %u64_input"
515      << "\n";
516   if (execution_model == "Fragment") {
517     ss << "OpExecutionMode %main OriginUpperLeft\n";
518   }
519 
520   ss << op_string_instructions;
521 
522   ss << R"(
523 %void = OpTypeVoid
524 %func = OpTypeFunction %void
525 %bool = OpTypeBool
526 %f16 = OpTypeFloat 16
527 %f32 = OpTypeFloat 32
528 %f64 = OpTypeFloat 64
529 %u32 = OpTypeInt 32 0
530 %s32 = OpTypeInt 32 1
531 %u64 = OpTypeInt 64 0
532 %s64 = OpTypeInt 64 1
533 %u16 = OpTypeInt 16 0
534 %s16 = OpTypeInt 16 1
535 %f32vec2 = OpTypeVector %f32 2
536 %f32vec3 = OpTypeVector %f32 3
537 %f32vec4 = OpTypeVector %f32 4
538 %f64vec2 = OpTypeVector %f64 2
539 %f64vec3 = OpTypeVector %f64 3
540 %f64vec4 = OpTypeVector %f64 4
541 %u32vec2 = OpTypeVector %u32 2
542 %u32vec3 = OpTypeVector %u32 3
543 %s32vec2 = OpTypeVector %s32 2
544 %u32vec4 = OpTypeVector %u32 4
545 %s32vec4 = OpTypeVector %s32 4
546 %u64vec2 = OpTypeVector %u64 2
547 %s64vec2 = OpTypeVector %s64 2
548 %f64mat22 = OpTypeMatrix %f64vec2 2
549 %f32mat22 = OpTypeMatrix %f32vec2 2
550 %f32mat23 = OpTypeMatrix %f32vec2 3
551 %f32mat32 = OpTypeMatrix %f32vec3 2
552 %f32mat33 = OpTypeMatrix %f32vec3 3
553 
554 %f32_0 = OpConstant %f32 0
555 %f32_1 = OpConstant %f32 1
556 %f32_2 = OpConstant %f32 2
557 %f32_3 = OpConstant %f32 3
558 %f32_4 = OpConstant %f32 4
559 %f32_h = OpConstant %f32 0.5
560 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
561 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
562 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
563 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
564 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
565 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
566 
567 %f64_0 = OpConstant %f64 0
568 %f64_1 = OpConstant %f64 1
569 %f64_2 = OpConstant %f64 2
570 %f64_3 = OpConstant %f64 3
571 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
572 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
573 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
574 
575 %f16_0 = OpConstant %f16 0
576 %f16_1 = OpConstant %f16 1
577 %f16_h = OpConstant %f16 0.5
578 
579 %u32_0 = OpConstant %u32 0
580 %u32_1 = OpConstant %u32 1
581 %u32_2 = OpConstant %u32 2
582 %u32_3 = OpConstant %u32 3
583 
584 %s32_0 = OpConstant %s32 0
585 %s32_1 = OpConstant %s32 1
586 %s32_2 = OpConstant %s32 2
587 %s32_3 = OpConstant %s32 3
588 
589 %u64_0 = OpConstant %u64 0
590 %u64_1 = OpConstant %u64 1
591 %u64_2 = OpConstant %u64 2
592 %u64_3 = OpConstant %u64 3
593 
594 %s64_0 = OpConstant %s64 0
595 %s64_1 = OpConstant %s64 1
596 %s64_2 = OpConstant %s64 2
597 %s64_3 = OpConstant %s64 3
598 )";
599 
600   ss << op_const_instructions;
601 
602   ss << R"(
603 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
604 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
605 
606 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
607 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
608 
609 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
610 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
611 
612 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
613 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
614 
615 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
616 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
617 
618 %f32_ptr_output = OpTypePointer Output %f32
619 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
620 
621 %u32_ptr_output = OpTypePointer Output %u32
622 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
623 
624 %u64_ptr_output = OpTypePointer Output %u64
625 
626 %f32_output = OpVariable %f32_ptr_output Output
627 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
628 
629 %u32_output = OpVariable %u32_ptr_output Output
630 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
631 
632 %u64_output = OpVariable %u64_ptr_output Output
633 
634 %f32_ptr_input = OpTypePointer Input %f32
635 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
636 
637 %u32_ptr_input = OpTypePointer Input %u32
638 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
639 
640 %u64_ptr_input = OpTypePointer Input %u64
641 
642 %f32_ptr_function = OpTypePointer Function %f32
643 
644 %f32_input = OpVariable %f32_ptr_input Input
645 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
646 
647 %u32_input = OpVariable %u32_ptr_input Input
648 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
649 
650 %u64_input = OpVariable %u64_ptr_input Input
651 
652 %u32_ptr_function = OpTypePointer Function %u32
653 
654 %struct_f16_u16 = OpTypeStruct %f16 %u16
655 %struct_f32_f32 = OpTypeStruct %f32 %f32
656 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
657 %struct_f32_u32 = OpTypeStruct %f32 %u32
658 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
659 %struct_u32_f32 = OpTypeStruct %u32 %f32
660 %struct_u32_u32 = OpTypeStruct %u32 %u32
661 %struct_f32_f64 = OpTypeStruct %f32 %f64
662 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
663 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
664 )";
665 
666   ss << debug_instructions_before_main;
667 
668   ss << R"(
669 %main = OpFunction %void None %func
670 %main_entry = OpLabel
671 )";
672 
673   ss << body;
674 
675   ss << R"(
676 OpReturn
677 OpFunctionEnd)";
678 
679   return ss.str();
680 }
681 
TEST_F(ValidateOldDebugInfo,UseDebugInstructionOutOfFunction)682 TEST_F(ValidateOldDebugInfo, UseDebugInstructionOutOfFunction) {
683   const std::string src = R"(
684 %code = OpString "main() {}"
685 )";
686 
687   const std::string dbg_inst = R"(
688 %cu = OpExtInst %void %DbgExt DebugCompilationUnit %code 1 1
689 )";
690 
691   const std::string extension = R"(
692 %DbgExt = OpExtInstImport "DebugInfo"
693 )";
694 
695   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
696                                                      extension, "Vertex"));
697   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
698 }
699 
TEST_F(ValidateOpenCL100DebugInfo,UseDebugInstructionOutOfFunction)700 TEST_F(ValidateOpenCL100DebugInfo, UseDebugInstructionOutOfFunction) {
701   const std::string src = R"(
702 %src = OpString "simple.hlsl"
703 %code = OpString "main() {}"
704 )";
705 
706   const std::string dbg_inst = R"(
707 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
708 )";
709 
710   const std::string extension = R"(
711 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
712 )";
713 
714   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
715                                                      extension, "Vertex"));
716   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
717 }
718 
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceInFunction)719 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceInFunction) {
720   const std::string src = R"(
721 %src = OpString "simple.hlsl"
722 %code = OpString "main() {}"
723 )";
724 
725   const std::string dbg_inst = R"(
726 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
727 )";
728 
729   const std::string extension = R"(
730 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
731 )";
732 
733   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", "", dbg_inst,
734                                                      extension, "Vertex"));
735   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
736   EXPECT_THAT(
737       getDiagnosticString(),
738       HasSubstr("Debug info extension instructions other than DebugScope, "
739                 "DebugNoScope, DebugDeclare, DebugValue must appear between "
740                 "section 9 (types, constants, global variables) and section 10 "
741                 "(function declarations)"));
742 }
743 
TEST_P(ValidateLocalDebugInfoOutOfFunction,OpenCLDebugInfo100DebugScope)744 TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) {
745   const std::string src = R"(
746 %src = OpString "simple.hlsl"
747 %code = OpString "void main() {}"
748 %void_name = OpString "void"
749 %main_name = OpString "main"
750 %main_linkage_name = OpString "v_main"
751 %int_name = OpString "int"
752 %foo_name = OpString "foo"
753 )";
754 
755   const std::string dbg_inst_header = R"(
756 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
757 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
758 %void_info = OpExtInst %void %DbgExt DebugTypeBasic %void_name %u32_0 Unspecified
759 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 Signed
760 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void_info %void_info
761 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
762 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %int_info %dbg_src 1 1 %main_info FlagIsLocal
763 %expr = OpExtInst %void %DbgExt DebugExpression
764 )";
765 
766   const std::string body = R"(
767 %foo = OpVariable %u32_ptr_function Function
768 %foo_val = OpLoad %u32 %foo
769 )";
770 
771   const std::string extension = R"(
772 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
773 )";
774 
775   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
776       src, "", dbg_inst_header + GetParam(), body, extension, "Vertex"));
777   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
778   EXPECT_THAT(getDiagnosticString(),
779               HasSubstr("DebugScope, DebugNoScope, DebugDeclare, DebugValue "
780                         "of debug info extension must appear in a function "
781                         "body"));
782 }
783 
784 INSTANTIATE_TEST_SUITE_P(
785     AllLocalDebugInfo, ValidateLocalDebugInfoOutOfFunction,
786     ::testing::ValuesIn(std::vector<std::string>{
787         "%main_scope = OpExtInst %void %DbgExt DebugScope %main_info",
788         "%no_scope = OpExtInst %void %DbgExt DebugNoScope",
789     }));
790 
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionForwardReference)791 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionForwardReference) {
792   const std::string src = R"(
793 %src = OpString "simple.hlsl"
794 %code = OpString "void main() {}"
795 %void_name = OpString "void"
796 %main_name = OpString "main"
797 %main_linkage_name = OpString "v_main"
798 )";
799 
800   const std::string dbg_inst_header = R"(
801 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
802 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
803 %void_info = OpExtInst %void %DbgExt DebugTypeBasic %void_name %u32_0 Unspecified
804 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void_info %void_info
805 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
806 )";
807 
808   const std::string body = R"(
809 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
810 )";
811 
812   const std::string extension = R"(
813 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
814 )";
815 
816   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
817       src, "", dbg_inst_header, body, extension, "Vertex"));
818   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
819 }
820 
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionMissingOpFunction)821 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionMissingOpFunction) {
822   const std::string src = R"(
823 %src = OpString "simple.hlsl"
824 %code = OpString "void main() {}"
825 %void_name = OpString "void"
826 %main_name = OpString "main"
827 %main_linkage_name = OpString "v_main"
828 )";
829 
830   const std::string dbg_inst_header = R"(
831 %dbgNone = OpExtInst %void %DbgExt DebugInfoNone
832 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
833 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
834 %void_info = OpExtInst %void %DbgExt DebugTypeBasic %void_name %u32_0 Unspecified
835 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void_info %void_info
836 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %dbgNone
837 )";
838 
839   const std::string body = R"(
840 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
841 )";
842 
843   const std::string extension = R"(
844 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
845 )";
846 
847   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
848       src, "", dbg_inst_header, body, extension, "Vertex"));
849   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
850 }
851 
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeBeforeOpVariableInFunction)852 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeBeforeOpVariableInFunction) {
853   const std::string src = R"(
854 %src = OpString "simple.hlsl"
855 %code = OpString "float4 main(float arg) {
856   float foo;
857   return float4(0, 0, 0, 0);
858 }
859 "
860 %float_name = OpString "float"
861 %main_name = OpString "main"
862 %main_linkage_name = OpString "v4f_main_f"
863 )";
864 
865   const std::string size_const = R"(
866 %int_32 = OpConstant %u32 32
867 )";
868 
869   const std::string dbg_inst_header = R"(
870 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
871 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
872 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
873 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
874 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
875 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
876 )";
877 
878   const std::string body = R"(
879 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
880 %foo = OpVariable %f32_ptr_function Function
881 )";
882 
883   const std::string extension = R"(
884 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
885 )";
886 
887   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
888       src, size_const, dbg_inst_header, body, extension, "Vertex"));
889   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
890 }
891 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeForwardReference)892 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeForwardReference) {
893   const std::string src = R"(
894 %src = OpString "simple.hlsl"
895 %code = OpString "struct VS_OUTPUT {
896   float4 pos : SV_POSITION;
897   float4 color : COLOR;
898 };
899 main() {}
900 "
901 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
902 %float_name = OpString "float"
903 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
904 %VS_OUTPUT_color_name = OpString "color : COLOR"
905 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
906 )";
907 
908   const std::string size_const = R"(
909 %int_32 = OpConstant %u32 32
910 %int_128 = OpConstant %u32 128
911 )";
912 
913   const std::string dbg_inst_header = R"(
914 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
915 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
916 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
917 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
918 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
919 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
920 %VS_OUTPUT_color_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_color_name %v4float_info %dbg_src 3 3 %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
921 )";
922 
923   const std::string extension = R"(
924 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
925 )";
926 
927   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
928       src, size_const, dbg_inst_header, "", extension, "Vertex"));
929   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
930 }
931 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeMissingReference)932 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeMissingReference) {
933   const std::string src = R"(
934 %src = OpString "simple.hlsl"
935 %code = OpString "struct VS_OUTPUT {
936   float4 pos : SV_POSITION;
937   float4 color : COLOR;
938 };
939 main() {}
940 "
941 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
942 %float_name = OpString "float"
943 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
944 %VS_OUTPUT_color_name = OpString "color : COLOR"
945 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
946 )";
947 
948   const std::string size_const = R"(
949 %int_32 = OpConstant %u32 32
950 %int_128 = OpConstant %u32 128
951 )";
952 
953   const std::string dbg_inst_header = R"(
954 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
955 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
956 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
957 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
958 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
959 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
960 )";
961 
962   const std::string extension = R"(
963 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
964 )";
965 
966   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
967       src, size_const, dbg_inst_header, "", extension, "Vertex"));
968   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
969   EXPECT_THAT(getDiagnosticString(),
970               HasSubstr("forward referenced IDs have not been defined"));
971 }
972 
TEST_F(ValidateOpenCL100DebugInfo,DebugInstructionWrongResultType)973 TEST_F(ValidateOpenCL100DebugInfo, DebugInstructionWrongResultType) {
974   const std::string src = R"(
975 %src = OpString "simple.hlsl"
976 %code = OpString "main() {}"
977 )";
978 
979   const std::string dbg_inst = R"(
980 %dbg_src = OpExtInst %bool %DbgExt DebugSource %src %code
981 )";
982 
983   const std::string extension = R"(
984 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
985 )";
986 
987   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
988                                                      extension, "Vertex"));
989   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
990   EXPECT_THAT(getDiagnosticString(),
991               HasSubstr("expected result type must be a result id of "
992                         "OpTypeVoid"));
993 }
994 
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnit)995 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnit) {
996   const std::string src = R"(
997 %src = OpString "simple.hlsl"
998 %code = OpString "main() {}"
999 )";
1000 
1001   const std::string dbg_inst = R"(
1002 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1003 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1004 )";
1005 
1006   const std::string extension = R"(
1007 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1008 )";
1009 
1010   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1011                                                      extension, "Vertex"));
1012   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1013 }
1014 
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnitFail)1015 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnitFail) {
1016   const std::string src = R"(
1017 %src = OpString "simple.hlsl"
1018 %code = OpString "main() {}"
1019 )";
1020 
1021   const std::string dbg_inst = R"(
1022 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1023 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %src HLSL
1024 )";
1025 
1026   const std::string extension = R"(
1027 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1028 )";
1029 
1030   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1031                                                      extension, "Vertex"));
1032   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1033   EXPECT_THAT(getDiagnosticString(),
1034               HasSubstr("expected operand Source must be a result id of "
1035                         "DebugSource"));
1036 }
1037 
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailFile)1038 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailFile) {
1039   const std::string src = R"(
1040 %code = OpString "main() {}"
1041 )";
1042 
1043   const std::string dbg_inst = R"(
1044 %dbg_src = OpExtInst %void %DbgExt DebugSource %DbgExt %code
1045 )";
1046 
1047   const std::string extension = R"(
1048 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1049 )";
1050 
1051   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1052                                                      extension, "Vertex"));
1053   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1054   EXPECT_THAT(getDiagnosticString(),
1055               HasSubstr("expected operand File must be a result id of "
1056                         "OpString"));
1057 }
1058 
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailSource)1059 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailSource) {
1060   const std::string src = R"(
1061 %src = OpString "simple.hlsl"
1062 )";
1063 
1064   const std::string dbg_inst = R"(
1065 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %DbgExt
1066 )";
1067 
1068   const std::string extension = R"(
1069 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1070 )";
1071 
1072   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1073                                                      extension, "Vertex"));
1074   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1075   EXPECT_THAT(getDiagnosticString(),
1076               HasSubstr("expected operand Text must be a result id of "
1077                         "OpString"));
1078 }
1079 
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceNoText)1080 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceNoText) {
1081   const std::string src = R"(
1082 %src = OpString "simple.hlsl"
1083 )";
1084 
1085   const std::string dbg_inst = R"(
1086 %dbg_src = OpExtInst %void %DbgExt DebugSource %src
1087 )";
1088 
1089   const std::string extension = R"(
1090 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1091 )";
1092 
1093   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1094                                                      extension, "Vertex"));
1095   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1096 }
1097 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailName)1098 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailName) {
1099   const std::string src = R"(
1100 %src = OpString "simple.hlsl"
1101 %code = OpString "float4 main(float arg) {
1102   float foo;
1103   return float4(0, 0, 0, 0);
1104 }
1105 "
1106 %float_name = OpString "float"
1107 )";
1108 
1109   const std::string size_const = R"(
1110 %int_32 = OpConstant %u32 32
1111 )";
1112 
1113   const std::string dbg_inst_header = R"(
1114 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1115 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1116 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %int_32 %int_32 Float
1117 )";
1118 
1119   const std::string extension = R"(
1120 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1121 )";
1122 
1123   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1124       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1125   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1126   EXPECT_THAT(getDiagnosticString(),
1127               HasSubstr("expected operand Name must be a result id of "
1128                         "OpString"));
1129 }
1130 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailSize)1131 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailSize) {
1132   const std::string src = R"(
1133 %src = OpString "simple.hlsl"
1134 %code = OpString "float4 main(float arg) {
1135   float foo;
1136   return float4(0, 0, 0, 0);
1137 }
1138 "
1139 %float_name = OpString "float"
1140 )";
1141 
1142   const std::string size_const = R"(
1143 %int_32 = OpConstant %u32 32
1144 )";
1145 
1146   const std::string dbg_inst_header = R"(
1147 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1148 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1149 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %float_name Float
1150 )";
1151 
1152   const std::string extension = R"(
1153 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1154 )";
1155 
1156   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1157       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1158   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1159   EXPECT_THAT(getDiagnosticString(),
1160               HasSubstr("expected operand Size must be a result id of "
1161                         "OpConstant"));
1162 }
1163 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointer)1164 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointer) {
1165   const std::string src = R"(
1166 %src = OpString "simple.hlsl"
1167 %code = OpString "float4 main(float arg) {
1168   float foo;
1169   return float4(0, 0, 0, 0);
1170 }
1171 "
1172 %float_name = OpString "float"
1173 )";
1174 
1175   const std::string size_const = R"(
1176 %int_32 = OpConstant %u32 32
1177 )";
1178 
1179   const std::string dbg_inst_header = R"(
1180 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1181 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1182 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1183 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %float_info Function FlagIsLocal
1184 )";
1185 
1186   const std::string extension = R"(
1187 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1188 )";
1189 
1190   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1191       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1192   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1193 }
1194 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointerFail)1195 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) {
1196   const std::string src = R"(
1197 %src = OpString "simple.hlsl"
1198 %code = OpString "float4 main(float arg) {
1199   float foo;
1200   return float4(0, 0, 0, 0);
1201 }
1202 "
1203 %float_name = OpString "float"
1204 )";
1205 
1206   const std::string size_const = R"(
1207 %int_32 = OpConstant %u32 32
1208 )";
1209 
1210   const std::string dbg_inst_header = R"(
1211 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1212 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1213 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1214 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %dbg_src Function FlagIsLocal
1215 )";
1216 
1217   const std::string extension = R"(
1218 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1219 )";
1220 
1221   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1222       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1223   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1224   EXPECT_THAT(getDiagnosticString(),
1225               HasSubstr("expected operand Base Type must be a result id of "
1226                         "DebugTypeBasic"));
1227 }
1228 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifier)1229 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) {
1230   const std::string src = R"(
1231 %src = OpString "simple.hlsl"
1232 %code = OpString "float4 main(float arg) {
1233   float foo;
1234   return float4(0, 0, 0, 0);
1235 }
1236 "
1237 %float_name = OpString "float"
1238 )";
1239 
1240   const std::string size_const = R"(
1241 %int_32 = OpConstant %u32 32
1242 )";
1243 
1244   const std::string dbg_inst_header = R"(
1245 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1246 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1247 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1248 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %float_info ConstType
1249 )";
1250 
1251   const std::string extension = R"(
1252 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1253 )";
1254 
1255   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1256       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1257   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1258 }
1259 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifierFail)1260 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) {
1261   const std::string src = R"(
1262 %src = OpString "simple.hlsl"
1263 %code = OpString "float4 main(float arg) {
1264   float foo;
1265   return float4(0, 0, 0, 0);
1266 }
1267 "
1268 %float_name = OpString "float"
1269 )";
1270 
1271   const std::string size_const = R"(
1272 %int_32 = OpConstant %u32 32
1273 )";
1274 
1275   const std::string dbg_inst_header = R"(
1276 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1277 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1278 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1279 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %comp_unit ConstType
1280 )";
1281 
1282   const std::string extension = R"(
1283 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1284 )";
1285 
1286   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1287       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1288   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1289   EXPECT_THAT(getDiagnosticString(),
1290               HasSubstr("expected operand Base Type must be a result id of "
1291                         "DebugTypeBasic"));
1292 }
1293 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArray)1294 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) {
1295   const std::string src = R"(
1296 %src = OpString "simple.hlsl"
1297 %code = OpString "main() {}"
1298 %float_name = OpString "float"
1299 )";
1300 
1301   const std::string size_const = R"(
1302 %int_32 = OpConstant %u32 32
1303 )";
1304 
1305   const std::string dbg_inst_header = R"(
1306 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1307 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1308 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1309 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %int_32
1310 )";
1311 
1312   const std::string extension = R"(
1313 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1314 )";
1315 
1316   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1317       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1318   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1319 }
1320 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailBaseType)1321 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailBaseType) {
1322   const std::string src = R"(
1323 %src = OpString "simple.hlsl"
1324 %code = OpString "main() {}"
1325 %float_name = OpString "float"
1326 )";
1327 
1328   const std::string size_const = R"(
1329 %int_32 = OpConstant %u32 32
1330 )";
1331 
1332   const std::string dbg_inst_header = R"(
1333 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1334 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1335 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1336 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %comp_unit %int_32
1337 )";
1338 
1339   const std::string extension = R"(
1340 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1341 )";
1342 
1343   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1344       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1345   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1346   EXPECT_THAT(getDiagnosticString(),
1347               HasSubstr("expected operand Base Type is not a valid debug "
1348                         "type"));
1349 }
1350 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCount)1351 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCount) {
1352   const std::string src = R"(
1353 %src = OpString "simple.hlsl"
1354 %code = OpString "main() {}"
1355 %float_name = OpString "float"
1356 )";
1357 
1358   const std::string size_const = R"(
1359 %int_32 = OpConstant %u32 32
1360 )";
1361 
1362   const std::string dbg_inst_header = R"(
1363 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1364 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1365 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1366 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %float_info
1367 )";
1368 
1369   const std::string extension = R"(
1370 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1371 )";
1372 
1373   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1374       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1375   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1376   EXPECT_THAT(getDiagnosticString(),
1377               HasSubstr("expected operand Component Count must be a result id "
1378                         "of OpConstant"));
1379 }
1380 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountFloat)1381 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountFloat) {
1382   const std::string src = R"(
1383 %src = OpString "simple.hlsl"
1384 %code = OpString "main() {}"
1385 %float_name = OpString "float"
1386 )";
1387 
1388   const std::string size_const = R"(
1389 %int_32 = OpConstant %u32 32
1390 )";
1391 
1392   const std::string dbg_inst_header = R"(
1393 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1394 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1395 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1396 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %f32_4
1397 )";
1398 
1399   const std::string extension = R"(
1400 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1401 )";
1402 
1403   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1404       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1405   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1406   EXPECT_THAT(getDiagnosticString(),
1407               HasSubstr("Component Count must be positive integer"));
1408 }
1409 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountZero)1410 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountZero) {
1411   const std::string src = R"(
1412 %src = OpString "simple.hlsl"
1413 %code = OpString "main() {}"
1414 %float_name = OpString "float"
1415 )";
1416 
1417   const std::string size_const = R"(
1418 %int_32 = OpConstant %u32 32
1419 )";
1420 
1421   const std::string dbg_inst_header = R"(
1422 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1423 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1424 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1425 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_0
1426 )";
1427 
1428   const std::string extension = R"(
1429 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1430 )";
1431 
1432   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1433       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1434   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1435   EXPECT_THAT(getDiagnosticString(),
1436               HasSubstr("Component Count must be positive integer"));
1437 }
1438 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVector)1439 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVector) {
1440   const std::string src = R"(
1441 %src = OpString "simple.hlsl"
1442 %code = OpString "main() {}"
1443 %float_name = OpString "float"
1444 )";
1445 
1446   const std::string size_const = R"(
1447 %int_32 = OpConstant %u32 32
1448 )";
1449 
1450   const std::string dbg_inst_header = R"(
1451 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1452 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1453 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1454 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1455 )";
1456 
1457   const std::string extension = R"(
1458 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1459 )";
1460 
1461   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1462       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1463   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1464 }
1465 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFail)1466 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFail) {
1467   const std::string src = R"(
1468 %src = OpString "simple.hlsl"
1469 %code = OpString "main() {}"
1470 %float_name = OpString "float"
1471 )";
1472 
1473   const std::string size_const = R"(
1474 %int_32 = OpConstant %u32 32
1475 )";
1476 
1477   const std::string dbg_inst_header = R"(
1478 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1479 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1480 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1481 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 4
1482 )";
1483 
1484   const std::string extension = R"(
1485 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1486 )";
1487 
1488   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1489       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1490   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1491   EXPECT_THAT(getDiagnosticString(),
1492               HasSubstr("expected operand Base Type must be a result id of "
1493                         "DebugTypeBasic"));
1494 }
1495 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentZero)1496 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentZero) {
1497   const std::string src = R"(
1498 %src = OpString "simple.hlsl"
1499 %code = OpString "main() {}"
1500 %float_name = OpString "float"
1501 )";
1502 
1503   const std::string size_const = R"(
1504 %int_32 = OpConstant %u32 32
1505 )";
1506 
1507   const std::string dbg_inst_header = R"(
1508 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1509 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1510 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1511 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 0
1512 )";
1513 
1514   const std::string extension = R"(
1515 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1516 )";
1517 
1518   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1519       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1520   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1521   EXPECT_THAT(getDiagnosticString(),
1522               HasSubstr("expected operand Base Type must be a result id of "
1523                         "DebugTypeBasic"));
1524 }
1525 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentFive)1526 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentFive) {
1527   const std::string src = R"(
1528 %src = OpString "simple.hlsl"
1529 %code = OpString "main() {}"
1530 %float_name = OpString "float"
1531 )";
1532 
1533   const std::string size_const = R"(
1534 %int_32 = OpConstant %u32 32
1535 )";
1536 
1537   const std::string dbg_inst_header = R"(
1538 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1539 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1540 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1541 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 5
1542 )";
1543 
1544   const std::string extension = R"(
1545 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1546 )";
1547 
1548   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1549       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1550   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1551   EXPECT_THAT(getDiagnosticString(),
1552               HasSubstr("expected operand Base Type must be a result id of "
1553                         "DebugTypeBasic"));
1554 }
1555 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypedef)1556 TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) {
1557   const std::string src = R"(
1558 %src = OpString "simple.hlsl"
1559 %code = OpString "main() {}"
1560 %float_name = OpString "float"
1561 %foo_name = OpString "foo"
1562 )";
1563 
1564   const std::string size_const = R"(
1565 %int_32 = OpConstant %u32 32
1566 )";
1567 
1568   const std::string dbg_inst_header = R"(
1569 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1570 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1571 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1572 %foo_info = OpExtInst %void %DbgExt DebugTypedef %foo_name %float_info %dbg_src 1 1 %comp_unit
1573 )";
1574 
1575   const std::string extension = R"(
1576 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1577 )";
1578 
1579   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1580       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1581   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1582 }
1583 
TEST_P(ValidateOpenCL100DebugInfoDebugTypedef,Fail)1584 TEST_P(ValidateOpenCL100DebugInfoDebugTypedef, Fail) {
1585   const std::string src = R"(
1586 %src = OpString "simple.hlsl"
1587 %code = OpString "main() {}"
1588 %float_name = OpString "float"
1589 %foo_name = OpString "foo"
1590 )";
1591 
1592   const std::string size_const = R"(
1593 %int_32 = OpConstant %u32 32
1594 )";
1595 
1596   const auto& param = GetParam();
1597 
1598   std::ostringstream ss;
1599   ss << R"(
1600 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1601 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1602 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1603 %foo_info = OpExtInst %void %DbgExt DebugTypedef )";
1604   ss << param.first;
1605 
1606   const std::string extension = R"(
1607 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1608 )";
1609 
1610   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1611                                                      "", extension, "Vertex"));
1612   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1613   EXPECT_THAT(getDiagnosticString(),
1614               HasSubstr("expected operand " + param.second +
1615                         " must be a result id of "));
1616 }
1617 
1618 INSTANTIATE_TEST_SUITE_P(
1619     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypedef,
1620     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1621         std::make_pair(R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit)",
1622                        "Name"),
1623         std::make_pair(R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit)",
1624                        "Base Type"),
1625         std::make_pair(R"(%foo_name %float_info %comp_unit 1 1 %comp_unit)",
1626                        "Source"),
1627         std::make_pair(R"(%foo_name %float_info %dbg_src 1 1 %dbg_src)",
1628                        "Parent"),
1629     }));
1630 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunction)1631 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunction) {
1632   const std::string src = R"(
1633 %src = OpString "simple.hlsl"
1634 %code = OpString "main() {}"
1635 %main_name = OpString "main"
1636 %main_linkage_name = OpString "v_main"
1637 %float_name = OpString "float"
1638 )";
1639 
1640   const std::string size_const = R"(
1641 %int_32 = OpConstant %u32 32
1642 )";
1643 
1644   const std::string dbg_inst_header = R"(
1645 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1646 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1647 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1648 %main_type_info1 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1649 %main_type_info2 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info
1650 %main_type_info3 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %float_info
1651 %main_type_info4 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void %float_info %float_info
1652 )";
1653 
1654   const std::string extension = R"(
1655 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1656 )";
1657 
1658   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1659       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1660   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1661 }
1662 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailReturn)1663 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailReturn) {
1664   const std::string src = R"(
1665 %src = OpString "simple.hlsl"
1666 %code = OpString "main() {}"
1667 %main_name = OpString "main"
1668 %main_linkage_name = OpString "v_main"
1669 %float_name = OpString "float"
1670 )";
1671 
1672   const std::string size_const = R"(
1673 %int_32 = OpConstant %u32 32
1674 )";
1675 
1676   const std::string dbg_inst_header = R"(
1677 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1678 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1679 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1680 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %dbg_src %float_info
1681 )";
1682 
1683   const std::string extension = R"(
1684 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1685 )";
1686 
1687   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1688       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1689   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1690   EXPECT_THAT(
1691       getDiagnosticString(),
1692       HasSubstr("expected operand Return Type is not a valid debug type"));
1693 }
1694 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailParam)1695 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailParam) {
1696   const std::string src = R"(
1697 %src = OpString "simple.hlsl"
1698 %code = OpString "main() {}"
1699 %main_name = OpString "main"
1700 %main_linkage_name = OpString "v_main"
1701 %float_name = OpString "float"
1702 )";
1703 
1704   const std::string size_const = R"(
1705 %int_32 = OpConstant %u32 32
1706 )";
1707 
1708   const std::string dbg_inst_header = R"(
1709 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1710 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1711 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1712 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %void
1713 )";
1714 
1715   const std::string extension = R"(
1716 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1717 )";
1718 
1719   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1720       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1721   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1722   EXPECT_THAT(
1723       getDiagnosticString(),
1724       HasSubstr("expected operand Parameter Types is not a valid debug type"));
1725 }
1726 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeEnum)1727 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeEnum) {
1728   const std::string src = R"(
1729 %src = OpString "simple.hlsl"
1730 %code = OpString "main() {}"
1731 %float_name = OpString "float"
1732 %foo_name = OpString "foo"
1733 )";
1734 
1735   const std::string size_const = R"(
1736 %int_32 = OpConstant %u32 32
1737 )";
1738 
1739   const std::string dbg_inst_header = R"(
1740 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1741 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1742 %none = OpExtInst %void %DbgExt DebugInfoNone
1743 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1744 %foo_info1 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1745 %foo_info2 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1746 %foo_info3 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic
1747 )";
1748 
1749   const std::string extension = R"(
1750 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1751 )";
1752 
1753   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1754       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1755   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1756 }
1757 
TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum,Fail)1758 TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum, Fail) {
1759   const std::string src = R"(
1760 %src = OpString "simple.hlsl"
1761 %code = OpString "main() {}"
1762 %float_name = OpString "float"
1763 %foo_name = OpString "foo"
1764 )";
1765 
1766   const std::string size_const = R"(
1767 %int_32 = OpConstant %u32 32
1768 )";
1769 
1770   const auto& param = GetParam();
1771 
1772   std::ostringstream ss;
1773   ss << R"(
1774 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1775 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1776 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1777 %foo_info = OpExtInst %void %DbgExt DebugTypeEnum )";
1778   ss << param.first;
1779 
1780   const std::string extension = R"(
1781 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1782 )";
1783 
1784   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1785                                                      "", extension, "Vertex"));
1786   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1787   EXPECT_THAT(getDiagnosticString(),
1788               HasSubstr("expected operand " + param.second));
1789 }
1790 
1791 INSTANTIATE_TEST_SUITE_P(
1792     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeEnum,
1793     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1794         std::make_pair(
1795             R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1796             "Name"),
1797         std::make_pair(
1798             R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1799             "Underlying Types"),
1800         std::make_pair(
1801             R"(%foo_name %float_info %comp_unit 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1802             "Source"),
1803         std::make_pair(
1804             R"(%foo_name %float_info %dbg_src 1 1 %dbg_src %int_32 FlagIsPublic %u32_0 %foo_name)",
1805             "Parent"),
1806         std::make_pair(
1807             R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %void FlagIsPublic %u32_0 %foo_name)",
1808             "Size"),
1809         std::make_pair(
1810             R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %u32_0 FlagIsPublic %u32_0 %foo_name)",
1811             "Size"),
1812         std::make_pair(
1813             R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %foo_name %foo_name)",
1814             "Value"),
1815         std::make_pair(
1816             R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %u32_1)",
1817             "Name"),
1818     }));
1819 
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeFunctionAndInheritance)1820 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeFunctionAndInheritance) {
1821   const std::string src = R"(
1822 %src = OpString "simple.hlsl"
1823 %code = OpString "struct VS_OUTPUT {
1824   float4 pos : SV_POSITION;
1825 };
1826 struct foo : VS_OUTPUT {
1827 };
1828 main() {}
1829 "
1830 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1831 %float_name = OpString "float"
1832 %foo_name = OpString "foo"
1833 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1834 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1835 %main_name = OpString "main"
1836 %main_linkage_name = OpString "v4f_main_f"
1837 )";
1838 
1839   const std::string size_const = R"(
1840 %int_32 = OpConstant %u32 32
1841 %int_128 = OpConstant %u32 128
1842 )";
1843 
1844   const std::string dbg_inst_header = R"(
1845 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1846 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1847 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child
1848 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1849 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1850 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
1851 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
1852 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
1853 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
1854 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
1855 )";
1856 
1857   const std::string extension = R"(
1858 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1859 )";
1860 
1861   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1862       src, size_const, dbg_inst_header, "", extension, "Vertex"));
1863   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1864 }
1865 
TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite,Fail)1866 TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite, Fail) {
1867   const std::string src = R"(
1868 %src = OpString "simple.hlsl"
1869 %code = OpString "struct VS_OUTPUT {
1870   float4 pos : SV_POSITION;
1871 };
1872 struct foo : VS_OUTPUT {
1873 };
1874 main() {}
1875 "
1876 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1877 %float_name = OpString "float"
1878 %foo_name = OpString "foo"
1879 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1880 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1881 %main_name = OpString "main"
1882 %main_linkage_name = OpString "v4f_main_f"
1883 )";
1884 
1885   const std::string size_const = R"(
1886 %int_32 = OpConstant %u32 32
1887 %int_128 = OpConstant %u32 128
1888 )";
1889 
1890   const auto& param = GetParam();
1891 
1892   std::ostringstream ss;
1893   ss << R"(
1894 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1895 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1896 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite )";
1897   ss << param.first;
1898   ss << R"(
1899 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1900 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1901 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
1902 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
1903 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
1904 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
1905 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
1906 )";
1907 
1908   const std::string extension = R"(
1909 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1910 )";
1911 
1912   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1913                                                      "", extension, "Vertex"));
1914   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1915   EXPECT_THAT(getDiagnosticString(),
1916               HasSubstr("expected operand " + param.second + " must be "));
1917 }
1918 
1919 INSTANTIATE_TEST_SUITE_P(
1920     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeComposite,
1921     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1922         std::make_pair(
1923             R"(%dbg_src Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
1924             "Name"),
1925         std::make_pair(
1926             R"(%VS_OUTPUT_name Structure %comp_unit 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
1927             "Source"),
1928         std::make_pair(
1929             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %dbg_src %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
1930             "Parent"),
1931         std::make_pair(
1932             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %int_128 %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
1933             "Linkage Name"),
1934         std::make_pair(
1935             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %dbg_src FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
1936             "Size"),
1937         std::make_pair(
1938             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %dbg_src %main_info %child)",
1939             "Members"),
1940         std::make_pair(
1941             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %dbg_src %child)",
1942             "Members"),
1943         std::make_pair(
1944             R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %dbg_src)",
1945             "Members"),
1946     }));
1947 
TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember,Fail)1948 TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember, Fail) {
1949   const std::string src = R"(
1950 %src = OpString "simple.hlsl"
1951 %code = OpString "struct VS_OUTPUT {
1952   float pos : SV_POSITION;
1953 };
1954 main() {}
1955 "
1956 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1957 %float_name = OpString "float"
1958 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1959 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1960 )";
1961 
1962   const std::string size_const = R"(
1963 %int_32 = OpConstant %u32 32
1964 )";
1965 
1966   const auto& param = GetParam();
1967 
1968   std::ostringstream ss;
1969   ss << R"(
1970 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1971 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1972 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_32 FlagIsPublic %VS_OUTPUT_pos_info
1973 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1974 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember )";
1975   ss << param.first;
1976 
1977   const std::string extension = R"(
1978 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1979 )";
1980 
1981   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1982                                                      "", extension, "Vertex"));
1983   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1984   if (!param.second.empty()) {
1985     EXPECT_THAT(getDiagnosticString(),
1986                 HasSubstr("expected operand " + param.second +
1987                           " must be a result id of "));
1988   }
1989 }
1990 
1991 INSTANTIATE_TEST_SUITE_P(
1992     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeMember,
1993     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1994         std::make_pair(
1995             R"(%dbg_src %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
1996             "Name"),
1997         std::make_pair(
1998             R"(%VS_OUTPUT_pos_name %dbg_src %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
1999             ""),
2000         std::make_pair(
2001             R"(%VS_OUTPUT_pos_name %float_info %float_info 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2002             "Source"),
2003         std::make_pair(
2004             R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %float_info %u32_0 %int_32 FlagIsPublic)",
2005             "Parent"),
2006         std::make_pair(
2007             R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %void %int_32 FlagIsPublic)",
2008             "Offset"),
2009         std::make_pair(
2010             R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2011             "Size"),
2012     }));
2013 
TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance,Fail)2014 TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance, Fail) {
2015   const std::string src = R"(
2016 %src = OpString "simple.hlsl"
2017 %code = OpString "struct VS_OUTPUT {};
2018 struct foo : VS_OUTPUT {};
2019 "
2020 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
2021 %foo_name = OpString "foo"
2022 )";
2023 
2024   const auto& param = GetParam();
2025 
2026   std::ostringstream ss;
2027   ss << R"(
2028 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2029 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2030 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_name %u32_0 FlagIsPublic %child
2031 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2032 %bar_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Union %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2033 %child = OpExtInst %void %DbgExt DebugTypeInheritance )"
2034      << param.first;
2035 
2036   const std::string extension = R"(
2037 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2038 )";
2039 
2040   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2041                                                      extension, "Vertex"));
2042   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2043   EXPECT_THAT(getDiagnosticString(),
2044               HasSubstr("expected operand " + param.second));
2045 }
2046 
2047 INSTANTIATE_TEST_SUITE_P(
2048     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeInheritance,
2049     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2050         std::make_pair(R"(%dbg_src %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2051                        "Child must be a result id of"),
2052         std::make_pair(R"(%foo_info %dbg_src %u32_0 %u32_0 FlagIsPublic)",
2053                        "Parent must be a result id of"),
2054         std::make_pair(
2055             R"(%bar_info %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2056             "Child must be class or struct debug type"),
2057         std::make_pair(R"(%foo_info %bar_info %u32_0 %u32_0 FlagIsPublic)",
2058                        "Parent must be class or struct debug type"),
2059         std::make_pair(R"(%foo_info %VS_OUTPUT_info %void %u32_0 FlagIsPublic)",
2060                        "Offset"),
2061         std::make_pair(R"(%foo_info %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2062                        "Size"),
2063     }));
TEST_P(ValidateGlslStd450SqrtLike,Success)2064 TEST_P(ValidateGlslStd450SqrtLike, Success) {
2065   const std::string ext_inst_name = GetParam();
2066   std::ostringstream ss;
2067   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
2068   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
2069      << " %f32vec2_01\n";
2070   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
2071   CompileSuccessfully(GenerateShaderCode(ss.str()));
2072   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2073 }
2074 
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionDeclaration)2075 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionDeclaration) {
2076   const std::string src = R"(
2077 %src = OpString "simple.hlsl"
2078 %code = OpString "struct VS_OUTPUT {
2079   float4 pos : SV_POSITION;
2080 };
2081 main() {}
2082 "
2083 %main_name = OpString "main"
2084 %main_linkage_name = OpString "v4f_main_f"
2085 )";
2086 
2087   const std::string dbg_inst_header = R"(
2088 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2089 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2090 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2091 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2092 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)";
2093 
2094   const std::string extension = R"(
2095 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2096 )";
2097 
2098   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2099                                                      "", extension, "Vertex"));
2100   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2101 }
2102 
TEST_P(ValidateOpenCL100DebugInfoDebugFunction,Fail)2103 TEST_P(ValidateOpenCL100DebugInfoDebugFunction, Fail) {
2104   const std::string src = R"(
2105 %src = OpString "simple.hlsl"
2106 %code = OpString "struct VS_OUTPUT {
2107   float4 pos : SV_POSITION;
2108 };
2109 main() {}
2110 "
2111 %main_name = OpString "main"
2112 %main_linkage_name = OpString "v4f_main_f"
2113 )";
2114 
2115   const auto& param = GetParam();
2116 
2117   std::ostringstream ss;
2118   ss << R"(
2119 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2120 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2121 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2122 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2123 %main_info = OpExtInst %void %DbgExt DebugFunction )"
2124      << param.first;
2125 
2126   const std::string extension = R"(
2127 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2128 )";
2129 
2130   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2131                                                      extension, "Vertex"));
2132   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2133   EXPECT_THAT(getDiagnosticString(),
2134               HasSubstr("expected operand " + param.second));
2135 }
2136 
2137 INSTANTIATE_TEST_SUITE_P(
2138     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugFunction,
2139     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2140         std::make_pair(
2141             R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2142             "Name"),
2143         std::make_pair(
2144             R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2145             "Type"),
2146         std::make_pair(
2147             R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2148             "Source"),
2149         std::make_pair(
2150             R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic 13 %main)",
2151             "Parent"),
2152         std::make_pair(
2153             R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic 13 %main)",
2154             "Linkage Name"),
2155         std::make_pair(
2156             R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %void)",
2157             "Function"),
2158         std::make_pair(
2159             R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main %dbg_src)",
2160             "Declaration"),
2161     }));
2162 
TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration,Fail)2163 TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration, Fail) {
2164   const std::string src = R"(
2165 %src = OpString "simple.hlsl"
2166 %code = OpString "struct VS_OUTPUT {
2167   float4 pos : SV_POSITION;
2168 };
2169 main() {}
2170 "
2171 %main_name = OpString "main"
2172 %main_linkage_name = OpString "v4f_main_f"
2173 )";
2174 
2175   const auto& param = GetParam();
2176 
2177   std::ostringstream ss;
2178   ss << R"(
2179 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2180 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2181 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2182 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration )"
2183      << param.first;
2184 
2185   const std::string extension = R"(
2186 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2187 )";
2188 
2189   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2190                                                      extension, "Vertex"));
2191   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2192   EXPECT_THAT(getDiagnosticString(),
2193               HasSubstr("expected operand " + param.second));
2194 }
2195 
2196 INSTANTIATE_TEST_SUITE_P(
2197     AllOpenCL100DebugInfoFail,
2198     ValidateOpenCL100DebugInfoDebugFunctionDeclaration,
2199     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2200         std::make_pair(
2201             R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2202             "Name"),
2203         std::make_pair(
2204             R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2205             "Type"),
2206         std::make_pair(
2207             R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2208             "Source"),
2209         std::make_pair(
2210             R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic)",
2211             "Parent"),
2212         std::make_pair(
2213             R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic)",
2214             "Linkage Name"),
2215     }));
2216 
TEST_F(ValidateOpenCL100DebugInfo,DebugLexicalBlock)2217 TEST_F(ValidateOpenCL100DebugInfo, DebugLexicalBlock) {
2218   const std::string src = R"(
2219 %src = OpString "simple.hlsl"
2220 %code = OpString "main() {}"
2221 %main_name = OpString "main"
2222 )";
2223 
2224   const std::string dbg_inst_header = R"(
2225 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2226 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2227 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock %dbg_src 1 1 %comp_unit %main_name)";
2228 
2229   const std::string extension = R"(
2230 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2231 )";
2232 
2233   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2234                                                      "", extension, "Vertex"));
2235   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2236 }
2237 
TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock,Fail)2238 TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock, Fail) {
2239   const std::string src = R"(
2240 %src = OpString "simple.hlsl"
2241 %code = OpString "main() {}"
2242 %main_name = OpString "main"
2243 )";
2244 
2245   const auto& param = GetParam();
2246 
2247   std::ostringstream ss;
2248   ss << R"(
2249 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2250 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2251 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock )"
2252      << param.first;
2253 
2254   const std::string extension = R"(
2255 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2256 )";
2257 
2258   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2259                                                      extension, "Vertex"));
2260   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2261   EXPECT_THAT(getDiagnosticString(),
2262               HasSubstr("expected operand " + param.second));
2263 }
2264 
2265 INSTANTIATE_TEST_SUITE_P(
2266     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLexicalBlock,
2267     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2268         std::make_pair(R"(%comp_unit 1 1 %comp_unit %main_name)", "Source"),
2269         std::make_pair(R"(%dbg_src 1 1 %dbg_src %main_name)", "Parent"),
2270         std::make_pair(R"(%dbg_src 1 1 %comp_unit %void)", "Name"),
2271     }));
2272 
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailScope)2273 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailScope) {
2274   const std::string src = R"(
2275 %src = OpString "simple.hlsl"
2276 %code = OpString "void main() {}"
2277 )";
2278 
2279   const std::string dbg_inst_header = R"(
2280 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2281 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2282 )";
2283 
2284   const std::string body = R"(
2285 %main_scope = OpExtInst %void %DbgExt DebugScope %dbg_src
2286 )";
2287 
2288   const std::string extension = R"(
2289 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2290 )";
2291 
2292   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2293       src, "", dbg_inst_header, body, extension, "Vertex"));
2294   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2295   EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope"));
2296 }
2297 
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailInlinedAt)2298 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailInlinedAt) {
2299   const std::string src = R"(
2300 %src = OpString "simple.hlsl"
2301 %code = OpString "void main() {}"
2302 )";
2303 
2304   const std::string dbg_inst_header = R"(
2305 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2306 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2307 )";
2308 
2309   const std::string body = R"(
2310 %main_scope = OpExtInst %void %DbgExt DebugScope %comp_unit %dbg_src
2311 )";
2312 
2313   const std::string extension = R"(
2314 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2315 )";
2316 
2317   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2318       src, "", dbg_inst_header, body, extension, "Vertex"));
2319   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2320   EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined At"));
2321 }
2322 
TEST_F(ValidateOpenCL100DebugInfo,DebugLocalVariable)2323 TEST_F(ValidateOpenCL100DebugInfo, DebugLocalVariable) {
2324   const std::string src = R"(
2325 %src = OpString "simple.hlsl"
2326 %code = OpString "void main() { float foo; }"
2327 %float_name = OpString "float"
2328 %foo_name = OpString "foo"
2329 )";
2330 
2331   const std::string size_const = R"(
2332 %int_32 = OpConstant %u32 32
2333 )";
2334 
2335   const std::string dbg_inst_header = R"(
2336 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2337 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2338 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2339 %foo = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2340 )";
2341 
2342   const std::string extension = R"(
2343 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2344 )";
2345 
2346   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2347       src, size_const, dbg_inst_header, "", extension, "Vertex"));
2348   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2349 }
2350 
TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable,Fail)2351 TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable, Fail) {
2352   const std::string src = R"(
2353 %src = OpString "simple.hlsl"
2354 %code = OpString "void main() { float foo; }"
2355 %float_name = OpString "float"
2356 %foo_name = OpString "foo"
2357 )";
2358 
2359   const std::string size_const = R"(
2360 %int_32 = OpConstant %u32 32
2361 )";
2362 
2363   const auto& param = GetParam();
2364 
2365   std::ostringstream ss;
2366   ss << R"(
2367 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2368 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2369 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2370 %foo = OpExtInst %void %DbgExt DebugLocalVariable )"
2371      << param.first;
2372 
2373   const std::string extension = R"(
2374 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2375 )";
2376 
2377   CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2378                                                      "", extension, "Vertex"));
2379   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2380   EXPECT_THAT(getDiagnosticString(),
2381               HasSubstr("expected operand " + param.second));
2382 }
2383 
2384 INSTANTIATE_TEST_SUITE_P(
2385     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLocalVariable,
2386     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2387         std::make_pair(
2388             R"(%void %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2389             "Name"),
2390         std::make_pair(
2391             R"(%foo_name %dbg_src %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2392             "Type"),
2393         std::make_pair(
2394             R"(%foo_name %float_info %comp_unit 1 10 %comp_unit FlagIsLocal 0)",
2395             "Source"),
2396         std::make_pair(
2397             R"(%foo_name %float_info %dbg_src 1 10 %dbg_src FlagIsLocal 0)",
2398             "Parent"),
2399     }));
2400 
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclare)2401 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclare) {
2402   const std::string src = R"(
2403 %src = OpString "simple.hlsl"
2404 %code = OpString "void main() { float foo; }"
2405 %float_name = OpString "float"
2406 %foo_name = OpString "foo"
2407 )";
2408 
2409   const std::string size_const = R"(
2410 %int_32 = OpConstant %u32 32
2411 )";
2412 
2413   const std::string dbg_inst_header = R"(
2414 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2415 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2416 %null_expr = OpExtInst %void %DbgExt DebugExpression
2417 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2418 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2419 )";
2420 
2421   const std::string body = R"(
2422 %foo = OpVariable %f32_ptr_function Function
2423 %decl = OpExtInst %void %DbgExt DebugDeclare %foo_info %foo %null_expr
2424 )";
2425 
2426   const std::string extension = R"(
2427 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2428 )";
2429 
2430   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2431       src, size_const, dbg_inst_header, body, extension, "Vertex"));
2432   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2433 }
2434 
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclareParam)2435 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclareParam) {
2436   CompileSuccessfully(R"(
2437                OpCapability Shader
2438           %1 = OpExtInstImport "OpenCL.DebugInfo.100"
2439                OpMemoryModel Logical GLSL450
2440                OpEntryPoint Vertex %main "main" %in_var_COLOR
2441           %4 = OpString "test.hlsl"
2442                OpSource HLSL 620 %4 "#line 1 \"test.hlsl\"
2443 void main(float foo:COLOR) {}
2444 "
2445          %11 = OpString "#line 1 \"test.hlsl\"
2446 void main(float foo:COLOR) {}
2447 "
2448          %14 = OpString "float"
2449          %17 = OpString "src.main"
2450          %20 = OpString "foo"
2451                OpName %in_var_COLOR "in.var.COLOR"
2452                OpName %main "main"
2453                OpName %param_var_foo "param.var.foo"
2454                OpName %src_main "src.main"
2455                OpName %foo "foo"
2456                OpName %bb_entry "bb.entry"
2457                OpDecorate %in_var_COLOR Location 0
2458        %uint = OpTypeInt 32 0
2459     %uint_32 = OpConstant %uint 32
2460       %float = OpTypeFloat 32
2461 %_ptr_Input_float = OpTypePointer Input %float
2462        %void = OpTypeVoid
2463          %23 = OpTypeFunction %void
2464 %_ptr_Function_float = OpTypePointer Function %float
2465          %29 = OpTypeFunction %void %_ptr_Function_float
2466                OpLine %4 1 21
2467 %in_var_COLOR = OpVariable %_ptr_Input_float Input
2468          %10 = OpExtInst %void %1 DebugExpression
2469          %12 = OpExtInst %void %1 DebugSource %4 %11
2470          %13 = OpExtInst %void %1 DebugCompilationUnit 1 4 %12 HLSL
2471          %15 = OpExtInst %void %1 DebugTypeBasic %14 %uint_32 Float
2472          %16 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %void %15
2473          %18 = OpExtInst %void %1 DebugFunction %17 %16 %12 1 1 %13 %17 FlagIsProtected|FlagIsPrivate 1 %src_main
2474          %21 = OpExtInst %void %1 DebugLocalVariable %20 %15 %12 1 17 %18 FlagIsLocal 0
2475          %22 = OpExtInst %void %1 DebugLexicalBlock %12 1 28 %18
2476                OpLine %4 1 1
2477        %main = OpFunction %void None %23
2478          %24 = OpLabel
2479                OpLine %4 1 17
2480 %param_var_foo = OpVariable %_ptr_Function_float Function
2481          %27 = OpLoad %float %in_var_COLOR
2482                OpLine %4 1 1
2483          %28 = OpFunctionCall %void %src_main %param_var_foo
2484                OpReturn
2485                OpFunctionEnd
2486    %src_main = OpFunction %void None %29
2487                OpLine %4 1 17
2488         %foo = OpFunctionParameter %_ptr_Function_float
2489          %31 = OpExtInst %void %1 DebugDeclare %21 %foo %10
2490    %bb_entry = OpLabel
2491                OpLine %4 1 29
2492                OpReturn
2493                OpFunctionEnd
2494 )");
2495   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2496 }
2497 
2498 TEST_P(ValidateOpenCL100DebugInfoDebugDeclare, Fail) {
2499   const std::string src = R"(
2500 %src = OpString "simple.hlsl"
2501 %code = OpString "void main() { float foo; }"
2502 %float_name = OpString "float"
2503 %foo_name = OpString "foo"
2504 )";
2505 
2506   const std::string size_const = R"(
2507 %int_32 = OpConstant %u32 32
2508 )";
2509 
2510   const std::string dbg_inst_header = R"(
2511 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2512 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2513 %null_expr = OpExtInst %void %DbgExt DebugExpression
2514 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2515 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2516 )";
2517 
2518   const auto& param = GetParam();
2519 
2520   std::ostringstream ss;
2521   ss << R"(
2522 %foo = OpVariable %f32_ptr_function Function
2523 %decl = OpExtInst %void %DbgExt DebugDeclare )"
2524      << param.first;
2525 
2526   const std::string extension = R"(
2527 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2528 )";
2529 
2530   CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2531       src, size_const, dbg_inst_header, ss.str(), extension, "Vertex"));
2532   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2533   EXPECT_THAT(getDiagnosticString(),
2534               HasSubstr("expected operand " + param.second));
2535 }
2536 
2537 INSTANTIATE_TEST_SUITE_P(
2538     AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugDeclare,
2539     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2540         std::make_pair(R"(%dbg_src %foo %null_expr)", "Local Variable"),
2541         std::make_pair(R"(%foo_info %void %null_expr)", "Variable"),
2542         std::make_pair(R"(%foo_info %foo %dbg_src)", "Expression"),
2543     }));
2544 
2545 TEST_F(ValidateOpenCL100DebugInfo, DebugExpression) {
2546   const std::string dbg_inst_header = R"(
2547 %op0 = OpExtInst %void %DbgExt DebugOperation Deref
2548 %op1 = OpExtInst %void %DbgExt DebugOperation Plus
2549 %null_expr = OpExtInst %void %DbgExt DebugExpression %op0 %op1
2550 )";
2551 
2552   const std::string extension = R"(
2553 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2554 )";
2555 
2556   CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2557                                                      "", extension, "Vertex"));
2558   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2559 }
2560 
2561 TEST_F(ValidateOpenCL100DebugInfo, DebugExpressionFail) {
2562   const std::string dbg_inst_header = R"(
2563 %op = OpExtInst %void %DbgExt DebugOperation Deref
2564 %null_expr = OpExtInst %void %DbgExt DebugExpression %op %void
2565 )";
2566 
2567   const std::string extension = R"(
2568 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2569 )";
2570 
2571   CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2572                                                      "", extension, "Vertex"));
2573   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2574   EXPECT_THAT(
2575       getDiagnosticString(),
2576       HasSubstr(
2577           "expected operand Operation must be a result id of DebugOperation"));
2578 }
2579 
2580 TEST_P(ValidateGlslStd450SqrtLike, IntResultType) {
2581   const std::string ext_inst_name = GetParam();
2582   const std::string body =
2583       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
2584 
2585   CompileSuccessfully(GenerateShaderCode(body));
2586   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2587   EXPECT_THAT(getDiagnosticString(),
2588               HasSubstr("GLSL.std.450 " + ext_inst_name +
2589                         ": expected Result Type to be a float scalar "
2590                         "or vector type"));
2591 }
2592 
2593 TEST_P(ValidateGlslStd450SqrtLike, IntOperand) {
2594   const std::string ext_inst_name = GetParam();
2595   const std::string body =
2596       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
2597 
2598   CompileSuccessfully(GenerateShaderCode(body));
2599   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2600   EXPECT_THAT(getDiagnosticString(),
2601               HasSubstr("GLSL.std.450 " + ext_inst_name +
2602                         ": expected types of all operands to be equal to "
2603                         "Result Type"));
2604 }
2605 
2606 INSTANTIATE_TEST_SUITE_P(AllSqrtLike, ValidateGlslStd450SqrtLike,
2607                          ::testing::ValuesIn(std::vector<std::string>{
2608                              "Round",
2609                              "RoundEven",
2610                              "FAbs",
2611                              "Trunc",
2612                              "FSign",
2613                              "Floor",
2614                              "Ceil",
2615                              "Fract",
2616                              "Sqrt",
2617                              "InverseSqrt",
2618                              "Normalize",
2619                          }));
2620 
2621 TEST_P(ValidateGlslStd450FMinLike, Success) {
2622   const std::string ext_inst_name = GetParam();
2623   std::ostringstream ss;
2624   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
2625      << " %f32_0 %f32_1\n";
2626   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
2627      << " %f32vec2_01 %f32vec2_12\n";
2628   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
2629      << " %f64_0 %f64_0\n";
2630   CompileSuccessfully(GenerateShaderCode(ss.str()));
2631   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2632 }
2633 
2634 TEST_P(ValidateGlslStd450FMinLike, IntResultType) {
2635   const std::string ext_inst_name = GetParam();
2636   const std::string body =
2637       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
2638 
2639   CompileSuccessfully(GenerateShaderCode(body));
2640   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2641   EXPECT_THAT(getDiagnosticString(),
2642               HasSubstr("GLSL.std.450 " + ext_inst_name +
2643                         ": expected Result Type to be a float scalar "
2644                         "or vector type"));
2645 }
2646 
2647 TEST_P(ValidateGlslStd450FMinLike, IntOperand1) {
2648   const std::string ext_inst_name = GetParam();
2649   const std::string body =
2650       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
2651 
2652   CompileSuccessfully(GenerateShaderCode(body));
2653   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2654   EXPECT_THAT(getDiagnosticString(),
2655               HasSubstr("GLSL.std.450 " + ext_inst_name +
2656                         ": expected types of all operands to be equal to "
2657                         "Result Type"));
2658 }
2659 
2660 TEST_P(ValidateGlslStd450FMinLike, IntOperand2) {
2661   const std::string ext_inst_name = GetParam();
2662   const std::string body =
2663       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
2664 
2665   CompileSuccessfully(GenerateShaderCode(body));
2666   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2667   EXPECT_THAT(getDiagnosticString(),
2668               HasSubstr("GLSL.std.450 " + ext_inst_name +
2669                         ": expected types of all operands to be equal to "
2670                         "Result Type"));
2671 }
2672 
2673 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateGlslStd450FMinLike,
2674                          ::testing::ValuesIn(std::vector<std::string>{
2675                              "FMin",
2676                              "FMax",
2677                              "Step",
2678                              "Reflect",
2679                              "NMin",
2680                              "NMax",
2681                          }));
2682 
2683 TEST_P(ValidateGlslStd450FClampLike, Success) {
2684   const std::string ext_inst_name = GetParam();
2685   std::ostringstream ss;
2686   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
2687      << " %f32_0 %f32_1 %f32_2\n";
2688   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
2689      << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
2690   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
2691      << " %f64_0 %f64_0 %f64_1\n";
2692   CompileSuccessfully(GenerateShaderCode(ss.str()));
2693   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2694 }
2695 
2696 TEST_P(ValidateGlslStd450FClampLike, IntResultType) {
2697   const std::string ext_inst_name = GetParam();
2698   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
2699                            " %f32_0 %f32_1 %f32_2\n";
2700 
2701   CompileSuccessfully(GenerateShaderCode(body));
2702   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2703   EXPECT_THAT(getDiagnosticString(),
2704               HasSubstr("GLSL.std.450 " + ext_inst_name +
2705                         ": expected Result Type to be a float scalar "
2706                         "or vector type"));
2707 }
2708 
2709 TEST_P(ValidateGlslStd450FClampLike, IntOperand1) {
2710   const std::string ext_inst_name = GetParam();
2711   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
2712                            " %u32_0 %f32_0 %f32_1\n";
2713 
2714   CompileSuccessfully(GenerateShaderCode(body));
2715   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2716   EXPECT_THAT(getDiagnosticString(),
2717               HasSubstr("GLSL.std.450 " + ext_inst_name +
2718                         ": expected types of all operands to be equal to "
2719                         "Result Type"));
2720 }
2721 
2722 TEST_P(ValidateGlslStd450FClampLike, IntOperand2) {
2723   const std::string ext_inst_name = GetParam();
2724   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
2725                            " %f32_0 %u32_0 %f32_1\n";
2726 
2727   CompileSuccessfully(GenerateShaderCode(body));
2728   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2729   EXPECT_THAT(getDiagnosticString(),
2730               HasSubstr("GLSL.std.450 " + ext_inst_name +
2731                         ": expected types of all operands to be equal to "
2732                         "Result Type"));
2733 }
2734 
2735 TEST_P(ValidateGlslStd450FClampLike, IntOperand3) {
2736   const std::string ext_inst_name = GetParam();
2737   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
2738                            " %f32_1 %f32_0 %u32_2\n";
2739 
2740   CompileSuccessfully(GenerateShaderCode(body));
2741   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2742   EXPECT_THAT(getDiagnosticString(),
2743               HasSubstr("GLSL.std.450 " + ext_inst_name +
2744                         ": expected types of all operands to be equal to "
2745                         "Result Type"));
2746 }
2747 
2748 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateGlslStd450FClampLike,
2749                          ::testing::ValuesIn(std::vector<std::string>{
2750                              "FClamp",
2751                              "FMix",
2752                              "SmoothStep",
2753                              "Fma",
2754                              "FaceForward",
2755                              "NClamp",
2756                          }));
2757 
2758 TEST_P(ValidateGlslStd450SAbsLike, Success) {
2759   const std::string ext_inst_name = GetParam();
2760   std::ostringstream ss;
2761   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n";
2762   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n";
2763   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
2764   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n";
2765   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
2766      << " %s32vec2_01\n";
2767   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
2768      << " %u32vec2_01\n";
2769   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
2770      << " %s32vec2_01\n";
2771   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
2772      << " %u32vec2_01\n";
2773   CompileSuccessfully(GenerateShaderCode(ss.str()));
2774   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2775 }
2776 
2777 TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) {
2778   const std::string ext_inst_name = GetParam();
2779   const std::string body =
2780       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
2781 
2782   CompileSuccessfully(GenerateShaderCode(body));
2783   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2784   EXPECT_THAT(getDiagnosticString(),
2785               HasSubstr("GLSL.std.450 " + ext_inst_name +
2786                         ": expected Result Type to be an int scalar "
2787                         "or vector type"));
2788 }
2789 
2790 TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) {
2791   const std::string ext_inst_name = GetParam();
2792   const std::string body =
2793       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n";
2794 
2795   CompileSuccessfully(GenerateShaderCode(body));
2796   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2797   EXPECT_THAT(getDiagnosticString(),
2798               HasSubstr("GLSL.std.450 " + ext_inst_name +
2799                         ": expected all operands to be int scalars or "
2800                         "vectors"));
2801 }
2802 
2803 TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) {
2804   const std::string ext_inst_name = GetParam();
2805   const std::string body =
2806       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n";
2807 
2808   CompileSuccessfully(GenerateShaderCode(body));
2809   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2810   EXPECT_THAT(getDiagnosticString(),
2811               HasSubstr("GLSL.std.450 " + ext_inst_name +
2812                         ": expected all operands to have the same dimension as "
2813                         "Result Type"));
2814 }
2815 
2816 TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) {
2817   const std::string ext_inst_name = GetParam();
2818   const std::string body =
2819       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n";
2820 
2821   CompileSuccessfully(GenerateShaderCode(body));
2822   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2823   EXPECT_THAT(getDiagnosticString(),
2824               HasSubstr("GLSL.std.450 " + ext_inst_name +
2825                         ": expected all operands to have the same bit width as "
2826                         "Result Type"));
2827 }
2828 
2829 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateGlslStd450SAbsLike,
2830                          ::testing::ValuesIn(std::vector<std::string>{
2831                              "SAbs",
2832                              "SSign",
2833                              "FindILsb",
2834                              "FindUMsb",
2835                              "FindSMsb",
2836                          }));
2837 
2838 TEST_F(ValidateExtInst, FindUMsbNot32Bit) {
2839   const std::string body = R"(
2840 %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1
2841 )";
2842 
2843   CompileSuccessfully(GenerateShaderCode(body));
2844   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2845   EXPECT_THAT(getDiagnosticString(),
2846               HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently "
2847                         "limited to 32-bit width components"));
2848 }
2849 
2850 TEST_F(ValidateExtInst, FindSMsbNot32Bit) {
2851   const std::string body = R"(
2852 %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1
2853 )";
2854 
2855   CompileSuccessfully(GenerateShaderCode(body));
2856   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2857   EXPECT_THAT(getDiagnosticString(),
2858               HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently "
2859                         "limited to 32-bit width components"));
2860 }
2861 
2862 TEST_P(ValidateGlslStd450UMinLike, Success) {
2863   const std::string ext_inst_name = GetParam();
2864   std::ostringstream ss;
2865   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
2866      << " %u32_1 %s32_2\n";
2867   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
2868      << " %s32_1 %u32_2\n";
2869   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
2870      << " %u32_1 %s32_2\n";
2871   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
2872      << " %s32_1 %u32_2\n";
2873   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
2874      << " %s32vec2_01 %u32vec2_01\n";
2875   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
2876      << " %u32vec2_01 %s32vec2_01\n";
2877   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
2878      << " %s32vec2_01 %u32vec2_01\n";
2879   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
2880      << " %u32vec2_01 %s32vec2_01\n";
2881   ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
2882      << " %u64_1 %s64_0\n";
2883   CompileSuccessfully(GenerateShaderCode(ss.str()));
2884   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2885 }
2886 
2887 TEST_P(ValidateGlslStd450UMinLike, FloatResultType) {
2888   const std::string ext_inst_name = GetParam();
2889   const std::string body =
2890       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
2891 
2892   CompileSuccessfully(GenerateShaderCode(body));
2893   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2894   EXPECT_THAT(getDiagnosticString(),
2895               HasSubstr("GLSL.std.450 " + ext_inst_name +
2896                         ": expected Result Type to be an int scalar "
2897                         "or vector type"));
2898 }
2899 
2900 TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) {
2901   const std::string ext_inst_name = GetParam();
2902   const std::string body =
2903       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
2904 
2905   CompileSuccessfully(GenerateShaderCode(body));
2906   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2907   EXPECT_THAT(getDiagnosticString(),
2908               HasSubstr("GLSL.std.450 " + ext_inst_name +
2909                         ": expected all operands to be int scalars or "
2910                         "vectors"));
2911 }
2912 
2913 TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) {
2914   const std::string ext_inst_name = GetParam();
2915   const std::string body =
2916       "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
2917 
2918   CompileSuccessfully(GenerateShaderCode(body));
2919   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2920   EXPECT_THAT(getDiagnosticString(),
2921               HasSubstr("GLSL.std.450 " + ext_inst_name +
2922                         ": expected all operands to be int scalars or "
2923                         "vectors"));
2924 }
2925 
2926 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) {
2927   const std::string ext_inst_name = GetParam();
2928   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
2929                            " %s32vec2_01 %s32_0\n";
2930 
2931   CompileSuccessfully(GenerateShaderCode(body));
2932   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2933   EXPECT_THAT(getDiagnosticString(),
2934               HasSubstr("GLSL.std.450 " + ext_inst_name +
2935                         ": expected all operands to have the same dimension as "
2936                         "Result Type"));
2937 }
2938 
2939 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) {
2940   const std::string ext_inst_name = GetParam();
2941   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
2942                            " %s32_0 %s32vec2_01\n";
2943 
2944   CompileSuccessfully(GenerateShaderCode(body));
2945   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2946   EXPECT_THAT(getDiagnosticString(),
2947               HasSubstr("GLSL.std.450 " + ext_inst_name +
2948                         ": expected all operands to have the same dimension as "
2949                         "Result Type"));
2950 }
2951 
2952 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) {
2953   const std::string ext_inst_name = GetParam();
2954   const std::string body =
2955       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n";
2956 
2957   CompileSuccessfully(GenerateShaderCode(body));
2958   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2959   EXPECT_THAT(getDiagnosticString(),
2960               HasSubstr("GLSL.std.450 " + ext_inst_name +
2961                         ": expected all operands to have the same bit width as "
2962                         "Result Type"));
2963 }
2964 
2965 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) {
2966   const std::string ext_inst_name = GetParam();
2967   const std::string body =
2968       "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n";
2969 
2970   CompileSuccessfully(GenerateShaderCode(body));
2971   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2972   EXPECT_THAT(getDiagnosticString(),
2973               HasSubstr("GLSL.std.450 " + ext_inst_name +
2974                         ": expected all operands to have the same bit width as "
2975                         "Result Type"));
2976 }
2977 
2978 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateGlslStd450UMinLike,
2979                          ::testing::ValuesIn(std::vector<std::string>{
2980                              "UMin",
2981                              "SMin",
2982                              "UMax",
2983                              "SMax",
2984                          }));
2985 
2986 TEST_P(ValidateGlslStd450UClampLike, Success) {
2987   const std::string ext_inst_name = GetParam();
2988   std::ostringstream ss;
2989   ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
2990      << " %s32_0 %u32_1 %s32_2\n";
2991   ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
2992      << " %u32_0 %s32_1 %u32_2\n";
2993   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
2994      << " %s32_0 %u32_1 %s32_2\n";
2995   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
2996      << " %u32_0 %s32_1 %u32_2\n";
2997   ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
2998      << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
2999   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3000      << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3001   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3002      << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
3003   ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3004      << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3005   ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
3006      << " %u64_1 %s64_0 %s64_1\n";
3007   CompileSuccessfully(GenerateShaderCode(ss.str()));
3008   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3009 }
3010 
3011 TEST_P(ValidateGlslStd450UClampLike, FloatResultType) {
3012   const std::string ext_inst_name = GetParam();
3013   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3014                            " %u32_0 %u32_0 %u32_1\n";
3015 
3016   CompileSuccessfully(GenerateShaderCode(body));
3017   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3018   EXPECT_THAT(getDiagnosticString(),
3019               HasSubstr("GLSL.std.450 " + ext_inst_name +
3020                         ": expected Result Type to be an int scalar "
3021                         "or vector type"));
3022 }
3023 
3024 TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) {
3025   const std::string ext_inst_name = GetParam();
3026   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3027                            " %f32_0 %u32_0 %u32_1\n";
3028 
3029   CompileSuccessfully(GenerateShaderCode(body));
3030   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3031   EXPECT_THAT(getDiagnosticString(),
3032               HasSubstr("GLSL.std.450 " + ext_inst_name +
3033                         ": expected all operands to be int scalars or "
3034                         "vectors"));
3035 }
3036 
3037 TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) {
3038   const std::string ext_inst_name = GetParam();
3039   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3040                            " %u32_0 %f32_0 %u32_1\n";
3041 
3042   CompileSuccessfully(GenerateShaderCode(body));
3043   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3044   EXPECT_THAT(getDiagnosticString(),
3045               HasSubstr("GLSL.std.450 " + ext_inst_name +
3046                         ": expected all operands to be int scalars or "
3047                         "vectors"));
3048 }
3049 
3050 TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) {
3051   const std::string ext_inst_name = GetParam();
3052   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3053                            " %u32_0 %u32_0 %f32_1\n";
3054 
3055   CompileSuccessfully(GenerateShaderCode(body));
3056   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3057   EXPECT_THAT(getDiagnosticString(),
3058               HasSubstr("GLSL.std.450 " + ext_inst_name +
3059                         ": expected all operands to be int scalars or "
3060                         "vectors"));
3061 }
3062 
3063 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) {
3064   const std::string ext_inst_name = GetParam();
3065   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3066                            " %s32vec2_01 %s32_0 %u32_1\n";
3067 
3068   CompileSuccessfully(GenerateShaderCode(body));
3069   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3070   EXPECT_THAT(getDiagnosticString(),
3071               HasSubstr("GLSL.std.450 " + ext_inst_name +
3072                         ": expected all operands to have the same dimension as "
3073                         "Result Type"));
3074 }
3075 
3076 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) {
3077   const std::string ext_inst_name = GetParam();
3078   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3079                            " %s32_0 %s32vec2_01 %u32_1\n";
3080 
3081   CompileSuccessfully(GenerateShaderCode(body));
3082   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3083   EXPECT_THAT(getDiagnosticString(),
3084               HasSubstr("GLSL.std.450 " + ext_inst_name +
3085                         ": expected all operands to have the same dimension as "
3086                         "Result Type"));
3087 }
3088 
3089 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) {
3090   const std::string ext_inst_name = GetParam();
3091   const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3092                            " %s32_0 %u32_1 %s32vec2_01\n";
3093 
3094   CompileSuccessfully(GenerateShaderCode(body));
3095   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3096   EXPECT_THAT(getDiagnosticString(),
3097               HasSubstr("GLSL.std.450 " + ext_inst_name +
3098                         ": expected all operands to have the same dimension as "
3099                         "Result Type"));
3100 }
3101 
3102 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) {
3103   const std::string ext_inst_name = GetParam();
3104   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3105                            " %s32_0 %s64_0 %s64_1\n";
3106 
3107   CompileSuccessfully(GenerateShaderCode(body));
3108   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3109   EXPECT_THAT(getDiagnosticString(),
3110               HasSubstr("GLSL.std.450 " + ext_inst_name +
3111                         ": expected all operands to have the same bit width as "
3112                         "Result Type"));
3113 }
3114 
3115 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) {
3116   const std::string ext_inst_name = GetParam();
3117   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3118                            " %s64_0 %s32_0 %s64_1\n";
3119 
3120   CompileSuccessfully(GenerateShaderCode(body));
3121   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3122   EXPECT_THAT(getDiagnosticString(),
3123               HasSubstr("GLSL.std.450 " + ext_inst_name +
3124                         ": expected all operands to have the same bit width as "
3125                         "Result Type"));
3126 }
3127 
3128 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) {
3129   const std::string ext_inst_name = GetParam();
3130   const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3131                            " %s64_0 %s64_0 %s32_1\n";
3132 
3133   CompileSuccessfully(GenerateShaderCode(body));
3134   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3135   EXPECT_THAT(getDiagnosticString(),
3136               HasSubstr("GLSL.std.450 " + ext_inst_name +
3137                         ": expected all operands to have the same bit width as "
3138                         "Result Type"));
3139 }
3140 
3141 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateGlslStd450UClampLike,
3142                          ::testing::ValuesIn(std::vector<std::string>{
3143                              "UClamp",
3144                              "SClamp",
3145                          }));
3146 
3147 TEST_P(ValidateGlslStd450SinLike, Success) {
3148   const std::string ext_inst_name = GetParam();
3149   std::ostringstream ss;
3150   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
3151   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3152      << " %f32vec2_01\n";
3153   CompileSuccessfully(GenerateShaderCode(ss.str()));
3154   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3155 }
3156 
3157 TEST_P(ValidateGlslStd450SinLike, IntResultType) {
3158   const std::string ext_inst_name = GetParam();
3159   const std::string body =
3160       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
3161 
3162   CompileSuccessfully(GenerateShaderCode(body));
3163   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3164   EXPECT_THAT(getDiagnosticString(),
3165               HasSubstr("GLSL.std.450 " + ext_inst_name +
3166                         ": expected Result Type to be a 16 or 32-bit scalar "
3167                         "or vector float type"));
3168 }
3169 
3170 TEST_P(ValidateGlslStd450SinLike, F64ResultType) {
3171   const std::string ext_inst_name = GetParam();
3172   const std::string body =
3173       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n";
3174 
3175   CompileSuccessfully(GenerateShaderCode(body));
3176   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3177   EXPECT_THAT(getDiagnosticString(),
3178               HasSubstr("GLSL.std.450 " + ext_inst_name +
3179                         ": expected Result Type to be a 16 or 32-bit scalar "
3180                         "or vector float type"));
3181 }
3182 
3183 TEST_P(ValidateGlslStd450SinLike, IntOperand) {
3184   const std::string ext_inst_name = GetParam();
3185   const std::string body =
3186       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3187 
3188   CompileSuccessfully(GenerateShaderCode(body));
3189   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3190   EXPECT_THAT(getDiagnosticString(),
3191               HasSubstr("GLSL.std.450 " + ext_inst_name +
3192                         ": expected types of all operands to be equal to "
3193                         "Result Type"));
3194 }
3195 
3196 INSTANTIATE_TEST_SUITE_P(AllSinLike, ValidateGlslStd450SinLike,
3197                          ::testing::ValuesIn(std::vector<std::string>{
3198                              "Radians",
3199                              "Degrees",
3200                              "Sin",
3201                              "Cos",
3202                              "Tan",
3203                              "Asin",
3204                              "Acos",
3205                              "Atan",
3206                              "Sinh",
3207                              "Cosh",
3208                              "Tanh",
3209                              "Asinh",
3210                              "Acosh",
3211                              "Atanh",
3212                              "Exp",
3213                              "Exp2",
3214                              "Log",
3215                              "Log2",
3216                          }));
3217 
3218 TEST_P(ValidateGlslStd450PowLike, Success) {
3219   const std::string ext_inst_name = GetParam();
3220   std::ostringstream ss;
3221   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3222      << " %f32_1 %f32_1\n";
3223   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3224      << " %f32vec2_01 %f32vec2_12\n";
3225   CompileSuccessfully(GenerateShaderCode(ss.str()));
3226   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3227 }
3228 
3229 TEST_P(ValidateGlslStd450PowLike, IntResultType) {
3230   const std::string ext_inst_name = GetParam();
3231   const std::string body =
3232       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3233 
3234   CompileSuccessfully(GenerateShaderCode(body));
3235   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3236   EXPECT_THAT(getDiagnosticString(),
3237               HasSubstr("GLSL.std.450 " + ext_inst_name +
3238                         ": expected Result Type to be a 16 or 32-bit scalar "
3239                         "or vector float type"));
3240 }
3241 
3242 TEST_P(ValidateGlslStd450PowLike, F64ResultType) {
3243   const std::string ext_inst_name = GetParam();
3244   const std::string body =
3245       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3246 
3247   CompileSuccessfully(GenerateShaderCode(body));
3248   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3249   EXPECT_THAT(getDiagnosticString(),
3250               HasSubstr("GLSL.std.450 " + ext_inst_name +
3251                         ": expected Result Type to be a 16 or 32-bit scalar "
3252                         "or vector float type"));
3253 }
3254 
3255 TEST_P(ValidateGlslStd450PowLike, IntOperand1) {
3256   const std::string ext_inst_name = GetParam();
3257   const std::string body =
3258       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
3259 
3260   CompileSuccessfully(GenerateShaderCode(body));
3261   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3262   EXPECT_THAT(getDiagnosticString(),
3263               HasSubstr("GLSL.std.450 " + ext_inst_name +
3264                         ": expected types of all operands to be equal to "
3265                         "Result Type"));
3266 }
3267 
3268 TEST_P(ValidateGlslStd450PowLike, IntOperand2) {
3269   const std::string ext_inst_name = GetParam();
3270   const std::string body =
3271       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
3272 
3273   CompileSuccessfully(GenerateShaderCode(body));
3274   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3275   EXPECT_THAT(getDiagnosticString(),
3276               HasSubstr("GLSL.std.450 " + ext_inst_name +
3277                         ": expected types of all operands to be equal to "
3278                         "Result Type"));
3279 }
3280 
3281 INSTANTIATE_TEST_SUITE_P(AllPowLike, ValidateGlslStd450PowLike,
3282                          ::testing::ValuesIn(std::vector<std::string>{
3283                              "Atan2",
3284                              "Pow",
3285                          }));
3286 
3287 TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) {
3288   const std::string body = R"(
3289 %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212
3290 )";
3291 
3292   CompileSuccessfully(GenerateShaderCode(body));
3293   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3294 }
3295 
3296 TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) {
3297   const std::string body = R"(
3298 %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212
3299 )";
3300 
3301   CompileSuccessfully(GenerateShaderCode(body));
3302   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3303   EXPECT_THAT(getDiagnosticString(),
3304               HasSubstr("GLSL.std.450 Determinant: "
3305                         "expected operand X component type to be equal to "
3306                         "Result Type"));
3307 }
3308 
3309 TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) {
3310   const std::string body = R"(
3311 %val1 = OpExtInst %f32 %extinst Determinant %f32_1
3312 )";
3313 
3314   CompileSuccessfully(GenerateShaderCode(body));
3315   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3316   EXPECT_THAT(getDiagnosticString(),
3317               HasSubstr("GLSL.std.450 Determinant: "
3318                         "expected operand X to be a square matrix"));
3319 }
3320 
3321 TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) {
3322   const std::string body = R"(
3323 %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212
3324 )";
3325 
3326   CompileSuccessfully(GenerateShaderCode(body));
3327   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3328   EXPECT_THAT(getDiagnosticString(),
3329               HasSubstr("GLSL.std.450 Determinant: "
3330                         "expected operand X to be a square matrix"));
3331 }
3332 
3333 TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) {
3334   const std::string body = R"(
3335 %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212
3336 )";
3337 
3338   CompileSuccessfully(GenerateShaderCode(body));
3339   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3340 }
3341 
3342 TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) {
3343   const std::string body = R"(
3344 %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212
3345 )";
3346 
3347   CompileSuccessfully(GenerateShaderCode(body));
3348   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3349   EXPECT_THAT(getDiagnosticString(),
3350               HasSubstr("GLSL.std.450 MatrixInverse: "
3351                         "expected operand X type to be equal to "
3352                         "Result Type"));
3353 }
3354 
3355 TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) {
3356   const std::string body = R"(
3357 %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212
3358 )";
3359 
3360   CompileSuccessfully(GenerateShaderCode(body));
3361   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3362   EXPECT_THAT(getDiagnosticString(),
3363               HasSubstr("GLSL.std.450 MatrixInverse: "
3364                         "expected Result Type to be a square matrix"));
3365 }
3366 
3367 TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) {
3368   const std::string body = R"(
3369 %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212
3370 )";
3371 
3372   CompileSuccessfully(GenerateShaderCode(body));
3373   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3374   EXPECT_THAT(getDiagnosticString(),
3375               HasSubstr("GLSL.std.450 MatrixInverse: "
3376                         "expected Result Type to be a square matrix"));
3377 }
3378 
3379 TEST_F(ValidateExtInst, GlslStd450ModfSuccess) {
3380   const std::string body = R"(
3381 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output
3382 %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output
3383 )";
3384 
3385   CompileSuccessfully(GenerateShaderCode(body));
3386   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3387 }
3388 
3389 TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) {
3390   const std::string body = R"(
3391 %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output
3392 )";
3393 
3394   CompileSuccessfully(GenerateShaderCode(body));
3395   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3396   EXPECT_THAT(getDiagnosticString(),
3397               HasSubstr("GLSL.std.450 Modf: "
3398                         "expected Result Type to be a scalar or vector "
3399                         "float type"));
3400 }
3401 
3402 TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) {
3403   const std::string body = R"(
3404 %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output
3405 )";
3406 
3407   CompileSuccessfully(GenerateShaderCode(body));
3408   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3409   EXPECT_THAT(getDiagnosticString(),
3410               HasSubstr("GLSL.std.450 Modf: "
3411                         "expected operand X type to be equal to Result Type"));
3412 }
3413 
3414 TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) {
3415   const std::string body = R"(
3416 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1
3417 )";
3418 
3419   CompileSuccessfully(GenerateShaderCode(body));
3420   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3421   EXPECT_THAT(getDiagnosticString(),
3422               HasSubstr("GLSL.std.450 Modf: "
3423                         "expected operand I to be a pointer"));
3424 }
3425 
3426 TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) {
3427   const std::string body = R"(
3428 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output
3429 )";
3430 
3431   CompileSuccessfully(GenerateShaderCode(body));
3432   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3433   EXPECT_THAT(getDiagnosticString(),
3434               HasSubstr("GLSL.std.450 Modf: "
3435                         "expected operand I data type to be equal to "
3436                         "Result Type"));
3437 }
3438 
3439 TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) {
3440   const std::string body = R"(
3441 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h
3442 %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01
3443 )";
3444 
3445   CompileSuccessfully(GenerateShaderCode(body));
3446   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3447 }
3448 
3449 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) {
3450   const std::string body = R"(
3451 %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h
3452 )";
3453 
3454   CompileSuccessfully(GenerateShaderCode(body));
3455   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3456   EXPECT_THAT(getDiagnosticString(),
3457               HasSubstr("GLSL.std.450 ModfStruct: "
3458                         "expected Result Type to be a struct with two "
3459                         "identical scalar or vector float type members"));
3460 }
3461 
3462 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) {
3463   const std::string body = R"(
3464 %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h
3465 )";
3466 
3467   CompileSuccessfully(GenerateShaderCode(body));
3468   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3469   EXPECT_THAT(getDiagnosticString(),
3470               HasSubstr("GLSL.std.450 ModfStruct: "
3471                         "expected Result Type to be a struct with two "
3472                         "identical scalar or vector float type members"));
3473 }
3474 
3475 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) {
3476   const std::string body = R"(
3477 %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h
3478 )";
3479 
3480   CompileSuccessfully(GenerateShaderCode(body));
3481   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3482   EXPECT_THAT(getDiagnosticString(),
3483               HasSubstr("GLSL.std.450 ModfStruct: "
3484                         "expected Result Type to be a struct with two "
3485                         "identical scalar or vector float type members"));
3486 }
3487 
3488 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) {
3489   const std::string body = R"(
3490 %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h
3491 )";
3492 
3493   CompileSuccessfully(GenerateShaderCode(body));
3494   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3495   EXPECT_THAT(getDiagnosticString(),
3496               HasSubstr("GLSL.std.450 ModfStruct: "
3497                         "expected Result Type to be a struct with two "
3498                         "identical scalar or vector float type members"));
3499 }
3500 
3501 TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) {
3502   const std::string body = R"(
3503 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0
3504 )";
3505 
3506   CompileSuccessfully(GenerateShaderCode(body));
3507   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3508   EXPECT_THAT(getDiagnosticString(),
3509               HasSubstr("GLSL.std.450 ModfStruct: "
3510                         "expected operand X type to be equal to members of "
3511                         "Result Type struct"));
3512 }
3513 
3514 TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) {
3515   const std::string body = R"(
3516 %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output
3517 %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output
3518 )";
3519 
3520   CompileSuccessfully(GenerateShaderCode(body));
3521   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3522 }
3523 
3524 TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) {
3525   const std::string body = R"(
3526 %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output
3527 )";
3528 
3529   CompileSuccessfully(GenerateShaderCode(body));
3530   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3531   EXPECT_THAT(getDiagnosticString(),
3532               HasSubstr("GLSL.std.450 Frexp: "
3533                         "expected Result Type to be a scalar or vector "
3534                         "float type"));
3535 }
3536 
3537 TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) {
3538   const std::string body = R"(
3539 %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output
3540 )";
3541 
3542   CompileSuccessfully(GenerateShaderCode(body));
3543   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3544   EXPECT_THAT(getDiagnosticString(),
3545               HasSubstr("GLSL.std.450 Frexp: "
3546                         "expected operand X type to be equal to Result Type"));
3547 }
3548 
3549 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) {
3550   const std::string body = R"(
3551 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1
3552 )";
3553 
3554   CompileSuccessfully(GenerateShaderCode(body));
3555   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3556   EXPECT_THAT(getDiagnosticString(),
3557               HasSubstr("GLSL.std.450 Frexp: "
3558                         "expected operand Exp to be a pointer"));
3559 }
3560 
3561 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) {
3562   const std::string body = R"(
3563 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output
3564 )";
3565 
3566   CompileSuccessfully(GenerateShaderCode(body));
3567   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3568   EXPECT_THAT(getDiagnosticString(),
3569               HasSubstr("GLSL.std.450 Frexp: "
3570                         "expected operand Exp data type to be a 32-bit int "
3571                         "scalar or vector type"));
3572 }
3573 
3574 TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) {
3575   const std::string body = R"(
3576 %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output
3577 )";
3578 
3579   CompileSuccessfully(GenerateShaderCode(body));
3580   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3581   EXPECT_THAT(getDiagnosticString(),
3582               HasSubstr("GLSL.std.450 Frexp: "
3583                         "expected operand Exp data type to have the same "
3584                         "component number as Result Type"));
3585 }
3586 
3587 TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) {
3588   const std::string body = R"(
3589 %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2
3590 %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12
3591 %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1
3592 )";
3593 
3594   CompileSuccessfully(GenerateShaderCode(body));
3595   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3596 }
3597 
3598 TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) {
3599   const std::string body = R"(
3600 %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2
3601 )";
3602 
3603   CompileSuccessfully(GenerateShaderCode(body));
3604   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3605   EXPECT_THAT(getDiagnosticString(),
3606               HasSubstr("GLSL.std.450 Ldexp: "
3607                         "expected Result Type to be a scalar or vector "
3608                         "float type"));
3609 }
3610 
3611 TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) {
3612   const std::string body = R"(
3613 %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2
3614 )";
3615 
3616   CompileSuccessfully(GenerateShaderCode(body));
3617   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3618   EXPECT_THAT(getDiagnosticString(),
3619               HasSubstr("GLSL.std.450 Ldexp: "
3620                         "expected operand X type to be equal to Result Type"));
3621 }
3622 
3623 TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) {
3624   const std::string body = R"(
3625 %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2
3626 )";
3627 
3628   CompileSuccessfully(GenerateShaderCode(body));
3629   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3630   EXPECT_THAT(getDiagnosticString(),
3631               HasSubstr("GLSL.std.450 Ldexp: "
3632                         "expected operand Exp to be a 32-bit int scalar "
3633                         "or vector type"));
3634 }
3635 
3636 TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) {
3637   const std::string body = R"(
3638 %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2
3639 )";
3640 
3641   CompileSuccessfully(GenerateShaderCode(body));
3642   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3643   EXPECT_THAT(getDiagnosticString(),
3644               HasSubstr("GLSL.std.450 Ldexp: "
3645                         "expected operand Exp to have the same component "
3646                         "number as Result Type"));
3647 }
3648 
3649 TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) {
3650   const std::string body = R"(
3651 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h
3652 %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01
3653 )";
3654 
3655   CompileSuccessfully(GenerateShaderCode(body));
3656   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3657 }
3658 
3659 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) {
3660   const std::string body = R"(
3661 %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h
3662 )";
3663 
3664   CompileSuccessfully(GenerateShaderCode(body));
3665   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3666   EXPECT_THAT(getDiagnosticString(),
3667               HasSubstr("GLSL.std.450 FrexpStruct: "
3668                         "expected Result Type to be a struct with two members, "
3669                         "first member a float scalar or vector, second member "
3670                         "a 32-bit int scalar or vector with the same number of "
3671                         "components as the first member"));
3672 }
3673 
3674 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) {
3675   const std::string body = R"(
3676 %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h
3677 )";
3678 
3679   CompileSuccessfully(GenerateShaderCode(body));
3680   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3681   EXPECT_THAT(getDiagnosticString(),
3682               HasSubstr("GLSL.std.450 FrexpStruct: "
3683                         "expected Result Type to be a struct with two members, "
3684                         "first member a float scalar or vector, second member "
3685                         "a 32-bit int scalar or vector with the same number of "
3686                         "components as the first member"));
3687 }
3688 
3689 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) {
3690   const std::string body = R"(
3691 %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h
3692 )";
3693 
3694   CompileSuccessfully(GenerateShaderCode(body));
3695   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3696   EXPECT_THAT(getDiagnosticString(),
3697               HasSubstr("GLSL.std.450 FrexpStruct: "
3698                         "expected Result Type to be a struct with two members, "
3699                         "first member a float scalar or vector, second member "
3700                         "a 32-bit int scalar or vector with the same number of "
3701                         "components as the first member"));
3702 }
3703 
3704 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) {
3705   const std::string body = R"(
3706 %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h
3707 )";
3708 
3709   CompileSuccessfully(GenerateShaderCode(body));
3710   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3711   EXPECT_THAT(getDiagnosticString(),
3712               HasSubstr("GLSL.std.450 FrexpStruct: "
3713                         "expected Result Type to be a struct with two members, "
3714                         "first member a float scalar or vector, second member "
3715                         "a 32-bit int scalar or vector with the same number of "
3716                         "components as the first member"));
3717 }
3718 
3719 TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) {
3720   const std::string body = R"(
3721 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0
3722 )";
3723 
3724   CompileSuccessfully(GenerateShaderCode(body));
3725   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3726   EXPECT_THAT(getDiagnosticString(),
3727               HasSubstr("GLSL.std.450 FrexpStruct: "
3728                         "expected operand X type to be equal to the first "
3729                         "member of Result Type struct"));
3730 }
3731 
3732 TEST_F(ValidateExtInst,
3733        GlslStd450FrexpStructResultTypeStructRightInt16Member2) {
3734   const std::string body = R"(
3735 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
3736 )";
3737 
3738   const std::string extension = R"(
3739 OpExtension  "SPV_AMD_gpu_shader_int16"
3740 )";
3741 
3742   CompileSuccessfully(GenerateShaderCode(body, extension));
3743   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3744 }
3745 
3746 TEST_F(ValidateExtInst,
3747        GlslStd450FrexpStructResultTypeStructWrongInt16Member2) {
3748   const std::string body = R"(
3749 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
3750 )";
3751 
3752   CompileSuccessfully(GenerateShaderCode(body));
3753   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3754   EXPECT_THAT(getDiagnosticString(),
3755               HasSubstr("GLSL.std.450 FrexpStruct: "
3756                         "expected Result Type to be a struct with two members, "
3757                         "first member a float scalar or vector, second member "
3758                         "a 32-bit int scalar or vector with the same number of "
3759                         "components as the first member"));
3760 }
3761 
3762 TEST_P(ValidateGlslStd450Pack, Success) {
3763   const std::string ext_inst_name = GetParam();
3764   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3765   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3766   const uint32_t total_bit_width = num_components * packed_bit_width;
3767   const std::string vec_str =
3768       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
3769 
3770   std::ostringstream body;
3771   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
3772        << ext_inst_name << vec_str;
3773   body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst "
3774        << ext_inst_name << vec_str;
3775   CompileSuccessfully(GenerateShaderCode(body.str()));
3776   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3777 }
3778 
3779 TEST_P(ValidateGlslStd450Pack, Float32ResultType) {
3780   const std::string ext_inst_name = GetParam();
3781   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3782   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3783   const uint32_t total_bit_width = num_components * packed_bit_width;
3784   const std::string vec_str =
3785       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
3786 
3787   std::ostringstream body;
3788   body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst "
3789        << ext_inst_name << vec_str;
3790 
3791   std::ostringstream expected;
3792   expected << "GLSL.std.450 " << ext_inst_name
3793            << ": expected Result Type to be " << total_bit_width
3794            << "-bit int scalar type";
3795 
3796   CompileSuccessfully(GenerateShaderCode(body.str()));
3797   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3798   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3799 }
3800 
3801 TEST_P(ValidateGlslStd450Pack, Int16ResultType) {
3802   const std::string ext_inst_name = GetParam();
3803   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3804   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3805   const uint32_t total_bit_width = num_components * packed_bit_width;
3806   const std::string vec_str =
3807       num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
3808 
3809   std::ostringstream body;
3810   body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str;
3811 
3812   std::ostringstream expected;
3813   expected << "GLSL.std.450 " << ext_inst_name
3814            << ": expected Result Type to be " << total_bit_width
3815            << "-bit int scalar type";
3816 
3817   CompileSuccessfully(GenerateShaderCode(body.str()));
3818   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3819   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3820 }
3821 
3822 TEST_P(ValidateGlslStd450Pack, VNotVector) {
3823   const std::string ext_inst_name = GetParam();
3824   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3825   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3826   const uint32_t total_bit_width = num_components * packed_bit_width;
3827 
3828   std::ostringstream body;
3829   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
3830        << ext_inst_name << " %f32_1\n";
3831 
3832   std::ostringstream expected;
3833   expected << "GLSL.std.450 " << ext_inst_name
3834            << ": expected operand V to be a 32-bit float vector of size "
3835            << num_components;
3836 
3837   CompileSuccessfully(GenerateShaderCode(body.str()));
3838   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3839   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3840 }
3841 
3842 TEST_P(ValidateGlslStd450Pack, VNotFloatVector) {
3843   const std::string ext_inst_name = GetParam();
3844   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3845   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3846   const uint32_t total_bit_width = num_components * packed_bit_width;
3847   const std::string vec_str =
3848       num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n";
3849 
3850   std::ostringstream body;
3851   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
3852        << ext_inst_name << vec_str;
3853 
3854   std::ostringstream expected;
3855   expected << "GLSL.std.450 " << ext_inst_name
3856            << ": expected operand V to be a 32-bit float vector of size "
3857            << num_components;
3858 
3859   CompileSuccessfully(GenerateShaderCode(body.str()));
3860   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3861   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3862 }
3863 
3864 TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) {
3865   const std::string ext_inst_name = GetParam();
3866   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3867   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3868   const uint32_t total_bit_width = num_components * packed_bit_width;
3869   const std::string vec_str =
3870       num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n";
3871 
3872   std::ostringstream body;
3873   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
3874        << ext_inst_name << vec_str;
3875 
3876   std::ostringstream expected;
3877   expected << "GLSL.std.450 " << ext_inst_name
3878            << ": expected operand V to be a 32-bit float vector of size "
3879            << num_components;
3880 
3881   CompileSuccessfully(GenerateShaderCode(body.str()));
3882   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3883   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3884 }
3885 
3886 TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) {
3887   const std::string ext_inst_name = GetParam();
3888   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
3889   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
3890   const uint32_t total_bit_width = num_components * packed_bit_width;
3891   const std::string vec_str =
3892       num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
3893 
3894   std::ostringstream body;
3895   body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
3896        << ext_inst_name << vec_str;
3897 
3898   std::ostringstream expected;
3899   expected << "GLSL.std.450 " << ext_inst_name
3900            << ": expected operand V to be a 32-bit float vector of size "
3901            << num_components;
3902 
3903   CompileSuccessfully(GenerateShaderCode(body.str()));
3904   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3905   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
3906 }
3907 
3908 INSTANTIATE_TEST_SUITE_P(AllPack, ValidateGlslStd450Pack,
3909                          ::testing::ValuesIn(std::vector<std::string>{
3910                              "PackSnorm4x8",
3911                              "PackUnorm4x8",
3912                              "PackSnorm2x16",
3913                              "PackUnorm2x16",
3914                              "PackHalf2x16",
3915                          }));
3916 
3917 TEST_F(ValidateExtInst, PackDouble2x32Success) {
3918   const std::string body = R"(
3919 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01
3920 )";
3921 
3922   CompileSuccessfully(GenerateShaderCode(body));
3923   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3924 }
3925 
3926 TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) {
3927   const std::string body = R"(
3928 %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01
3929 )";
3930 
3931   CompileSuccessfully(GenerateShaderCode(body));
3932   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3933   EXPECT_THAT(getDiagnosticString(),
3934               HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
3935                         "be 64-bit float scalar type"));
3936 }
3937 
3938 TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) {
3939   const std::string body = R"(
3940 %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01
3941 )";
3942 
3943   CompileSuccessfully(GenerateShaderCode(body));
3944   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3945   EXPECT_THAT(getDiagnosticString(),
3946               HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
3947                         "be 64-bit float scalar type"));
3948 }
3949 
3950 TEST_F(ValidateExtInst, PackDouble2x32VNotVector) {
3951   const std::string body = R"(
3952 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1
3953 )";
3954 
3955   CompileSuccessfully(GenerateShaderCode(body));
3956   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3957   EXPECT_THAT(getDiagnosticString(),
3958               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
3959                         "a 32-bit int vector of size 2"));
3960 }
3961 
3962 TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) {
3963   const std::string body = R"(
3964 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01
3965 )";
3966 
3967   CompileSuccessfully(GenerateShaderCode(body));
3968   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3969   EXPECT_THAT(getDiagnosticString(),
3970               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
3971                         "a 32-bit int vector of size 2"));
3972 }
3973 
3974 TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) {
3975   const std::string body = R"(
3976 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01
3977 )";
3978 
3979   CompileSuccessfully(GenerateShaderCode(body));
3980   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3981   EXPECT_THAT(getDiagnosticString(),
3982               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
3983                         "a 32-bit int vector of size 2"));
3984 }
3985 
3986 TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) {
3987   const std::string body = R"(
3988 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123
3989 )";
3990 
3991   CompileSuccessfully(GenerateShaderCode(body));
3992   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3993   EXPECT_THAT(getDiagnosticString(),
3994               HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
3995                         "a 32-bit int vector of size 2"));
3996 }
3997 
3998 TEST_P(ValidateGlslStd450Unpack, Success) {
3999   const std::string ext_inst_name = GetParam();
4000   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4001   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4002   const uint32_t total_bit_width = num_components * packed_bit_width;
4003   const std::string result_type_str =
4004       num_components == 2 ? "%f32vec2" : " %f32vec4";
4005 
4006   std::ostringstream body;
4007   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4008        << ext_inst_name << " %u" << total_bit_width << "_1\n";
4009   body << "%val2 = OpExtInst " << result_type_str << " %extinst "
4010        << ext_inst_name << " %s" << total_bit_width << "_1\n";
4011   CompileSuccessfully(GenerateShaderCode(body.str()));
4012   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4013 }
4014 
4015 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) {
4016   const std::string ext_inst_name = GetParam();
4017   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4018   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4019   const uint32_t total_bit_width = num_components * packed_bit_width;
4020   const std::string result_type_str = "%f32";
4021 
4022   std::ostringstream body;
4023   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4024        << ext_inst_name << " %u" << total_bit_width << "_1\n";
4025 
4026   std::ostringstream expected;
4027   expected << "GLSL.std.450 " << ext_inst_name
4028            << ": expected Result Type to be a 32-bit float vector of size "
4029            << num_components;
4030 
4031   CompileSuccessfully(GenerateShaderCode(body.str()));
4032   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4033   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4034 }
4035 
4036 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) {
4037   const std::string ext_inst_name = GetParam();
4038   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4039   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4040   const uint32_t total_bit_width = num_components * packed_bit_width;
4041   const std::string result_type_str =
4042       num_components == 2 ? "%u32vec2" : " %u32vec4";
4043 
4044   std::ostringstream body;
4045   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4046        << ext_inst_name << " %u" << total_bit_width << "_1\n";
4047 
4048   std::ostringstream expected;
4049   expected << "GLSL.std.450 " << ext_inst_name
4050            << ": expected Result Type to be a 32-bit float vector of size "
4051            << num_components;
4052 
4053   CompileSuccessfully(GenerateShaderCode(body.str()));
4054   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4055   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4056 }
4057 
4058 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) {
4059   const std::string ext_inst_name = GetParam();
4060   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4061   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4062   const uint32_t total_bit_width = num_components * packed_bit_width;
4063   const std::string result_type_str =
4064       num_components == 2 ? "%f64vec2" : " %f64vec4";
4065 
4066   std::ostringstream body;
4067   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4068        << ext_inst_name << " %u" << total_bit_width << "_1\n";
4069 
4070   std::ostringstream expected;
4071   expected << "GLSL.std.450 " << ext_inst_name
4072            << ": expected Result Type to be a 32-bit float vector of size "
4073            << num_components;
4074 
4075   CompileSuccessfully(GenerateShaderCode(body.str()));
4076   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4077   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4078 }
4079 
4080 TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) {
4081   const std::string ext_inst_name = GetParam();
4082   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4083   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4084   const uint32_t total_bit_width = num_components * packed_bit_width;
4085   const std::string result_type_str =
4086       num_components == 4 ? "%f32vec2" : " %f32vec4";
4087 
4088   std::ostringstream body;
4089   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4090        << ext_inst_name << " %u" << total_bit_width << "_1\n";
4091 
4092   std::ostringstream expected;
4093   expected << "GLSL.std.450 " << ext_inst_name
4094            << ": expected Result Type to be a 32-bit float vector of size "
4095            << num_components;
4096 
4097   CompileSuccessfully(GenerateShaderCode(body.str()));
4098   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4099   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4100 }
4101 
4102 TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) {
4103   const std::string ext_inst_name = GetParam();
4104   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4105   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4106   const uint32_t total_bit_width = num_components * packed_bit_width;
4107   const std::string result_type_str =
4108       num_components == 2 ? "%f32vec2" : " %f32vec4";
4109 
4110   std::ostringstream body;
4111   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4112        << ext_inst_name << " %f" << total_bit_width << "_1\n";
4113 
4114   std::ostringstream expected;
4115   expected << "GLSL.std.450 " << ext_inst_name
4116            << ": expected operand P to be a " << total_bit_width
4117            << "-bit int scalar";
4118 
4119   CompileSuccessfully(GenerateShaderCode(body.str()));
4120   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4121   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4122 }
4123 
4124 TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) {
4125   const std::string ext_inst_name = GetParam();
4126   const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4127   const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4128   const uint32_t total_bit_width = num_components * packed_bit_width;
4129   const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32;
4130   const std::string result_type_str =
4131       num_components == 2 ? "%f32vec2" : " %f32vec4";
4132 
4133   std::ostringstream body;
4134   body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4135        << ext_inst_name << " %u" << wrong_bit_width << "_1\n";
4136 
4137   std::ostringstream expected;
4138   expected << "GLSL.std.450 " << ext_inst_name
4139            << ": expected operand P to be a " << total_bit_width
4140            << "-bit int scalar";
4141 
4142   CompileSuccessfully(GenerateShaderCode(body.str()));
4143   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4144   EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4145 }
4146 
4147 INSTANTIATE_TEST_SUITE_P(AllUnpack, ValidateGlslStd450Unpack,
4148                          ::testing::ValuesIn(std::vector<std::string>{
4149                              "UnpackSnorm4x8",
4150                              "UnpackUnorm4x8",
4151                              "UnpackSnorm2x16",
4152                              "UnpackUnorm2x16",
4153                              "UnpackHalf2x16",
4154                          }));
4155 
4156 TEST_F(ValidateExtInst, UnpackDouble2x32Success) {
4157   const std::string body = R"(
4158 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1
4159 )";
4160 
4161   CompileSuccessfully(GenerateShaderCode(body));
4162   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4163 }
4164 
4165 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) {
4166   const std::string body = R"(
4167 %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1
4168 )";
4169 
4170   CompileSuccessfully(GenerateShaderCode(body));
4171   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4172   EXPECT_THAT(getDiagnosticString(),
4173               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4174                         "to be a 32-bit int vector of size 2"));
4175 }
4176 
4177 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) {
4178   const std::string body = R"(
4179 %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1
4180 )";
4181 
4182   CompileSuccessfully(GenerateShaderCode(body));
4183   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4184   EXPECT_THAT(getDiagnosticString(),
4185               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4186                         "to be a 32-bit int vector of size 2"));
4187 }
4188 
4189 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) {
4190   const std::string body = R"(
4191 %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1
4192 )";
4193 
4194   CompileSuccessfully(GenerateShaderCode(body));
4195   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4196   EXPECT_THAT(getDiagnosticString(),
4197               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4198                         "to be a 32-bit int vector of size 2"));
4199 }
4200 
4201 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) {
4202   const std::string body = R"(
4203 %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1
4204 )";
4205 
4206   CompileSuccessfully(GenerateShaderCode(body));
4207   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4208   EXPECT_THAT(getDiagnosticString(),
4209               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4210                         "to be a 32-bit int vector of size 2"));
4211 }
4212 
4213 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) {
4214   const std::string body = R"(
4215 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1
4216 )";
4217 
4218   CompileSuccessfully(GenerateShaderCode(body));
4219   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4220   EXPECT_THAT(getDiagnosticString(),
4221               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4222                         "be a 64-bit float scalar"));
4223 }
4224 
4225 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) {
4226   const std::string body = R"(
4227 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1
4228 )";
4229 
4230   CompileSuccessfully(GenerateShaderCode(body));
4231   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4232   EXPECT_THAT(getDiagnosticString(),
4233               HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4234                         "be a 64-bit float scalar"));
4235 }
4236 
4237 TEST_F(ValidateExtInst, GlslStd450LengthSuccess) {
4238   const std::string body = R"(
4239 %val1 = OpExtInst %f32 %extinst Length %f32_1
4240 %val2 = OpExtInst %f32 %extinst Length %f32vec2_01
4241 %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123
4242 )";
4243 
4244   CompileSuccessfully(GenerateShaderCode(body));
4245   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4246 }
4247 
4248 TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) {
4249   const std::string body = R"(
4250 %val1 = OpExtInst %u32 %extinst Length %f32vec2_01
4251 )";
4252 
4253   CompileSuccessfully(GenerateShaderCode(body));
4254   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4255   EXPECT_THAT(getDiagnosticString(),
4256               HasSubstr("GLSL.std.450 Length: "
4257                         "expected Result Type to be a float scalar type"));
4258 }
4259 
4260 TEST_F(ValidateExtInst, GlslStd450LengthIntX) {
4261   const std::string body = R"(
4262 %val1 = OpExtInst %f32 %extinst Length %u32vec2_01
4263 )";
4264 
4265   CompileSuccessfully(GenerateShaderCode(body));
4266   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4267   EXPECT_THAT(getDiagnosticString(),
4268               HasSubstr("GLSL.std.450 Length: "
4269                         "expected operand X to be of float scalar or "
4270                         "vector type"));
4271 }
4272 
4273 TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) {
4274   const std::string body = R"(
4275 %val1 = OpExtInst %f64 %extinst Length %f32vec2_01
4276 )";
4277 
4278   CompileSuccessfully(GenerateShaderCode(body));
4279   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4280   EXPECT_THAT(getDiagnosticString(),
4281               HasSubstr("GLSL.std.450 Length: "
4282                         "expected operand X component type to be equal to "
4283                         "Result Type"));
4284 }
4285 
4286 TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) {
4287   const std::string body = R"(
4288 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1
4289 %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12
4290 %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234
4291 )";
4292 
4293   CompileSuccessfully(GenerateShaderCode(body));
4294   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4295 }
4296 
4297 TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) {
4298   const std::string body = R"(
4299 %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12
4300 )";
4301 
4302   CompileSuccessfully(GenerateShaderCode(body));
4303   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4304   EXPECT_THAT(getDiagnosticString(),
4305               HasSubstr("GLSL.std.450 Distance: "
4306                         "expected Result Type to be a float scalar type"));
4307 }
4308 
4309 TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) {
4310   const std::string body = R"(
4311 %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1
4312 )";
4313 
4314   CompileSuccessfully(GenerateShaderCode(body));
4315   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4316   EXPECT_THAT(getDiagnosticString(),
4317               HasSubstr("GLSL.std.450 Distance: "
4318                         "expected operand P0 to be of float scalar or "
4319                         "vector type"));
4320 }
4321 
4322 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) {
4323   const std::string body = R"(
4324 %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12
4325 )";
4326 
4327   CompileSuccessfully(GenerateShaderCode(body));
4328   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4329   EXPECT_THAT(getDiagnosticString(),
4330               HasSubstr("GLSL.std.450 Distance: "
4331                         "expected operand P0 component type to be equal to "
4332                         "Result Type"));
4333 }
4334 
4335 TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) {
4336   const std::string body = R"(
4337 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1
4338 )";
4339 
4340   CompileSuccessfully(GenerateShaderCode(body));
4341   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4342   EXPECT_THAT(getDiagnosticString(),
4343               HasSubstr("GLSL.std.450 Distance: "
4344                         "expected operand P1 to be of float scalar or "
4345                         "vector type"));
4346 }
4347 
4348 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) {
4349   const std::string body = R"(
4350 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01
4351 )";
4352 
4353   CompileSuccessfully(GenerateShaderCode(body));
4354   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4355   EXPECT_THAT(getDiagnosticString(),
4356               HasSubstr("GLSL.std.450 Distance: "
4357                         "expected operand P1 component type to be equal to "
4358                         "Result Type"));
4359 }
4360 
4361 TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) {
4362   const std::string body = R"(
4363 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123
4364 )";
4365 
4366   CompileSuccessfully(GenerateShaderCode(body));
4367   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4368   EXPECT_THAT(getDiagnosticString(),
4369               HasSubstr("GLSL.std.450 Distance: "
4370                         "expected operands P0 and P1 to have the same number "
4371                         "of components"));
4372 }
4373 
4374 TEST_F(ValidateExtInst, GlslStd450CrossSuccess) {
4375   const std::string body = R"(
4376 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
4377 )";
4378 
4379   CompileSuccessfully(GenerateShaderCode(body));
4380   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4381 }
4382 
4383 TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) {
4384   const std::string body = R"(
4385 %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
4386 )";
4387 
4388   CompileSuccessfully(GenerateShaderCode(body));
4389   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4390   EXPECT_THAT(getDiagnosticString(),
4391               HasSubstr("GLSL.std.450 Cross: "
4392                         "expected Result Type to be a float vector type"));
4393 }
4394 
4395 TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) {
4396   const std::string body = R"(
4397 %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123
4398 )";
4399 
4400   CompileSuccessfully(GenerateShaderCode(body));
4401   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4402   EXPECT_THAT(getDiagnosticString(),
4403               HasSubstr("GLSL.std.450 Cross: "
4404                         "expected Result Type to have 3 components"));
4405 }
4406 
4407 TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) {
4408   const std::string body = R"(
4409 %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123
4410 )";
4411 
4412   CompileSuccessfully(GenerateShaderCode(body));
4413   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4414   EXPECT_THAT(getDiagnosticString(),
4415               HasSubstr("GLSL.std.450 Cross: "
4416                         "expected operand X type to be equal to Result Type"));
4417 }
4418 
4419 TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) {
4420   const std::string body = R"(
4421 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012
4422 )";
4423 
4424   CompileSuccessfully(GenerateShaderCode(body));
4425   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4426   EXPECT_THAT(getDiagnosticString(),
4427               HasSubstr("GLSL.std.450 Cross: "
4428                         "expected operand Y type to be equal to Result Type"));
4429 }
4430 
4431 TEST_F(ValidateExtInst, GlslStd450RefractSuccess) {
4432   const std::string body = R"(
4433 %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1
4434 %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1
4435 )";
4436 
4437   CompileSuccessfully(GenerateShaderCode(body));
4438   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4439 }
4440 
4441 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) {
4442   const std::string body = R"(
4443 %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1
4444 )";
4445 
4446   CompileSuccessfully(GenerateShaderCode(body));
4447   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4448   EXPECT_THAT(getDiagnosticString(),
4449               HasSubstr("GLSL.std.450 Refract: "
4450                         "expected Result Type to be a float scalar or "
4451                         "vector type"));
4452 }
4453 
4454 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) {
4455   const std::string body = R"(
4456 %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1
4457 )";
4458 
4459   CompileSuccessfully(GenerateShaderCode(body));
4460   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4461   EXPECT_THAT(getDiagnosticString(),
4462               HasSubstr("GLSL.std.450 Refract: "
4463                         "expected operand I to be of type equal to "
4464                         "Result Type"));
4465 }
4466 
4467 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) {
4468   const std::string body = R"(
4469 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1
4470 )";
4471 
4472   CompileSuccessfully(GenerateShaderCode(body));
4473   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4474   EXPECT_THAT(getDiagnosticString(),
4475               HasSubstr("GLSL.std.450 Refract: "
4476                         "expected operand N to be of type equal to "
4477                         "Result Type"));
4478 }
4479 
4480 TEST_F(ValidateExtInst, GlslStd450RefractIntEta) {
4481   const std::string body = R"(
4482 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1
4483 )";
4484 
4485   CompileSuccessfully(GenerateShaderCode(body));
4486   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4487   EXPECT_THAT(getDiagnosticString(),
4488               HasSubstr("GLSL.std.450 Refract: "
4489                         "expected operand Eta to be a float scalar"));
4490 }
4491 
4492 TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) {
4493   // SPIR-V issue 337: Eta can be 64-bit float scalar.
4494   const std::string body = R"(
4495 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1
4496 )";
4497 
4498   CompileSuccessfully(GenerateShaderCode(body));
4499   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4500   EXPECT_THAT(getDiagnosticString(), Eq(""));
4501 }
4502 
4503 TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) {
4504   const std::string body = R"(
4505 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01
4506 )";
4507 
4508   CompileSuccessfully(GenerateShaderCode(body));
4509   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4510   EXPECT_THAT(getDiagnosticString(),
4511               HasSubstr("GLSL.std.450 Refract: "
4512                         "expected operand Eta to be a float scalar"));
4513 }
4514 
4515 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) {
4516   const std::string body = R"(
4517 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
4518 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input
4519 )";
4520 
4521   CompileSuccessfully(
4522       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4523   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4524 }
4525 
4526 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
4527   const std::string body = R"(
4528 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
4529 )";
4530 
4531   CompileSuccessfully(GenerateShaderCode(body));
4532   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
4533   EXPECT_THAT(getDiagnosticString(),
4534               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
4535                         "capability InterpolationFunction"));
4536 }
4537 
4538 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
4539   const std::string body = R"(
4540 %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
4541 )";
4542 
4543   CompileSuccessfully(
4544       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4545   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4546   EXPECT_THAT(getDiagnosticString(),
4547               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
4548                         "expected Result Type to be a 32-bit float scalar "
4549                         "or vector type"));
4550 }
4551 
4552 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
4553   const std::string body = R"(
4554 %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
4555 )";
4556 
4557   CompileSuccessfully(
4558       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4559   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4560   EXPECT_THAT(getDiagnosticString(),
4561               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
4562                         "expected Result Type to be a 32-bit float scalar "
4563                         "or vector type"));
4564 }
4565 
4566 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
4567   const std::string body = R"(
4568 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
4569 )";
4570 
4571   CompileSuccessfully(
4572       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4573   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4574   EXPECT_THAT(getDiagnosticString(),
4575               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
4576                         "expected Interpolant to be a pointer"));
4577 }
4578 
4579 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
4580   const std::string body = R"(
4581 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
4582 )";
4583 
4584   CompileSuccessfully(
4585       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4586   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4587   EXPECT_THAT(getDiagnosticString(),
4588               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
4589                         "expected Interpolant data type to be equal to "
4590                         "Result Type"));
4591 }
4592 
4593 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
4594   const std::string body = R"(
4595 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
4596 )";
4597 
4598   CompileSuccessfully(
4599       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4600   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4601   EXPECT_THAT(getDiagnosticString(),
4602               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
4603                         "expected Interpolant storage class to be Input"));
4604 }
4605 
4606 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
4607   const std::string body = R"(
4608 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
4609 )";
4610 
4611   CompileSuccessfully(GenerateShaderCode(
4612       body, "OpCapability InterpolationFunction\n", "Vertex"));
4613   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4614   EXPECT_THAT(getDiagnosticString(),
4615               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
4616                         "Fragment execution model"));
4617 }
4618 
4619 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
4620   const std::string body = R"(
4621 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
4622 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
4623 )";
4624 
4625   CompileSuccessfully(
4626       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4627   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4628 }
4629 
4630 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
4631   const std::string body = R"(
4632 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
4633 )";
4634 
4635   CompileSuccessfully(GenerateShaderCode(body));
4636   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
4637   EXPECT_THAT(getDiagnosticString(),
4638               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
4639                         "capability InterpolationFunction"));
4640 }
4641 
4642 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
4643   const std::string body = R"(
4644 %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
4645 )";
4646 
4647   CompileSuccessfully(
4648       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4649   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4650   EXPECT_THAT(getDiagnosticString(),
4651               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4652                         "expected Result Type to be a 32-bit float scalar "
4653                         "or vector type"));
4654 }
4655 
4656 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
4657   const std::string body = R"(
4658 %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
4659 )";
4660 
4661   CompileSuccessfully(
4662       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4663   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4664   EXPECT_THAT(getDiagnosticString(),
4665               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4666                         "expected Result Type to be a 32-bit float scalar "
4667                         "or vector type"));
4668 }
4669 
4670 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
4671   const std::string body = R"(
4672 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
4673 )";
4674 
4675   CompileSuccessfully(
4676       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4677   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4678   EXPECT_THAT(getDiagnosticString(),
4679               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4680                         "expected Interpolant to be a pointer"));
4681 }
4682 
4683 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
4684   const std::string body = R"(
4685 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
4686 )";
4687 
4688   CompileSuccessfully(
4689       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4690   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4691   EXPECT_THAT(getDiagnosticString(),
4692               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4693                         "expected Interpolant data type to be equal to "
4694                         "Result Type"));
4695 }
4696 
4697 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
4698   const std::string body = R"(
4699 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
4700 )";
4701 
4702   CompileSuccessfully(
4703       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4704   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4705   EXPECT_THAT(getDiagnosticString(),
4706               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4707                         "expected Interpolant storage class to be Input"));
4708 }
4709 
4710 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
4711   const std::string body = R"(
4712 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
4713 )";
4714 
4715   CompileSuccessfully(
4716       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4717   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4718   EXPECT_THAT(getDiagnosticString(),
4719               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4720                         "expected Sample to be 32-bit integer"));
4721 }
4722 
4723 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
4724   const std::string body = R"(
4725 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
4726 )";
4727 
4728   CompileSuccessfully(
4729       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4730   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4731   EXPECT_THAT(getDiagnosticString(),
4732               HasSubstr("GLSL.std.450 InterpolateAtSample: "
4733                         "expected Sample to be 32-bit integer"));
4734 }
4735 
4736 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
4737   const std::string body = R"(
4738 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
4739 )";
4740 
4741   CompileSuccessfully(GenerateShaderCode(
4742       body, "OpCapability InterpolationFunction\n", "Vertex"));
4743   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4744   EXPECT_THAT(getDiagnosticString(),
4745               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
4746                         "Fragment execution model"));
4747 }
4748 
4749 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
4750   const std::string body = R"(
4751 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
4752 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
4753 )";
4754 
4755   CompileSuccessfully(
4756       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4757   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4758 }
4759 
4760 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
4761   const std::string body = R"(
4762 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
4763 )";
4764 
4765   CompileSuccessfully(GenerateShaderCode(body));
4766   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
4767   EXPECT_THAT(getDiagnosticString(),
4768               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
4769                         "capability InterpolationFunction"));
4770 }
4771 
4772 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
4773   const std::string body = R"(
4774 %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
4775 )";
4776 
4777   CompileSuccessfully(
4778       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4779   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4780   EXPECT_THAT(getDiagnosticString(),
4781               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4782                         "expected Result Type to be a 32-bit float scalar "
4783                         "or vector type"));
4784 }
4785 
4786 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
4787   const std::string body = R"(
4788 %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
4789 )";
4790 
4791   CompileSuccessfully(
4792       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4793   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4794   EXPECT_THAT(getDiagnosticString(),
4795               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4796                         "expected Result Type to be a 32-bit float scalar "
4797                         "or vector type"));
4798 }
4799 
4800 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
4801   const std::string body = R"(
4802 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
4803 )";
4804 
4805   CompileSuccessfully(
4806       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4807   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4808   EXPECT_THAT(getDiagnosticString(),
4809               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4810                         "expected Interpolant to be a pointer"));
4811 }
4812 
4813 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
4814   const std::string body = R"(
4815 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
4816 )";
4817 
4818   CompileSuccessfully(
4819       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4820   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4821   EXPECT_THAT(getDiagnosticString(),
4822               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4823                         "expected Interpolant data type to be equal to "
4824                         "Result Type"));
4825 }
4826 
4827 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
4828   const std::string body = R"(
4829 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
4830 )";
4831 
4832   CompileSuccessfully(
4833       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4834   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4835   EXPECT_THAT(getDiagnosticString(),
4836               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4837                         "expected Interpolant storage class to be Input"));
4838 }
4839 
4840 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
4841   const std::string body = R"(
4842 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
4843 )";
4844 
4845   CompileSuccessfully(
4846       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4847   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4848   EXPECT_THAT(getDiagnosticString(),
4849               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4850                         "expected Offset to be a vector of 2 32-bit floats"));
4851 }
4852 
4853 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
4854   const std::string body = R"(
4855 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
4856 )";
4857 
4858   CompileSuccessfully(
4859       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4860   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4861   EXPECT_THAT(getDiagnosticString(),
4862               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4863                         "expected Offset to be a vector of 2 32-bit floats"));
4864 }
4865 
4866 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
4867   const std::string body = R"(
4868 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
4869 )";
4870 
4871   CompileSuccessfully(
4872       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4873   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4874   EXPECT_THAT(getDiagnosticString(),
4875               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4876                         "expected Offset to be a vector of 2 32-bit floats"));
4877 }
4878 
4879 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
4880   const std::string body = R"(
4881 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
4882 )";
4883 
4884   CompileSuccessfully(
4885       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
4886   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4887   EXPECT_THAT(getDiagnosticString(),
4888               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
4889                         "expected Offset to be a vector of 2 32-bit floats"));
4890 }
4891 
4892 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
4893   const std::string body = R"(
4894 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
4895 )";
4896 
4897   CompileSuccessfully(GenerateShaderCode(
4898       body, "OpCapability InterpolationFunction\n", "Vertex"));
4899   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4900   EXPECT_THAT(getDiagnosticString(),
4901               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
4902                         "Fragment execution model"));
4903 }
4904 
4905 TEST_P(ValidateOpenCLStdSqrtLike, Success) {
4906   const std::string ext_inst_name = GetParam();
4907   std::ostringstream ss;
4908   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
4909   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
4910      << " %f32vec2_01\n";
4911   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
4912      << " %f32vec4_0123\n";
4913   ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
4914   CompileSuccessfully(GenerateKernelCode(ss.str()));
4915   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4916 }
4917 
4918 TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
4919   const std::string ext_inst_name = GetParam();
4920   const std::string body =
4921       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
4922 
4923   CompileSuccessfully(GenerateKernelCode(body));
4924   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4925   EXPECT_THAT(getDiagnosticString(),
4926               HasSubstr("OpenCL.std " + ext_inst_name +
4927                         ": expected Result Type to be a float scalar "
4928                         "or vector type"));
4929 }
4930 
4931 TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
4932   const std::string ext_inst_name = GetParam();
4933   const std::string body =
4934       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
4935 
4936   CompileSuccessfully(GenerateKernelCode(body));
4937   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4938   EXPECT_THAT(getDiagnosticString(),
4939               HasSubstr("OpenCL.std " + ext_inst_name +
4940                         ": expected types of all operands to be equal to "
4941                         "Result Type"));
4942 }
4943 
4944 INSTANTIATE_TEST_SUITE_P(
4945     AllSqrtLike, ValidateOpenCLStdSqrtLike,
4946     ::testing::ValuesIn(std::vector<std::string>{
4947         "acos",         "acosh",       "acospi",       "asin",
4948         "asinh",        "asinpi",      "atan",         "atanh",
4949         "atanpi",       "cbrt",        "ceil",         "cos",
4950         "cosh",         "cospi",       "erfc",         "erf",
4951         "exp",          "exp2",        "exp10",        "expm1",
4952         "fabs",         "floor",       "log",          "log2",
4953         "log10",        "log1p",       "logb",         "rint",
4954         "round",        "rsqrt",       "sin",          "sinh",
4955         "sinpi",        "sqrt",        "tan",          "tanh",
4956         "tanpi",        "tgamma",      "trunc",        "half_cos",
4957         "half_exp",     "half_exp2",   "half_exp10",   "half_log",
4958         "half_log2",    "half_log10",  "half_recip",   "half_rsqrt",
4959         "half_sin",     "half_sqrt",   "half_tan",     "lgamma",
4960         "native_cos",   "native_exp",  "native_exp2",  "native_exp10",
4961         "native_log",   "native_log2", "native_log10", "native_recip",
4962         "native_rsqrt", "native_sin",  "native_sqrt",  "native_tan",
4963         "degrees",      "radians",     "sign",
4964     }));
4965 
4966 TEST_P(ValidateOpenCLStdFMinLike, Success) {
4967   const std::string ext_inst_name = GetParam();
4968   std::ostringstream ss;
4969   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
4970      << " %f32_0 %f32_1\n";
4971   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
4972      << " %f32vec2_01 %f32vec2_12\n";
4973   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
4974      << " %f64_0 %f64_0\n";
4975   CompileSuccessfully(GenerateKernelCode(ss.str()));
4976   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4977 }
4978 
4979 TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
4980   const std::string ext_inst_name = GetParam();
4981   const std::string body =
4982       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
4983 
4984   CompileSuccessfully(GenerateKernelCode(body));
4985   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4986   EXPECT_THAT(getDiagnosticString(),
4987               HasSubstr("OpenCL.std " + ext_inst_name +
4988                         ": expected Result Type to be a float scalar "
4989                         "or vector type"));
4990 }
4991 
4992 TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
4993   const std::string ext_inst_name = GetParam();
4994   const std::string body =
4995       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
4996 
4997   CompileSuccessfully(GenerateKernelCode(body));
4998   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4999   EXPECT_THAT(getDiagnosticString(),
5000               HasSubstr("OpenCL.std " + ext_inst_name +
5001                         ": expected types of all operands to be equal to "
5002                         "Result Type"));
5003 }
5004 
5005 TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
5006   const std::string ext_inst_name = GetParam();
5007   const std::string body =
5008       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
5009 
5010   CompileSuccessfully(GenerateKernelCode(body));
5011   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5012   EXPECT_THAT(getDiagnosticString(),
5013               HasSubstr("OpenCL.std " + ext_inst_name +
5014                         ": expected types of all operands to be equal to "
5015                         "Result Type"));
5016 }
5017 
5018 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
5019                          ::testing::ValuesIn(std::vector<std::string>{
5020                              "atan2",     "atan2pi",       "copysign",
5021                              "fdim",      "fmax",          "fmin",
5022                              "fmod",      "maxmag",        "minmag",
5023                              "hypot",     "nextafter",     "pow",
5024                              "powr",      "remainder",     "half_divide",
5025                              "half_powr", "native_divide", "native_powr",
5026                              "step",      "fmax_common",   "fmin_common",
5027                          }));
5028 
5029 TEST_P(ValidateOpenCLStdFClampLike, Success) {
5030   const std::string ext_inst_name = GetParam();
5031   std::ostringstream ss;
5032   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5033      << " %f32_0 %f32_1 %f32_2\n";
5034   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5035      << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
5036   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5037      << " %f64_0 %f64_0 %f64_1\n";
5038   CompileSuccessfully(GenerateKernelCode(ss.str()));
5039   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5040 }
5041 
5042 TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
5043   const std::string ext_inst_name = GetParam();
5044   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5045                            " %f32_0 %f32_1 %f32_2\n";
5046 
5047   CompileSuccessfully(GenerateKernelCode(body));
5048   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5049   EXPECT_THAT(getDiagnosticString(),
5050               HasSubstr("OpenCL.std " + ext_inst_name +
5051                         ": expected Result Type to be a float scalar "
5052                         "or vector type"));
5053 }
5054 
5055 TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
5056   const std::string ext_inst_name = GetParam();
5057   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5058                            " %u32_0 %f32_0 %f32_1\n";
5059 
5060   CompileSuccessfully(GenerateKernelCode(body));
5061   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5062   EXPECT_THAT(getDiagnosticString(),
5063               HasSubstr("OpenCL.std " + ext_inst_name +
5064                         ": expected types of all operands to be equal to "
5065                         "Result Type"));
5066 }
5067 
5068 TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
5069   const std::string ext_inst_name = GetParam();
5070   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5071                            " %f32_0 %u32_0 %f32_1\n";
5072 
5073   CompileSuccessfully(GenerateKernelCode(body));
5074   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5075   EXPECT_THAT(getDiagnosticString(),
5076               HasSubstr("OpenCL.std " + ext_inst_name +
5077                         ": expected types of all operands to be equal to "
5078                         "Result Type"));
5079 }
5080 
5081 TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
5082   const std::string ext_inst_name = GetParam();
5083   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5084                            " %f32_1 %f32_0 %u32_2\n";
5085 
5086   CompileSuccessfully(GenerateKernelCode(body));
5087   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5088   EXPECT_THAT(getDiagnosticString(),
5089               HasSubstr("OpenCL.std " + ext_inst_name +
5090                         ": expected types of all operands to be equal to "
5091                         "Result Type"));
5092 }
5093 
5094 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
5095                          ::testing::ValuesIn(std::vector<std::string>{
5096                              "fma",
5097                              "mad",
5098                              "fclamp",
5099                              "mix",
5100                              "smoothstep",
5101                          }));
5102 
5103 TEST_P(ValidateOpenCLStdSAbsLike, Success) {
5104   const std::string ext_inst_name = GetParam();
5105   std::ostringstream ss;
5106   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5107   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5108   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5109   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5110   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5111      << " %u32vec2_01\n";
5112   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5113      << " %u32vec2_01\n";
5114   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5115      << " %u32vec2_01\n";
5116   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5117      << " %u32vec2_01\n";
5118   CompileSuccessfully(GenerateKernelCode(ss.str()));
5119   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5120 }
5121 
5122 TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
5123   const std::string ext_inst_name = GetParam();
5124   const std::string body =
5125       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5126 
5127   CompileSuccessfully(GenerateKernelCode(body));
5128   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5129   EXPECT_THAT(getDiagnosticString(),
5130               HasSubstr("OpenCL.std " + ext_inst_name +
5131                         ": expected Result Type to be an int scalar "
5132                         "or vector type"));
5133 }
5134 
5135 TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
5136   const std::string ext_inst_name = GetParam();
5137   const std::string body =
5138       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5139 
5140   CompileSuccessfully(GenerateKernelCode(body));
5141   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5142   EXPECT_THAT(
5143       getDiagnosticString(),
5144       HasSubstr("OpenCL.std " + ext_inst_name +
5145                 ": expected types of all operands to be equal to Result Type"));
5146 }
5147 
5148 TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
5149   const std::string ext_inst_name = GetParam();
5150   const std::string body =
5151       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
5152 
5153   CompileSuccessfully(GenerateKernelCode(body));
5154   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5155   EXPECT_THAT(
5156       getDiagnosticString(),
5157       HasSubstr("OpenCL.std " + ext_inst_name +
5158                 ": expected types of all operands to be equal to Result Type"));
5159 }
5160 
5161 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
5162                          ::testing::ValuesIn(std::vector<std::string>{
5163                              "s_abs",
5164                              "clz",
5165                              "ctz",
5166                              "popcount",
5167                              "u_abs",
5168                          }));
5169 
5170 TEST_P(ValidateOpenCLStdUMinLike, Success) {
5171   const std::string ext_inst_name = GetParam();
5172   std::ostringstream ss;
5173   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5174      << " %u32_1 %u32_2\n";
5175   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5176      << " %u32_1 %u32_2\n";
5177   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5178      << " %u32_1 %u32_2\n";
5179   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5180      << " %u32_1 %u32_2\n";
5181   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5182      << " %u32vec2_01 %u32vec2_01\n";
5183   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5184      << " %u32vec2_01 %u32vec2_01\n";
5185   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5186      << " %u32vec2_01 %u32vec2_01\n";
5187   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5188      << " %u32vec2_01 %u32vec2_01\n";
5189   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5190      << " %u64_1 %u64_0\n";
5191   CompileSuccessfully(GenerateKernelCode(ss.str()));
5192   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5193 }
5194 
5195 TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
5196   const std::string ext_inst_name = GetParam();
5197   const std::string body =
5198       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
5199 
5200   CompileSuccessfully(GenerateKernelCode(body));
5201   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5202   EXPECT_THAT(getDiagnosticString(),
5203               HasSubstr("OpenCL.std " + ext_inst_name +
5204                         ": expected Result Type to be an int scalar "
5205                         "or vector type"));
5206 }
5207 
5208 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
5209   const std::string ext_inst_name = GetParam();
5210   const std::string body =
5211       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
5212 
5213   CompileSuccessfully(GenerateKernelCode(body));
5214   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5215   EXPECT_THAT(
5216       getDiagnosticString(),
5217       HasSubstr("OpenCL.std " + ext_inst_name +
5218                 ": expected types of all operands to be equal to Result Type"));
5219 }
5220 
5221 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
5222   const std::string ext_inst_name = GetParam();
5223   const std::string body =
5224       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
5225 
5226   CompileSuccessfully(GenerateKernelCode(body));
5227   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5228   EXPECT_THAT(
5229       getDiagnosticString(),
5230       HasSubstr("OpenCL.std " + ext_inst_name +
5231                 ": expected types of all operands to be equal to Result Type"));
5232 }
5233 
5234 TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
5235   const std::string ext_inst_name = GetParam();
5236   const std::string body =
5237       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
5238 
5239   CompileSuccessfully(GenerateKernelCode(body));
5240   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5241   EXPECT_THAT(
5242       getDiagnosticString(),
5243       HasSubstr("OpenCL.std " + ext_inst_name +
5244                 ": expected types of all operands to be equal to Result Type"));
5245 }
5246 
5247 TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
5248   const std::string ext_inst_name = GetParam();
5249   const std::string body =
5250       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
5251 
5252   CompileSuccessfully(GenerateKernelCode(body));
5253   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5254   EXPECT_THAT(
5255       getDiagnosticString(),
5256       HasSubstr("OpenCL.std " + ext_inst_name +
5257                 ": expected types of all operands to be equal to Result Type"));
5258 }
5259 
5260 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
5261                          ::testing::ValuesIn(std::vector<std::string>{
5262                              "s_max",
5263                              "u_max",
5264                              "s_min",
5265                              "u_min",
5266                              "s_abs_diff",
5267                              "s_add_sat",
5268                              "u_add_sat",
5269                              "s_mul_hi",
5270                              "rotate",
5271                              "s_sub_sat",
5272                              "u_sub_sat",
5273                              "s_hadd",
5274                              "u_hadd",
5275                              "s_rhadd",
5276                              "u_rhadd",
5277                              "u_abs_diff",
5278                              "u_mul_hi",
5279                          }));
5280 
5281 TEST_P(ValidateOpenCLStdUClampLike, Success) {
5282   const std::string ext_inst_name = GetParam();
5283   std::ostringstream ss;
5284   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5285      << " %u32_0 %u32_1 %u32_2\n";
5286   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5287      << " %u32_0 %u32_1 %u32_2\n";
5288   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5289      << " %u32_0 %u32_1 %u32_2\n";
5290   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5291      << " %u32_0 %u32_1 %u32_2\n";
5292   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5293      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5294   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5295      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5296   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5297      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5298   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5299      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5300   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5301      << " %u64_1 %u64_0 %u64_1\n";
5302   CompileSuccessfully(GenerateKernelCode(ss.str()));
5303   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5304 }
5305 
5306 TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
5307   const std::string ext_inst_name = GetParam();
5308   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5309                            " %u32_0 %u32_0 %u32_1\n";
5310 
5311   CompileSuccessfully(GenerateKernelCode(body));
5312   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5313   EXPECT_THAT(getDiagnosticString(),
5314               HasSubstr("OpenCL.std " + ext_inst_name +
5315                         ": expected Result Type to be an int scalar "
5316                         "or vector type"));
5317 }
5318 
5319 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
5320   const std::string ext_inst_name = GetParam();
5321   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5322                            " %f32_0 %u32_0 %u32_1\n";
5323 
5324   CompileSuccessfully(GenerateKernelCode(body));
5325   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5326   EXPECT_THAT(
5327       getDiagnosticString(),
5328       HasSubstr("OpenCL.std " + ext_inst_name +
5329                 ": expected types of all operands to be equal to Result Type"));
5330 }
5331 
5332 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
5333   const std::string ext_inst_name = GetParam();
5334   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5335                            " %u32_0 %f32_0 %u32_1\n";
5336 
5337   CompileSuccessfully(GenerateKernelCode(body));
5338   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5339   EXPECT_THAT(
5340       getDiagnosticString(),
5341       HasSubstr("OpenCL.std " + ext_inst_name +
5342                 ": expected types of all operands to be equal to Result Type"));
5343 }
5344 
5345 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
5346   const std::string ext_inst_name = GetParam();
5347   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5348                            " %u32_0 %u32_0 %f32_1\n";
5349 
5350   CompileSuccessfully(GenerateKernelCode(body));
5351   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5352   EXPECT_THAT(
5353       getDiagnosticString(),
5354       HasSubstr("OpenCL.std " + ext_inst_name +
5355                 ": expected types of all operands to be equal to Result Type"));
5356 }
5357 
5358 TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
5359   const std::string ext_inst_name = GetParam();
5360   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5361                            " %f32_0 %u32_0 %u64_1\n";
5362 
5363   CompileSuccessfully(GenerateKernelCode(body));
5364   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5365   EXPECT_THAT(
5366       getDiagnosticString(),
5367       HasSubstr("OpenCL.std " + ext_inst_name +
5368                 ": expected types of all operands to be equal to Result Type"));
5369 }
5370 
5371 TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
5372   const std::string ext_inst_name = GetParam();
5373   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5374                            " %u32_0 %f32_0 %u64_1\n";
5375 
5376   CompileSuccessfully(GenerateKernelCode(body));
5377   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5378   EXPECT_THAT(
5379       getDiagnosticString(),
5380       HasSubstr("OpenCL.std " + ext_inst_name +
5381                 ": expected types of all operands to be equal to Result Type"));
5382 }
5383 
5384 TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
5385   const std::string ext_inst_name = GetParam();
5386   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5387                            " %u32_0 %u32_0 %u64_1\n";
5388 
5389   CompileSuccessfully(GenerateKernelCode(body));
5390   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5391   EXPECT_THAT(
5392       getDiagnosticString(),
5393       HasSubstr("OpenCL.std " + ext_inst_name +
5394                 ": expected types of all operands to be equal to Result Type"));
5395 }
5396 
5397 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
5398                          ::testing::ValuesIn(std::vector<std::string>{
5399                              "s_clamp",
5400                              "u_clamp",
5401                              "s_mad_hi",
5402                              "u_mad_sat",
5403                              "s_mad_sat",
5404                              "u_mad_hi",
5405                          }));
5406 
5407 // -------------------------------------------------------------
5408 TEST_P(ValidateOpenCLStdUMul24Like, Success) {
5409   const std::string ext_inst_name = GetParam();
5410   std::ostringstream ss;
5411   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5412      << " %u32_1 %u32_2\n";
5413   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5414      << " %u32_1 %u32_2\n";
5415   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5416      << " %u32_1 %u32_2\n";
5417   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5418      << " %u32_1 %u32_2\n";
5419   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5420      << " %u32vec2_01 %u32vec2_01\n";
5421   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5422      << " %u32vec2_01 %u32vec2_01\n";
5423   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5424      << " %u32vec2_01 %u32vec2_01\n";
5425   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5426      << " %u32vec2_01 %u32vec2_01\n";
5427   CompileSuccessfully(GenerateKernelCode(ss.str()));
5428   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5429 }
5430 
5431 TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
5432   const std::string ext_inst_name = GetParam();
5433   const std::string body =
5434       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
5435 
5436   CompileSuccessfully(GenerateKernelCode(body));
5437   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5438   EXPECT_THAT(
5439       getDiagnosticString(),
5440       HasSubstr(
5441           "OpenCL.std " + ext_inst_name +
5442           ": expected Result Type to be a 32-bit int scalar or vector type"));
5443 }
5444 
5445 TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
5446   const std::string ext_inst_name = GetParam();
5447   const std::string body =
5448       "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
5449 
5450   CompileSuccessfully(GenerateKernelCode(body));
5451   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5452   EXPECT_THAT(
5453       getDiagnosticString(),
5454       HasSubstr(
5455           "OpenCL.std " + ext_inst_name +
5456           ": expected Result Type to be a 32-bit int scalar or vector type"));
5457 }
5458 
5459 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
5460   const std::string ext_inst_name = GetParam();
5461   const std::string body =
5462       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
5463 
5464   CompileSuccessfully(GenerateKernelCode(body));
5465   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5466   EXPECT_THAT(
5467       getDiagnosticString(),
5468       HasSubstr("OpenCL.std " + ext_inst_name +
5469                 ": expected types of all operands to be equal to Result Type"));
5470 }
5471 
5472 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
5473   const std::string ext_inst_name = GetParam();
5474   const std::string body =
5475       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
5476 
5477   CompileSuccessfully(GenerateKernelCode(body));
5478   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5479   EXPECT_THAT(
5480       getDiagnosticString(),
5481       HasSubstr("OpenCL.std " + ext_inst_name +
5482                 ": expected types of all operands to be equal to Result Type"));
5483 }
5484 
5485 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
5486   const std::string ext_inst_name = GetParam();
5487   const std::string body =
5488       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
5489 
5490   CompileSuccessfully(GenerateKernelCode(body));
5491   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5492   EXPECT_THAT(
5493       getDiagnosticString(),
5494       HasSubstr("OpenCL.std " + ext_inst_name +
5495                 ": expected types of all operands to be equal to Result Type"));
5496 }
5497 
5498 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
5499   const std::string ext_inst_name = GetParam();
5500   const std::string body =
5501       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
5502 
5503   CompileSuccessfully(GenerateKernelCode(body));
5504   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5505   EXPECT_THAT(
5506       getDiagnosticString(),
5507       HasSubstr("OpenCL.std " + ext_inst_name +
5508                 ": expected types of all operands to be equal to Result Type"));
5509 }
5510 
5511 INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
5512                          ::testing::ValuesIn(std::vector<std::string>{
5513                              "s_mul24",
5514                              "u_mul24",
5515                          }));
5516 
5517 TEST_P(ValidateOpenCLStdUMad24Like, Success) {
5518   const std::string ext_inst_name = GetParam();
5519   std::ostringstream ss;
5520   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5521      << " %u32_0 %u32_1 %u32_2\n";
5522   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5523      << " %u32_0 %u32_1 %u32_2\n";
5524   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5525      << " %u32_0 %u32_1 %u32_2\n";
5526   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5527      << " %u32_0 %u32_1 %u32_2\n";
5528   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5529      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5530   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5531      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5532   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5533      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5534   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5535      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5536   CompileSuccessfully(GenerateKernelCode(ss.str()));
5537   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5538 }
5539 
5540 TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
5541   const std::string ext_inst_name = GetParam();
5542   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5543                            " %u32_0 %u32_0 %u32_1\n";
5544 
5545   CompileSuccessfully(GenerateKernelCode(body));
5546   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5547   EXPECT_THAT(
5548       getDiagnosticString(),
5549       HasSubstr(
5550           "OpenCL.std " + ext_inst_name +
5551           ": expected Result Type to be a 32-bit int scalar or vector type"));
5552 }
5553 
5554 TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
5555   const std::string ext_inst_name = GetParam();
5556   const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
5557                            " %u64_0 %u64_0 %u64_1\n";
5558 
5559   CompileSuccessfully(GenerateKernelCode(body));
5560   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5561   EXPECT_THAT(
5562       getDiagnosticString(),
5563       HasSubstr(
5564           "OpenCL.std " + ext_inst_name +
5565           ": expected Result Type to be a 32-bit int scalar or vector type"));
5566 }
5567 
5568 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
5569   const std::string ext_inst_name = GetParam();
5570   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5571                            " %f32_0 %u32_0 %u32_1\n";
5572 
5573   CompileSuccessfully(GenerateKernelCode(body));
5574   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5575   EXPECT_THAT(
5576       getDiagnosticString(),
5577       HasSubstr("OpenCL.std " + ext_inst_name +
5578                 ": expected types of all operands to be equal to Result Type"));
5579 }
5580 
5581 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
5582   const std::string ext_inst_name = GetParam();
5583   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5584                            " %u32_0 %f32_0 %u32_1\n";
5585 
5586   CompileSuccessfully(GenerateKernelCode(body));
5587   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5588   EXPECT_THAT(
5589       getDiagnosticString(),
5590       HasSubstr("OpenCL.std " + ext_inst_name +
5591                 ": expected types of all operands to be equal to Result Type"));
5592 }
5593 
5594 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
5595   const std::string ext_inst_name = GetParam();
5596   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5597                            " %u32_0 %u32_0 %f32_1\n";
5598 
5599   CompileSuccessfully(GenerateKernelCode(body));
5600   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5601   EXPECT_THAT(
5602       getDiagnosticString(),
5603       HasSubstr("OpenCL.std " + ext_inst_name +
5604                 ": expected types of all operands to be equal to Result Type"));
5605 }
5606 
5607 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
5608   const std::string ext_inst_name = GetParam();
5609   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5610                            " %f32_0 %u32_0 %u64_1\n";
5611 
5612   CompileSuccessfully(GenerateKernelCode(body));
5613   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5614   EXPECT_THAT(
5615       getDiagnosticString(),
5616       HasSubstr("OpenCL.std " + ext_inst_name +
5617                 ": expected types of all operands to be equal to Result Type"));
5618 }
5619 
5620 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
5621   const std::string ext_inst_name = GetParam();
5622   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5623                            " %u32_0 %f32_0 %u64_1\n";
5624 
5625   CompileSuccessfully(GenerateKernelCode(body));
5626   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5627   EXPECT_THAT(
5628       getDiagnosticString(),
5629       HasSubstr("OpenCL.std " + ext_inst_name +
5630                 ": expected types of all operands to be equal to Result Type"));
5631 }
5632 
5633 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
5634   const std::string ext_inst_name = GetParam();
5635   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5636                            " %u32_0 %u32_0 %u64_1\n";
5637 
5638   CompileSuccessfully(GenerateKernelCode(body));
5639   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5640   EXPECT_THAT(
5641       getDiagnosticString(),
5642       HasSubstr("OpenCL.std " + ext_inst_name +
5643                 ": expected types of all operands to be equal to Result Type"));
5644 }
5645 
5646 INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
5647                          ::testing::ValuesIn(std::vector<std::string>{
5648                              "s_mad24",
5649                              "u_mad24",
5650                          }));
5651 
5652 TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
5653   const std::string body = R"(
5654 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
5655 %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
5656 )";
5657 
5658   CompileSuccessfully(GenerateKernelCode(body));
5659   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5660 }
5661 
5662 TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
5663   const std::string body = R"(
5664 %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
5665 )";
5666 
5667   CompileSuccessfully(GenerateKernelCode(body));
5668   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5669   EXPECT_THAT(getDiagnosticString(),
5670               HasSubstr("OpenCL.std cross: "
5671                         "expected Result Type to be a float vector type"));
5672 }
5673 
5674 TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
5675   const std::string body = R"(
5676 %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
5677 )";
5678 
5679   CompileSuccessfully(GenerateKernelCode(body));
5680   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5681   EXPECT_THAT(getDiagnosticString(),
5682               HasSubstr("OpenCL.std cross: "
5683                         "expected Result Type to have 3 or 4 components"));
5684 }
5685 
5686 TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
5687   const std::string body = R"(
5688 %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
5689 )";
5690 
5691   CompileSuccessfully(GenerateKernelCode(body));
5692   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5693   EXPECT_THAT(getDiagnosticString(),
5694               HasSubstr("OpenCL.std cross: "
5695                         "expected operand X type to be equal to Result Type"));
5696 }
5697 
5698 TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
5699   const std::string body = R"(
5700 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
5701 )";
5702 
5703   CompileSuccessfully(GenerateKernelCode(body));
5704   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5705   EXPECT_THAT(getDiagnosticString(),
5706               HasSubstr("OpenCL.std cross: "
5707                         "expected operand Y type to be equal to Result Type"));
5708 }
5709 
5710 TEST_P(ValidateOpenCLStdLengthLike, Success) {
5711   const std::string ext_inst_name = GetParam();
5712   std::ostringstream ss;
5713   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
5714   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
5715      << " %f32vec4_0123\n";
5716 
5717   CompileSuccessfully(GenerateKernelCode(ss.str()));
5718   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5719 }
5720 
5721 TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
5722   const std::string ext_inst_name = GetParam();
5723   const std::string body =
5724       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
5725 
5726   CompileSuccessfully(GenerateKernelCode(body));
5727   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5728   EXPECT_THAT(getDiagnosticString(),
5729               HasSubstr("OpenCL.std " + ext_inst_name +
5730                         ": "
5731                         "expected Result Type to be a float scalar type"));
5732 }
5733 
5734 TEST_P(ValidateOpenCLStdLengthLike, IntX) {
5735   const std::string ext_inst_name = GetParam();
5736   const std::string body =
5737       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
5738 
5739   CompileSuccessfully(GenerateKernelCode(body));
5740   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5741   EXPECT_THAT(getDiagnosticString(),
5742               HasSubstr("OpenCL.std " + ext_inst_name +
5743                         ": "
5744                         "expected operand P to be a float scalar or vector"));
5745 }
5746 
5747 TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
5748   const std::string ext_inst_name = GetParam();
5749   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5750                            " %f32vec8_01010101\n";
5751 
5752   CompileSuccessfully(GenerateKernelCode(body));
5753   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5754   EXPECT_THAT(
5755       getDiagnosticString(),
5756       HasSubstr("OpenCL.std " + ext_inst_name +
5757                 ": "
5758                 "expected operand P to have no more than 4 components"));
5759 }
5760 
5761 TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
5762   const std::string ext_inst_name = GetParam();
5763   const std::string body =
5764       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
5765 
5766   CompileSuccessfully(GenerateKernelCode(body));
5767   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5768   EXPECT_THAT(getDiagnosticString(),
5769               HasSubstr("OpenCL.std " + ext_inst_name +
5770                         ": "
5771                         "expected operand P component type to be equal to "
5772                         "Result Type"));
5773 }
5774 
5775 INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
5776                          ::testing::ValuesIn(std::vector<std::string>{
5777                              "length",
5778                              "fast_length",
5779                          }));
5780 
5781 TEST_P(ValidateOpenCLStdDistanceLike, Success) {
5782   const std::string ext_inst_name = GetParam();
5783   std::ostringstream ss;
5784   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5785      << " %f32vec2_01 %f32vec2_01\n";
5786   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
5787      << " %f32vec4_0123 %f32vec4_1234\n";
5788   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
5789      << " %f32_0 %f32_1\n";
5790 
5791   CompileSuccessfully(GenerateKernelCode(ss.str()));
5792   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5793 }
5794 
5795 TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
5796   const std::string ext_inst_name = GetParam();
5797   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5798                            " %f32vec2_01 %f32vec2_12\n";
5799 
5800   CompileSuccessfully(GenerateKernelCode(body));
5801   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5802   EXPECT_THAT(getDiagnosticString(),
5803               HasSubstr("OpenCL.std " + ext_inst_name +
5804                         ": "
5805                         "expected Result Type to be a float scalar type"));
5806 }
5807 
5808 TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
5809   const std::string ext_inst_name = GetParam();
5810   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5811                            " %u32vec2_01 %f32vec2_12\n";
5812 
5813   CompileSuccessfully(GenerateKernelCode(body));
5814   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5815   EXPECT_THAT(
5816       getDiagnosticString(),
5817       HasSubstr("OpenCL.std " + ext_inst_name +
5818                 ": "
5819                 "expected operand P0 to be of float scalar or vector type"));
5820 }
5821 
5822 TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
5823   const std::string ext_inst_name = GetParam();
5824   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5825                            " %f32vec8_01010101 %f32vec8_01010101\n";
5826 
5827   CompileSuccessfully(GenerateKernelCode(body));
5828   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5829   EXPECT_THAT(
5830       getDiagnosticString(),
5831       HasSubstr("OpenCL.std " + ext_inst_name +
5832                 ": "
5833                 "expected operand P0 to have no more than 4 components"));
5834 }
5835 
5836 TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
5837   const std::string ext_inst_name = GetParam();
5838   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5839                            " %f64vec2_01 %f32vec2_12\n";
5840 
5841   CompileSuccessfully(GenerateKernelCode(body));
5842   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5843   EXPECT_THAT(
5844       getDiagnosticString(),
5845       HasSubstr(
5846           "OpenCL.std " + ext_inst_name +
5847           ": "
5848           "expected operand P0 component type to be equal to Result Type"));
5849 }
5850 
5851 TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
5852   const std::string ext_inst_name = GetParam();
5853   const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
5854                            " %f64vec2_01 %f32vec2_12\n";
5855 
5856   CompileSuccessfully(GenerateKernelCode(body));
5857   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5858   EXPECT_THAT(getDiagnosticString(),
5859               HasSubstr("OpenCL.std " + ext_inst_name +
5860                         ": "
5861                         "expected operands P0 and P1 to be of the same type"));
5862 }
5863 
5864 INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
5865                          ::testing::ValuesIn(std::vector<std::string>{
5866                              "distance",
5867                              "fast_distance",
5868                          }));
5869 
5870 TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
5871   const std::string ext_inst_name = GetParam();
5872   std::ostringstream ss;
5873   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5874      << " %f32vec2_01\n";
5875   ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
5876      << " %f32vec4_0123\n";
5877   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
5878 
5879   CompileSuccessfully(GenerateKernelCode(ss.str()));
5880   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5881 }
5882 
5883 TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
5884   const std::string ext_inst_name = GetParam();
5885   const std::string body =
5886       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
5887 
5888   CompileSuccessfully(GenerateKernelCode(body));
5889   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5890   EXPECT_THAT(
5891       getDiagnosticString(),
5892       HasSubstr("OpenCL.std " + ext_inst_name +
5893                 ": "
5894                 "expected Result Type to be a float scalar or vector type"));
5895 }
5896 
5897 TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
5898   const std::string ext_inst_name = GetParam();
5899   const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
5900                            ext_inst_name + " %f32vec8_01010101\n";
5901 
5902   CompileSuccessfully(GenerateKernelCode(body));
5903   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5904   EXPECT_THAT(
5905       getDiagnosticString(),
5906       HasSubstr("OpenCL.std " + ext_inst_name +
5907                 ": "
5908                 "expected Result Type to have no more than 4 components"));
5909 }
5910 
5911 TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
5912   const std::string ext_inst_name = GetParam();
5913   const std::string body =
5914       "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
5915 
5916   CompileSuccessfully(GenerateKernelCode(body));
5917   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5918   EXPECT_THAT(getDiagnosticString(),
5919               HasSubstr("OpenCL.std " + ext_inst_name +
5920                         ": "
5921                         "expected operand P type to be equal to Result Type"));
5922 }
5923 
5924 INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
5925                          ::testing::ValuesIn(std::vector<std::string>{
5926                              "normalize",
5927                              "fast_normalize",
5928                          }));
5929 
5930 TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
5931   const std::string body = R"(
5932 %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
5933 %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
5934 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
5935 %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
5936 %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
5937 )";
5938 
5939   CompileSuccessfully(GenerateKernelCode(body));
5940   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5941 }
5942 
5943 TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
5944   const std::string body = R"(
5945 %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
5946 )";
5947 
5948   CompileSuccessfully(GenerateKernelCode(body));
5949   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5950   EXPECT_THAT(
5951       getDiagnosticString(),
5952       HasSubstr(
5953           "OpenCL.std bitselect: "
5954           "expected Result Type to be an int or float scalar or vector type"));
5955 }
5956 
5957 TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
5958   const std::string body = R"(
5959 %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
5960 )";
5961 
5962   CompileSuccessfully(GenerateKernelCode(body));
5963   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5964   EXPECT_THAT(
5965       getDiagnosticString(),
5966       HasSubstr("OpenCL.std bitselect: "
5967                 "expected types of all operands to be equal to Result Type"));
5968 }
5969 
5970 TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
5971   const std::string body = R"(
5972 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
5973 )";
5974 
5975   CompileSuccessfully(GenerateKernelCode(body));
5976   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5977   EXPECT_THAT(
5978       getDiagnosticString(),
5979       HasSubstr("OpenCL.std bitselect: "
5980                 "expected types of all operands to be equal to Result Type"));
5981 }
5982 
5983 TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
5984   const std::string body = R"(
5985 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
5986 )";
5987 
5988   CompileSuccessfully(GenerateKernelCode(body));
5989   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5990   EXPECT_THAT(
5991       getDiagnosticString(),
5992       HasSubstr("OpenCL.std bitselect: "
5993                 "expected types of all operands to be equal to Result Type"));
5994 }
5995 
5996 TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
5997   const std::string body = R"(
5998 %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
5999 %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
6000 %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
6001 %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6002 %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
6003 )";
6004 
6005   CompileSuccessfully(GenerateKernelCode(body));
6006   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6007 }
6008 
6009 TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
6010   const std::string body = R"(
6011 %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
6012 )";
6013 
6014   CompileSuccessfully(GenerateKernelCode(body));
6015   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6016   EXPECT_THAT(
6017       getDiagnosticString(),
6018       HasSubstr(
6019           "OpenCL.std select: "
6020           "expected Result Type to be an int or float scalar or vector type"));
6021 }
6022 
6023 TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
6024   const std::string body = R"(
6025 %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
6026 )";
6027 
6028   CompileSuccessfully(GenerateKernelCode(body));
6029   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6030   EXPECT_THAT(getDiagnosticString(),
6031               HasSubstr("OpenCL.std select: "
6032                         "expected operand A type to be equal to Result Type"));
6033 }
6034 
6035 TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
6036   const std::string body = R"(
6037 %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
6038 )";
6039 
6040   CompileSuccessfully(GenerateKernelCode(body));
6041   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6042   EXPECT_THAT(getDiagnosticString(),
6043               HasSubstr("OpenCL.std select: "
6044                         "expected operand B type to be equal to Result Type"));
6045 }
6046 
6047 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
6048   const std::string body = R"(
6049 %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
6050 )";
6051 
6052   CompileSuccessfully(GenerateKernelCode(body));
6053   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6054   EXPECT_THAT(getDiagnosticString(),
6055               HasSubstr("OpenCL.std select: "
6056                         "expected operand C to be an int scalar or vector"));
6057 }
6058 
6059 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
6060   const std::string body = R"(
6061 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
6062 )";
6063 
6064   CompileSuccessfully(GenerateKernelCode(body));
6065   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6066   EXPECT_THAT(getDiagnosticString(),
6067               HasSubstr("OpenCL.std select: "
6068                         "expected operand C to have the same number of "
6069                         "components as Result Type"));
6070 }
6071 
6072 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
6073   const std::string body = R"(
6074 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
6075 )";
6076 
6077   CompileSuccessfully(GenerateKernelCode(body));
6078   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6079   EXPECT_THAT(
6080       getDiagnosticString(),
6081       HasSubstr(
6082           "OpenCL.std select: "
6083           "expected operand C to have the same bit width as Result Type"));
6084 }
6085 
6086 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
6087   const std::string ext_inst_name = GetParam();
6088   const std::string rounding_mode =
6089       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6090 
6091   std::ostringstream ss;
6092   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6093   if (std::string::npos == ext_inst_name.find("halfn")) {
6094     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6095        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6096     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6097        << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
6098   } else {
6099     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6100        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6101     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6102        << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
6103     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6104        << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
6105   }
6106 
6107   CompileSuccessfully(GenerateKernelCode(ss.str()));
6108   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6109 }
6110 
6111 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
6112   const std::string ext_inst_name = GetParam();
6113   const std::string rounding_mode =
6114       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6115 
6116   std::ostringstream ss;
6117   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6118   if (std::string::npos == ext_inst_name.find("halfn")) {
6119     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6120        << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
6121     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6122        << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
6123   } else {
6124     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6125        << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
6126     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6127        << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
6128     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6129        << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
6130   }
6131 
6132   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6133   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6134 }
6135 
6136 TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
6137   const std::string ext_inst_name = GetParam();
6138   const std::string rounding_mode =
6139       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6140 
6141   std::ostringstream ss;
6142   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6143   if (std::string::npos == ext_inst_name.find("halfn")) {
6144     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6145        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6146   } else {
6147     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6148        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6149   }
6150 
6151   CompileSuccessfully(GenerateKernelCode(ss.str()));
6152   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6153   EXPECT_THAT(getDiagnosticString(),
6154               HasSubstr("OpenCL.std " + ext_inst_name +
6155                         ": expected Result Type to be void"));
6156 }
6157 
6158 TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
6159   const std::string ext_inst_name = GetParam();
6160   const std::string rounding_mode =
6161       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6162 
6163   std::ostringstream ss;
6164   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6165   if (std::string::npos == ext_inst_name.find("halfn")) {
6166     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6167        << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6168     CompileSuccessfully(GenerateKernelCode(ss.str()));
6169     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6170     EXPECT_THAT(getDiagnosticString(),
6171                 HasSubstr("OpenCL.std " + ext_inst_name +
6172                           ": expected Data to be a 32 or 64-bit float scalar"));
6173   } else {
6174     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6175        << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
6176     CompileSuccessfully(GenerateKernelCode(ss.str()));
6177     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6178     EXPECT_THAT(getDiagnosticString(),
6179                 HasSubstr("OpenCL.std " + ext_inst_name +
6180                           ": expected Data to be a 32 or 64-bit float vector"));
6181   }
6182 }
6183 
6184 TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
6185   const std::string ext_inst_name = GetParam();
6186   const std::string rounding_mode =
6187       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6188 
6189   std::ostringstream ss;
6190   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6191   if (std::string::npos == ext_inst_name.find("halfn")) {
6192     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6193        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6194   } else {
6195     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6196        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6197   }
6198 
6199   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6200   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6201   EXPECT_THAT(getDiagnosticString(),
6202               HasSubstr("OpenCL.std " + ext_inst_name +
6203                         " can only be used with physical addressing models"));
6204 }
6205 
6206 TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
6207   const std::string ext_inst_name = GetParam();
6208   const std::string rounding_mode =
6209       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6210 
6211   std::ostringstream ss;
6212   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6213   if (std::string::npos == ext_inst_name.find("halfn")) {
6214     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6215        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6216   } else {
6217     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6218        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6219   }
6220 
6221   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6222   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6223   EXPECT_THAT(
6224       getDiagnosticString(),
6225       HasSubstr("OpenCL.std " + ext_inst_name +
6226                 ": "
6227                 "expected operand Offset to be of type size_t (64-bit integer "
6228                 "for the addressing model used in the module)"));
6229 }
6230 
6231 TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
6232   const std::string ext_inst_name = GetParam();
6233   const std::string rounding_mode =
6234       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6235 
6236   std::ostringstream ss;
6237   if (std::string::npos == ext_inst_name.find("halfn")) {
6238     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6239        << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
6240   } else {
6241     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6242        << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
6243   }
6244 
6245   CompileSuccessfully(GenerateKernelCode(ss.str()));
6246   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6247   EXPECT_THAT(getDiagnosticString(),
6248               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
6249 }
6250 
6251 TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
6252   const std::string ext_inst_name = GetParam();
6253   const std::string rounding_mode =
6254       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6255 
6256   std::ostringstream ss;
6257   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6258         "%f16vec8_uniform_constant %u32_1\n";
6259   if (std::string::npos == ext_inst_name.find("halfn")) {
6260     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6261        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6262   } else {
6263     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6264        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6265   }
6266 
6267   CompileSuccessfully(GenerateKernelCode(ss.str()));
6268   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6269   EXPECT_THAT(getDiagnosticString(),
6270               HasSubstr("OpenCL.std " + ext_inst_name +
6271                         ": expected operand P storage class to be Generic, "
6272                         "CrossWorkgroup, Workgroup or Function"));
6273 }
6274 
6275 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
6276   const std::string ext_inst_name = GetParam();
6277   const std::string rounding_mode =
6278       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6279 
6280   std::ostringstream ss;
6281   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
6282   if (std::string::npos == ext_inst_name.find("halfn")) {
6283     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6284        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6285   } else {
6286     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6287        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6288   }
6289 
6290   CompileSuccessfully(GenerateKernelCode(ss.str()));
6291   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6292   EXPECT_THAT(
6293       getDiagnosticString(),
6294       HasSubstr("OpenCL.std " + ext_inst_name +
6295                 ": expected operand P data type to be 16-bit float scalar"));
6296 }
6297 
6298 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
6299   const std::string ext_inst_name = GetParam();
6300   const std::string rounding_mode =
6301       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6302 
6303   std::ostringstream ss;
6304   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6305   if (std::string::npos == ext_inst_name.find("halfn")) {
6306     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6307        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6308   } else {
6309     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6310        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6311   }
6312 
6313   CompileSuccessfully(GenerateKernelCode(ss.str()));
6314   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6315   EXPECT_THAT(
6316       getDiagnosticString(),
6317       HasSubstr("OpenCL.std " + ext_inst_name +
6318                 ": expected operand P data type to be 16-bit float scalar"));
6319 }
6320 
6321 INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
6322                          ::testing::ValuesIn(std::vector<std::string>{
6323                              "vstore_half",
6324                              "vstore_half_r",
6325                              "vstore_halfn",
6326                              "vstore_halfn_r",
6327                              "vstorea_halfn",
6328                              "vstorea_halfn_r",
6329                          }));
6330 
6331 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
6332   const std::string ext_inst_name = GetParam();
6333 
6334   std::ostringstream ss;
6335   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6336   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6337      << " %u32_1 %ptr 2\n";
6338   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
6339      << " %u32_1 %ptr 3\n";
6340   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
6341      << " %u32_1 %ptr 4\n";
6342 
6343   CompileSuccessfully(GenerateKernelCode(ss.str()));
6344   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6345 }
6346 
6347 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
6348   const std::string ext_inst_name = GetParam();
6349 
6350   std::ostringstream ss;
6351   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6352   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6353      << " %u64_1 %ptr 2\n";
6354   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
6355      << " %u64_1 %ptr 3\n";
6356   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
6357      << " %u64_1 %ptr 4\n";
6358 
6359   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6360   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6361 }
6362 
6363 TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
6364   const std::string ext_inst_name = GetParam();
6365 
6366   std::ostringstream ss;
6367   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6368   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6369      << " %u32_1 %ptr 1\n";
6370 
6371   CompileSuccessfully(GenerateKernelCode(ss.str()));
6372   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6373   EXPECT_THAT(getDiagnosticString(),
6374               HasSubstr("OpenCL.std " + ext_inst_name +
6375                         ": expected Result Type to be a float vector type"));
6376 }
6377 
6378 TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
6379   const std::string ext_inst_name = GetParam();
6380 
6381   std::ostringstream ss;
6382   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6383   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6384      << " %u32_1 %ptr 2\n";
6385 
6386   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6387   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6388   EXPECT_THAT(getDiagnosticString(),
6389               HasSubstr("OpenCL.std " + ext_inst_name +
6390                         " can only be used with physical addressing models"));
6391 }
6392 
6393 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
6394   const std::string ext_inst_name = GetParam();
6395 
6396   std::ostringstream ss;
6397   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6398   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6399      << " %u64_1 %ptr 2\n";
6400 
6401   CompileSuccessfully(GenerateKernelCode(ss.str()));
6402   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6403   EXPECT_THAT(
6404       getDiagnosticString(),
6405       HasSubstr("OpenCL.std " + ext_inst_name +
6406                 ": expected operand Offset to be of type size_t (32-bit "
6407                 "integer for the addressing model used in the module)"));
6408 }
6409 
6410 TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
6411   const std::string ext_inst_name = GetParam();
6412 
6413   std::ostringstream ss;
6414   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6415      << " %u32_1 %f16_ptr_workgroup 2\n";
6416 
6417   CompileSuccessfully(GenerateKernelCode(ss.str()));
6418   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6419   EXPECT_THAT(getDiagnosticString(),
6420               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
6421 }
6422 
6423 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
6424   const std::string ext_inst_name = GetParam();
6425 
6426   std::ostringstream ss;
6427   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
6428   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6429      << " %u32_1 %ptr 2\n";
6430 
6431   CompileSuccessfully(GenerateKernelCode(ss.str()));
6432   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6433   EXPECT_THAT(
6434       getDiagnosticString(),
6435       HasSubstr("OpenCL.std " + ext_inst_name +
6436                 ": expected operand P storage class to be UniformConstant, "
6437                 "Generic, CrossWorkgroup, Workgroup or Function"));
6438 }
6439 
6440 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
6441   const std::string ext_inst_name = GetParam();
6442 
6443   std::ostringstream ss;
6444   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
6445   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6446      << " %u32_1 %ptr 2\n";
6447 
6448   CompileSuccessfully(GenerateKernelCode(ss.str()));
6449   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6450   EXPECT_THAT(
6451       getDiagnosticString(),
6452       HasSubstr("OpenCL.std " + ext_inst_name +
6453                 ": expected operand P data type to be 16-bit float scalar"));
6454 }
6455 
6456 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
6457   const std::string ext_inst_name = GetParam();
6458 
6459   std::ostringstream ss;
6460   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6461   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6462      << " %u32_1 %ptr 2\n";
6463 
6464   CompileSuccessfully(GenerateKernelCode(ss.str()));
6465   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6466   EXPECT_THAT(
6467       getDiagnosticString(),
6468       HasSubstr("OpenCL.std " + ext_inst_name +
6469                 ": expected operand P data type to be 16-bit float scalar"));
6470 }
6471 
6472 TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
6473   const std::string ext_inst_name = GetParam();
6474 
6475   std::ostringstream ss;
6476   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6477   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6478      << " %u32_1 %ptr 3\n";
6479 
6480   CompileSuccessfully(GenerateKernelCode(ss.str()));
6481   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6482   EXPECT_THAT(getDiagnosticString(),
6483               HasSubstr("OpenCL.std " + ext_inst_name +
6484                         ": expected literal N to be equal to the number of "
6485                         "components of Result Type"));
6486 }
6487 
6488 INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
6489                          ::testing::ValuesIn(std::vector<std::string>{
6490                              "vload_halfn",
6491                              "vloada_halfn",
6492                          }));
6493 
6494 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
6495   std::ostringstream ss;
6496   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6497         "%f32vec8_uniform_constant %u32_1\n";
6498   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
6499   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
6500   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
6501 
6502   CompileSuccessfully(GenerateKernelCode(ss.str()));
6503   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6504 }
6505 
6506 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
6507   std::ostringstream ss;
6508   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
6509         "%u32vec8_uniform_constant %u32_1\n";
6510   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
6511   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
6512   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
6513 
6514   CompileSuccessfully(GenerateKernelCode(ss.str()));
6515   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6516 }
6517 
6518 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
6519   std::ostringstream ss;
6520   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6521         "%f32vec8_uniform_constant %u32_1\n";
6522   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
6523   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
6524   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
6525 
6526   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6527   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6528 }
6529 
6530 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
6531   std::ostringstream ss;
6532   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
6533         "%u32vec8_uniform_constant %u32_1\n";
6534   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
6535   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
6536   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
6537 
6538   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6539   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6540 }
6541 
6542 TEST_F(ValidateExtInst, VLoadNWrongResultType) {
6543   std::ostringstream ss;
6544   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6545         "%f32vec8_uniform_constant %u32_1\n";
6546   ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
6547 
6548   CompileSuccessfully(GenerateKernelCode(ss.str()));
6549   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6550   EXPECT_THAT(
6551       getDiagnosticString(),
6552       HasSubstr("OpenCL.std vloadn: "
6553                 "expected Result Type to be an int or float vector type"));
6554 }
6555 
6556 TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
6557   std::ostringstream ss;
6558   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6559         "%f32vec8_uniform_constant %u32_1\n";
6560   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
6561 
6562   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6563   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6564   EXPECT_THAT(getDiagnosticString(),
6565               HasSubstr("OpenCL.std vloadn can only be used with physical "
6566                         "addressing models"));
6567 }
6568 
6569 TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
6570   std::ostringstream ss;
6571   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6572         "%f32vec8_uniform_constant %u32_1\n";
6573   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
6574 
6575   CompileSuccessfully(GenerateKernelCode(ss.str()));
6576   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6577   EXPECT_THAT(
6578       getDiagnosticString(),
6579       HasSubstr(
6580           "OpenCL.std vloadn: expected operand Offset to be of type size_t "
6581           "(32-bit integer for the addressing model used in the module)"));
6582 }
6583 
6584 TEST_F(ValidateExtInst, VLoadNPNotPointer) {
6585   std::ostringstream ss;
6586   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
6587         "%f32_ptr_uniform_constant 2\n";
6588 
6589   CompileSuccessfully(GenerateKernelCode(ss.str()));
6590   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6591   EXPECT_THAT(getDiagnosticString(),
6592               HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
6593                         "type"));
6594 }
6595 
6596 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
6597   std::ostringstream ss;
6598   ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
6599   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
6600 
6601   CompileSuccessfully(GenerateKernelCode(ss.str()));
6602   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6603   EXPECT_THAT(getDiagnosticString(),
6604               HasSubstr("OpenCL.std vloadn: expected operand P storage class "
6605                         "to be UniformConstant, Generic, CrossWorkgroup, "
6606                         "Workgroup or Function"));
6607 }
6608 
6609 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
6610   std::ostringstream ss;
6611   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6612         "%f32vec8_uniform_constant %u32_1\n";
6613   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
6614 
6615   CompileSuccessfully(GenerateKernelCode(ss.str()));
6616   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6617   EXPECT_THAT(getDiagnosticString(),
6618               HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
6619                         "equal to component type of Result Type"));
6620 }
6621 
6622 TEST_F(ValidateExtInst, VLoadNWrongN) {
6623   std::ostringstream ss;
6624   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6625         "%f32vec8_uniform_constant %u32_1\n";
6626   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
6627 
6628   CompileSuccessfully(GenerateKernelCode(ss.str()));
6629   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6630   EXPECT_THAT(getDiagnosticString(),
6631               HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
6632                         "the number of components of Result Type"));
6633 }
6634 
6635 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
6636   std::ostringstream ss;
6637   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6638         "%f16vec8_uniform_constant %u32_1\n";
6639   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
6640   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
6641 
6642   CompileSuccessfully(GenerateKernelCode(ss.str()));
6643   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6644 }
6645 
6646 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
6647   std::ostringstream ss;
6648   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6649         "%f16vec8_uniform_constant %u32_1\n";
6650   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
6651   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
6652 
6653   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6654   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6655 }
6656 
6657 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
6658   std::ostringstream ss;
6659   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6660         "%f16vec8_uniform_constant %u32_1\n";
6661   ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
6662 
6663   CompileSuccessfully(GenerateKernelCode(ss.str()));
6664   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6665   EXPECT_THAT(getDiagnosticString(),
6666               HasSubstr("OpenCL.std vload_half: "
6667                         "expected Result Type to be a float scalar type"));
6668 }
6669 
6670 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
6671   std::ostringstream ss;
6672   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6673         "%f16vec8_uniform_constant %u32_1\n";
6674   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
6675 
6676   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6677   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6678   EXPECT_THAT(getDiagnosticString(),
6679               HasSubstr("OpenCL.std vload_half can only be used with physical "
6680                         "addressing models"));
6681 }
6682 
6683 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
6684   std::ostringstream ss;
6685   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6686         "%f16vec8_uniform_constant %u32_1\n";
6687   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
6688 
6689   CompileSuccessfully(GenerateKernelCode(ss.str()));
6690   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6691   EXPECT_THAT(
6692       getDiagnosticString(),
6693       HasSubstr(
6694           "OpenCL.std vload_half: expected operand Offset to be of type size_t "
6695           "(32-bit integer for the addressing model used in the module)"));
6696 }
6697 
6698 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
6699   std::ostringstream ss;
6700   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
6701         "%f16_ptr_uniform_constant\n";
6702 
6703   CompileSuccessfully(GenerateKernelCode(ss.str()));
6704   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6705   EXPECT_THAT(getDiagnosticString(),
6706               HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
6707                         "type"));
6708 }
6709 
6710 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
6711   std::ostringstream ss;
6712   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
6713   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
6714 
6715   CompileSuccessfully(GenerateKernelCode(ss.str()));
6716   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6717   EXPECT_THAT(
6718       getDiagnosticString(),
6719       HasSubstr(
6720           "OpenCL.std vload_half: expected operand P storage class to be "
6721           "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
6722 }
6723 
6724 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
6725   std::ostringstream ss;
6726   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
6727         "%u32vec8_uniform_constant %u32_1\n";
6728   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
6729 
6730   CompileSuccessfully(GenerateKernelCode(ss.str()));
6731   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6732   EXPECT_THAT(getDiagnosticString(),
6733               HasSubstr("OpenCL.std vload_half: expected operand P data type "
6734                         "to be 16-bit float scalar"));
6735 }
6736 
6737 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
6738   std::ostringstream ss;
6739   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
6740         "%f32vec8_uniform_constant %u32_1\n";
6741   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
6742 
6743   CompileSuccessfully(GenerateKernelCode(ss.str()));
6744   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6745   EXPECT_THAT(getDiagnosticString(),
6746               HasSubstr("OpenCL.std vload_half: expected operand P data type "
6747                         "to be 16-bit float scalar"));
6748 }
6749 
6750 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
6751   std::ostringstream ss;
6752   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6753   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6754   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
6755   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
6756         "%ptr_g\n";
6757 
6758   CompileSuccessfully(GenerateKernelCode(ss.str()));
6759   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6760 }
6761 
6762 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
6763   std::ostringstream ss;
6764   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6765   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6766   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
6767   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
6768         "%ptr_g\n";
6769 
6770   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6771   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6772 }
6773 
6774 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
6775   std::ostringstream ss;
6776   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
6777   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
6778   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
6779   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
6780         "%ptr_g\n";
6781 
6782   CompileSuccessfully(GenerateKernelCode(ss.str()));
6783   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6784 }
6785 
6786 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
6787   std::ostringstream ss;
6788   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
6789   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
6790   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
6791   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
6792         "%ptr_g\n";
6793 
6794   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6795   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6796 }
6797 
6798 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
6799   std::ostringstream ss;
6800   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6801   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6802   ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
6803 
6804   CompileSuccessfully(GenerateKernelCode(ss.str()));
6805   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6806   EXPECT_THAT(getDiagnosticString(),
6807               HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
6808 }
6809 
6810 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
6811   std::ostringstream ss;
6812   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6813   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6814   ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
6815 
6816   CompileSuccessfully(GenerateKernelCode(ss.str()));
6817   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6818   EXPECT_THAT(
6819       getDiagnosticString(),
6820       HasSubstr(
6821           "OpenCL.std vstoren: expected Data to be an int or float vector"));
6822 }
6823 
6824 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
6825   std::ostringstream ss;
6826   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6827   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6828   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
6829 
6830   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6831   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6832   EXPECT_THAT(getDiagnosticString(),
6833               HasSubstr("OpenCL.std vstoren can only be used with physical "
6834                         "addressing models"));
6835 }
6836 
6837 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
6838   std::ostringstream ss;
6839   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6840   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6841   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
6842 
6843   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6844   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6845   EXPECT_THAT(
6846       getDiagnosticString(),
6847       HasSubstr(
6848           "OpenCL.std vstoren: expected operand Offset to be of type size_t "
6849           "(64-bit integer for the addressing model used in the module)"));
6850 }
6851 
6852 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
6853   std::ostringstream ss;
6854   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
6855         "%f32_ptr_generic\n";
6856 
6857   CompileSuccessfully(GenerateKernelCode(ss.str()));
6858   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6859   EXPECT_THAT(getDiagnosticString(),
6860               HasSubstr("Operand 127[%_ptr_Generic_float] cannot be a type"));
6861 }
6862 
6863 TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
6864   std::ostringstream ss;
6865   ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
6866         "%f32vec8_uniform_constant %u32_1\n";
6867   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
6868 
6869   CompileSuccessfully(GenerateKernelCode(ss.str()));
6870   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6871   EXPECT_THAT(
6872       getDiagnosticString(),
6873       HasSubstr("OpenCL.std vstoren: expected operand P storage class "
6874                 "to be Generic, CrossWorkgroup, Workgroup or Function"));
6875 }
6876 
6877 TEST_F(ValidateExtInst, VStorePWrongDataType) {
6878   std::ostringstream ss;
6879   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6880   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
6881   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
6882 
6883   CompileSuccessfully(GenerateKernelCode(ss.str()));
6884   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6885   EXPECT_THAT(getDiagnosticString(),
6886               HasSubstr("OpenCL.std vstoren: expected operand P data type to "
6887                         "be equal to the type of operand Data components"));
6888 }
6889 
6890 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
6891   const std::string body = R"(
6892 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
6893 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
6894 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
6895 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
6896 )";
6897 
6898   CompileSuccessfully(GenerateKernelCode(body));
6899   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6900 }
6901 
6902 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
6903   const std::string body = R"(
6904 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
6905 )";
6906 
6907   CompileSuccessfully(GenerateKernelCode(body));
6908   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6909   EXPECT_THAT(
6910       getDiagnosticString(),
6911       HasSubstr("OpenCL.std shuffle: "
6912                 "expected Result Type to be an int or float vector type"));
6913 }
6914 
6915 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
6916   const std::string body = R"(
6917 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
6918 )";
6919 
6920   CompileSuccessfully(GenerateKernelCode(body));
6921   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6922   EXPECT_THAT(
6923       getDiagnosticString(),
6924       HasSubstr("OpenCL.std shuffle: "
6925                 "expected Result Type to have 2, 4, 8 or 16 components"));
6926 }
6927 
6928 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
6929   const std::string body = R"(
6930 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
6931 )";
6932 
6933   CompileSuccessfully(GenerateKernelCode(body));
6934   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6935   EXPECT_THAT(getDiagnosticString(),
6936               HasSubstr("OpenCL.std shuffle: "
6937                         "expected operand X to be an int or float vector"));
6938 }
6939 
6940 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
6941   const std::string body = R"(
6942 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
6943 )";
6944 
6945   CompileSuccessfully(GenerateKernelCode(body));
6946   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6947   EXPECT_THAT(getDiagnosticString(),
6948               HasSubstr("OpenCL.std shuffle: "
6949                         "expected operand X to have 2, 4, 8 or 16 components"));
6950 }
6951 
6952 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
6953   const std::string body = R"(
6954 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
6955 )";
6956 
6957   CompileSuccessfully(GenerateKernelCode(body));
6958   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6959   EXPECT_THAT(
6960       getDiagnosticString(),
6961       HasSubstr(
6962           "OpenCL.std shuffle: "
6963           "expected operand X and Result Type to have equal component types"));
6964 }
6965 
6966 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
6967   const std::string body = R"(
6968 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
6969 )";
6970 
6971   CompileSuccessfully(GenerateKernelCode(body));
6972   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6973   EXPECT_THAT(getDiagnosticString(),
6974               HasSubstr("OpenCL.std shuffle: "
6975                         "expected operand Shuffle Mask to be an int vector"));
6976 }
6977 
6978 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
6979   const std::string body = R"(
6980 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
6981 )";
6982 
6983   CompileSuccessfully(GenerateKernelCode(body));
6984   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6985   EXPECT_THAT(getDiagnosticString(),
6986               HasSubstr("OpenCL.std shuffle: "
6987                         "expected operand Shuffle Mask to have the same number "
6988                         "of components as Result Type"));
6989 }
6990 
6991 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
6992   const std::string body = R"(
6993 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
6994 )";
6995 
6996   CompileSuccessfully(GenerateKernelCode(body));
6997   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6998   EXPECT_THAT(getDiagnosticString(),
6999               HasSubstr("OpenCL.std shuffle: "
7000                         "expected operand Shuffle Mask components to have the "
7001                         "same bit width as Result Type components"));
7002 }
7003 
7004 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
7005   const std::string body = R"(
7006 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7007 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
7008 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
7009 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
7010 )";
7011 
7012   CompileSuccessfully(GenerateKernelCode(body));
7013   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7014 }
7015 
7016 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
7017   const std::string body = R"(
7018 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7019 )";
7020 
7021   CompileSuccessfully(GenerateKernelCode(body));
7022   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7023   EXPECT_THAT(
7024       getDiagnosticString(),
7025       HasSubstr("OpenCL.std shuffle2: "
7026                 "expected Result Type to be an int or float vector type"));
7027 }
7028 
7029 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
7030   const std::string body = R"(
7031 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
7032 )";
7033 
7034   CompileSuccessfully(GenerateKernelCode(body));
7035   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7036   EXPECT_THAT(
7037       getDiagnosticString(),
7038       HasSubstr("OpenCL.std shuffle2: "
7039                 "expected Result Type to have 2, 4, 8 or 16 components"));
7040 }
7041 
7042 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
7043   const std::string body = R"(
7044 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
7045 )";
7046 
7047   CompileSuccessfully(GenerateKernelCode(body));
7048   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7049   EXPECT_THAT(getDiagnosticString(),
7050               HasSubstr("OpenCL.std shuffle2: "
7051                         "expected operand X to be an int or float vector"));
7052 }
7053 
7054 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
7055   const std::string body = R"(
7056 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
7057 )";
7058 
7059   CompileSuccessfully(GenerateKernelCode(body));
7060   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7061   EXPECT_THAT(getDiagnosticString(),
7062               HasSubstr("OpenCL.std shuffle2: "
7063                         "expected operands X and Y to be of the same type"));
7064 }
7065 
7066 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
7067   const std::string body = R"(
7068 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
7069 )";
7070 
7071   CompileSuccessfully(GenerateKernelCode(body));
7072   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7073   EXPECT_THAT(getDiagnosticString(),
7074               HasSubstr("OpenCL.std shuffle2: "
7075                         "expected operand X to have 2, 4, 8 or 16 components"));
7076 }
7077 
7078 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
7079   const std::string body = R"(
7080 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7081 )";
7082 
7083   CompileSuccessfully(GenerateKernelCode(body));
7084   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7085   EXPECT_THAT(
7086       getDiagnosticString(),
7087       HasSubstr(
7088           "OpenCL.std shuffle2: "
7089           "expected operand X and Result Type to have equal component types"));
7090 }
7091 
7092 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
7093   const std::string body = R"(
7094 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
7095 )";
7096 
7097   CompileSuccessfully(GenerateKernelCode(body));
7098   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7099   EXPECT_THAT(getDiagnosticString(),
7100               HasSubstr("OpenCL.std shuffle2: "
7101                         "expected operand Shuffle Mask to be an int vector"));
7102 }
7103 
7104 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
7105   const std::string body = R"(
7106 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7107 )";
7108 
7109   CompileSuccessfully(GenerateKernelCode(body));
7110   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7111   EXPECT_THAT(getDiagnosticString(),
7112               HasSubstr("OpenCL.std shuffle2: "
7113                         "expected operand Shuffle Mask to have the same number "
7114                         "of components as Result Type"));
7115 }
7116 
7117 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
7118   const std::string body = R"(
7119 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7120 )";
7121 
7122   CompileSuccessfully(GenerateKernelCode(body));
7123   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7124   EXPECT_THAT(getDiagnosticString(),
7125               HasSubstr("OpenCL.std shuffle2: "
7126                         "expected operand Shuffle Mask components to have the "
7127                         "same bit width as Result Type components"));
7128 }
7129 
7130 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
7131   const std::string body = R"(
7132 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7133 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7134 )";
7135 
7136   CompileSuccessfully(GenerateKernelCode(body));
7137   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7138 }
7139 
7140 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
7141   const std::string body = R"(
7142 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7143 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
7144 )";
7145 
7146   CompileSuccessfully(GenerateKernelCode(body));
7147   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7148   EXPECT_THAT(
7149       getDiagnosticString(),
7150       HasSubstr(
7151           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7152 }
7153 
7154 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
7155   const std::string body = R"(
7156 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7157 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
7158 )";
7159 
7160   CompileSuccessfully(GenerateKernelCode(body));
7161   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7162   EXPECT_THAT(
7163       getDiagnosticString(),
7164       HasSubstr(
7165           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7166 }
7167 
7168 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
7169   const std::string body = R"(
7170 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
7171 )";
7172 
7173   CompileSuccessfully(GenerateKernelCode(body));
7174   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7175   EXPECT_THAT(getDiagnosticString(),
7176               HasSubstr("Operand 137[%_ptr_UniformConstant_uchar] cannot be a "
7177                         "type"));
7178 }
7179 
7180 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
7181   const std::string body = R"(
7182 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7183 %format = OpBitcast %u8_ptr_generic %format_const
7184 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7185 )";
7186 
7187   CompileSuccessfully(GenerateKernelCode(body));
7188   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7189   EXPECT_THAT(getDiagnosticString(),
7190               HasSubstr("OpenCL.std printf: expected Format storage class to "
7191                         "be UniformConstant"));
7192 }
7193 
7194 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
7195   const std::string body = R"(
7196 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
7197 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7198 )";
7199 
7200   CompileSuccessfully(GenerateKernelCode(body));
7201   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7202   EXPECT_THAT(
7203       getDiagnosticString(),
7204       HasSubstr(
7205           "OpenCL.std printf: expected Format data type to be 8-bit int"));
7206 }
7207 
7208 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
7209   const std::string body = R"(
7210 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7211 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7212 )";
7213 
7214   CompileSuccessfully(GenerateKernelCode(body));
7215   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7216 }
7217 
7218 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
7219   const std::string body = R"(
7220 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7221 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
7222 )";
7223 
7224   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
7225   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7226 }
7227 
7228 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
7229   const std::string body = R"(
7230 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
7231 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7232 )";
7233 
7234   CompileSuccessfully(GenerateKernelCode(body));
7235   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7236 }
7237 
7238 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
7239   const std::string body = R"(
7240 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
7241 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7242 )";
7243 
7244   CompileSuccessfully(GenerateKernelCode(body));
7245   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7246 }
7247 
7248 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
7249   const std::string body = R"(
7250 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7251 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
7252 )";
7253 
7254   CompileSuccessfully(GenerateKernelCode(body));
7255   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7256   EXPECT_THAT(
7257       getDiagnosticString(),
7258       HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
7259 }
7260 
7261 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
7262   const std::string body = R"(
7263 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
7264 )";
7265 
7266   CompileSuccessfully(GenerateKernelCode(body));
7267   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7268   EXPECT_THAT(getDiagnosticString(),
7269               HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
7270                         "type"));
7271 }
7272 
7273 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
7274   const std::string body = R"(
7275 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7276 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7277 )";
7278 
7279   CompileSuccessfully(GenerateKernelCode(body));
7280   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7281   EXPECT_THAT(getDiagnosticString(),
7282               HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
7283                         "class to be CrossWorkgroup"));
7284 }
7285 
7286 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
7287   const std::string body = R"(
7288 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
7289 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7290 )";
7291 
7292   CompileSuccessfully(GenerateKernelCode(body));
7293   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7294   EXPECT_THAT(getDiagnosticString(),
7295               HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
7296                         "or float scalar or vector"));
7297 }
7298 
7299 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
7300   const std::string body = R"(
7301 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7302 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7303 )";
7304 
7305   CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
7306   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7307   EXPECT_THAT(getDiagnosticString(),
7308               HasSubstr("OpenCL.std prefetch can only be used with physical "
7309                         "addressing models"));
7310 }
7311 
7312 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
7313   const std::string body = R"(
7314 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
7315 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7316 )";
7317 
7318   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
7319   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7320   EXPECT_THAT(getDiagnosticString(),
7321               HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
7322                         "be of type size_t (64-bit integer for the addressing "
7323                         "model used in the module)"));
7324 }
7325 
7326 TEST_P(ValidateOpenCLStdFractLike, Success) {
7327   const std::string ext_inst_name = GetParam();
7328   std::ostringstream ss;
7329   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
7330   ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
7331   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7332      << " %f32_0 %var_f32\n";
7333   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7334      << " %f32vec2_01 %var_f32vec2\n";
7335 
7336   CompileSuccessfully(GenerateKernelCode(ss.str()));
7337   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7338 }
7339 
7340 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
7341   const std::string ext_inst_name = GetParam();
7342   std::ostringstream ss;
7343   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
7344   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
7345      << " %f32_0 %var_f32\n";
7346 
7347   CompileSuccessfully(GenerateKernelCode(ss.str()));
7348   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7349   EXPECT_THAT(
7350       getDiagnosticString(),
7351       HasSubstr("OpenCL.std " + ext_inst_name +
7352                 ": expected Result Type to be a float scalar or vector type"));
7353 }
7354 
7355 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
7356   const std::string ext_inst_name = GetParam();
7357   std::ostringstream ss;
7358   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
7359   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7360      << " %f64_0 %var_f32\n";
7361 
7362   CompileSuccessfully(GenerateKernelCode(ss.str()));
7363   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7364   EXPECT_THAT(
7365       getDiagnosticString(),
7366       HasSubstr("OpenCL.std " + ext_inst_name +
7367                 ": expected type of operand X to be equal to Result Type"));
7368 }
7369 
7370 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
7371   const std::string ext_inst_name = GetParam();
7372   std::ostringstream ss;
7373   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
7374   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7375      << " %f32_0 %f32_1\n";
7376 
7377   CompileSuccessfully(GenerateKernelCode(ss.str()));
7378   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7379   EXPECT_THAT(getDiagnosticString(),
7380               HasSubstr("OpenCL.std " + ext_inst_name +
7381                         ": expected the last operand to be a pointer"));
7382 }
7383 
7384 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
7385   const std::string ext_inst_name = GetParam();
7386   std::ostringstream ss;
7387   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7388         "%f32vec8_uniform_constant %u32_1\n";
7389   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
7390 
7391   CompileSuccessfully(GenerateKernelCode(ss.str()));
7392   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7393   EXPECT_THAT(getDiagnosticString(),
7394               HasSubstr("OpenCL.std " + ext_inst_name +
7395                         ": expected storage class of the pointer to be "
7396                         "Generic, CrossWorkgroup, Workgroup or Function"));
7397 }
7398 
7399 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
7400   const std::string ext_inst_name = GetParam();
7401   std::ostringstream ss;
7402   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
7403   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7404      << " %f32_0 %var_u32\n";
7405 
7406   CompileSuccessfully(GenerateKernelCode(ss.str()));
7407   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7408   EXPECT_THAT(
7409       getDiagnosticString(),
7410       HasSubstr(
7411           "OpenCL.std " + ext_inst_name +
7412           ": expected data type of the pointer to be equal to Result Type"));
7413 }
7414 
7415 INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
7416                          ::testing::ValuesIn(std::vector<std::string>{
7417                              "fract",
7418                              "modf",
7419                              "sincos",
7420                          }));
7421 
7422 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
7423   const std::string body = R"(
7424 %var_u32 = OpVariable %u32_ptr_function Function
7425 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
7426 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
7427 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
7428 )";
7429 
7430   CompileSuccessfully(GenerateKernelCode(body));
7431   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7432 }
7433 
7434 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
7435   const std::string body = R"(
7436 %var_u32 = OpVariable %u32_ptr_function Function
7437 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
7438 )";
7439 
7440   CompileSuccessfully(GenerateKernelCode(body));
7441   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7442   EXPECT_THAT(
7443       getDiagnosticString(),
7444       HasSubstr("OpenCL.std remquo: "
7445                 "expected Result Type to be a float scalar or vector type"));
7446 }
7447 
7448 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
7449   const std::string body = R"(
7450 %var_u32 = OpVariable %f32_ptr_function Function
7451 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
7452 )";
7453 
7454   CompileSuccessfully(GenerateKernelCode(body));
7455   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7456   EXPECT_THAT(
7457       getDiagnosticString(),
7458       HasSubstr("OpenCL.std remquo: "
7459                 "expected type of operand X to be equal to Result Type"));
7460 }
7461 
7462 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
7463   const std::string body = R"(
7464 %var_u32 = OpVariable %f32_ptr_function Function
7465 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
7466 )";
7467 
7468   CompileSuccessfully(GenerateKernelCode(body));
7469   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7470   EXPECT_THAT(
7471       getDiagnosticString(),
7472       HasSubstr("OpenCL.std remquo: "
7473                 "expected type of operand Y to be equal to Result Type"));
7474 }
7475 
7476 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
7477   const std::string body = R"(
7478 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
7479 )";
7480 
7481   CompileSuccessfully(GenerateKernelCode(body));
7482   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7483   EXPECT_THAT(getDiagnosticString(),
7484               HasSubstr("OpenCL.std remquo: "
7485                         "expected the last operand to be a pointer"));
7486 }
7487 
7488 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
7489   const std::string body = R"(
7490 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
7491 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
7492 )";
7493 
7494   CompileSuccessfully(GenerateKernelCode(body));
7495   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7496   EXPECT_THAT(getDiagnosticString(),
7497               HasSubstr("OpenCL.std remquo: "
7498                         "expected storage class of the pointer to be Generic, "
7499                         "CrossWorkgroup, Workgroup or Function"));
7500 }
7501 
7502 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
7503   const std::string body = R"(
7504 %var_f32 = OpVariable %f32_ptr_function Function
7505 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
7506 )";
7507 
7508   CompileSuccessfully(GenerateKernelCode(body));
7509   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7510   EXPECT_THAT(getDiagnosticString(),
7511               HasSubstr("OpenCL.std remquo: "
7512                         "expected data type of the pointer to be a 32-bit int "
7513                         "scalar or vector type"));
7514 }
7515 
7516 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
7517   const std::string body = R"(
7518 %var_u64 = OpVariable %u64_ptr_function Function
7519 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
7520 )";
7521   CompileSuccessfully(GenerateKernelCode(body));
7522   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7523   EXPECT_THAT(getDiagnosticString(),
7524               HasSubstr("OpenCL.std remquo: "
7525                         "expected data type of the pointer to be a 32-bit int "
7526                         "scalar or vector type"));
7527 }
7528 
7529 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
7530   const std::string body = R"(
7531 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
7532 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
7533 )";
7534 
7535   CompileSuccessfully(GenerateKernelCode(body));
7536   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7537   EXPECT_THAT(
7538       getDiagnosticString(),
7539       HasSubstr("OpenCL.std remquo: "
7540                 "expected data type of the pointer to have the same number "
7541                 "of components as Result Type"));
7542 }
7543 
7544 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
7545   const std::string ext_inst_name = GetParam();
7546   std::ostringstream ss;
7547   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
7548   ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
7549   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7550      << " %f32_0 %var_u32\n";
7551   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7552      << " %f32vec2_01 %var_u32vec2\n";
7553 
7554   CompileSuccessfully(GenerateKernelCode(ss.str()));
7555   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7556 }
7557 
7558 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
7559   const std::string ext_inst_name = GetParam();
7560   std::ostringstream ss;
7561   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
7562   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
7563      << " %f32_0 %var_u32\n";
7564 
7565   CompileSuccessfully(GenerateKernelCode(ss.str()));
7566   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7567   EXPECT_THAT(
7568       getDiagnosticString(),
7569       HasSubstr("OpenCL.std " + ext_inst_name +
7570                 ": expected Result Type to be a float scalar or vector type"));
7571 }
7572 
7573 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
7574   const std::string ext_inst_name = GetParam();
7575   std::ostringstream ss;
7576   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
7577   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7578      << " %f64_0 %var_u32\n";
7579 
7580   CompileSuccessfully(GenerateKernelCode(ss.str()));
7581   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7582   EXPECT_THAT(
7583       getDiagnosticString(),
7584       HasSubstr("OpenCL.std " + ext_inst_name +
7585                 ": expected type of operand X to be equal to Result Type"));
7586 }
7587 
7588 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
7589   const std::string ext_inst_name = GetParam();
7590   std::ostringstream ss;
7591   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7592      << " %f32_0 %u32_1\n";
7593 
7594   CompileSuccessfully(GenerateKernelCode(ss.str()));
7595   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7596   EXPECT_THAT(getDiagnosticString(),
7597               HasSubstr("OpenCL.std " + ext_inst_name +
7598                         ": expected the last operand to be a pointer"));
7599 }
7600 
7601 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
7602   const std::string ext_inst_name = GetParam();
7603   std::ostringstream ss;
7604   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7605         "%f32vec8_uniform_constant %u32_1\n";
7606   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
7607 
7608   CompileSuccessfully(GenerateKernelCode(ss.str()));
7609   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7610   EXPECT_THAT(getDiagnosticString(),
7611               HasSubstr("OpenCL.std " + ext_inst_name +
7612                         ": expected storage class of the pointer to be "
7613                         "Generic, CrossWorkgroup, Workgroup or Function"));
7614 }
7615 
7616 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
7617   const std::string ext_inst_name = GetParam();
7618   std::ostringstream ss;
7619   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
7620   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7621      << " %f32_0 %var_f32\n";
7622 
7623   CompileSuccessfully(GenerateKernelCode(ss.str()));
7624   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7625   EXPECT_THAT(getDiagnosticString(),
7626               HasSubstr("OpenCL.std " + ext_inst_name +
7627                         ": expected data type of the pointer to be a 32-bit "
7628                         "int scalar or vector type"));
7629 }
7630 
7631 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
7632   const std::string ext_inst_name = GetParam();
7633   std::ostringstream ss;
7634   ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
7635   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7636      << " %f32_0 %var_u64\n";
7637 
7638   CompileSuccessfully(GenerateKernelCode(ss.str()));
7639   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7640   EXPECT_THAT(getDiagnosticString(),
7641               HasSubstr("OpenCL.std " + ext_inst_name +
7642                         ": expected data type of the pointer to be a 32-bit "
7643                         "int scalar or vector type"));
7644 }
7645 
7646 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
7647   const std::string ext_inst_name = GetParam();
7648   std::ostringstream ss;
7649   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
7650   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7651      << " %f32vec2_01 %var_u32\n";
7652 
7653   CompileSuccessfully(GenerateKernelCode(ss.str()));
7654   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7655   EXPECT_THAT(getDiagnosticString(),
7656               HasSubstr("OpenCL.std " + ext_inst_name +
7657                         ": expected data type of the pointer to have the same "
7658                         "number of components as Result Type"));
7659 }
7660 
7661 INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
7662                          ::testing::ValuesIn(std::vector<std::string>{
7663                              "frexp",
7664                              "lgamma_r",
7665                          }));
7666 
7667 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
7668   const std::string body = R"(
7669 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
7670 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
7671 )";
7672 
7673   CompileSuccessfully(GenerateKernelCode(body));
7674   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7675 }
7676 
7677 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
7678   const std::string body = R"(
7679 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
7680 )";
7681 
7682   CompileSuccessfully(GenerateKernelCode(body));
7683   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7684   EXPECT_THAT(
7685       getDiagnosticString(),
7686       HasSubstr(
7687           "OpenCL.std ilogb: "
7688           "expected Result Type to be a 32-bit int scalar or vector type"));
7689 }
7690 
7691 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
7692   const std::string body = R"(
7693 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
7694 )";
7695 
7696   CompileSuccessfully(GenerateKernelCode(body));
7697   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7698   EXPECT_THAT(getDiagnosticString(),
7699               HasSubstr("OpenCL.std ilogb: "
7700                         "expected operand X to be a float scalar or vector"));
7701 }
7702 
7703 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
7704   const std::string body = R"(
7705 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
7706 )";
7707 
7708   CompileSuccessfully(GenerateKernelCode(body));
7709   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7710   EXPECT_THAT(getDiagnosticString(),
7711               HasSubstr("OpenCL.std ilogb: "
7712                         "expected operand X to have the same number of "
7713                         "components as Result Type"));
7714 }
7715 
7716 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
7717   const std::string body = R"(
7718 %val1 = OpExtInst %f32 %extinst nan %u32_3
7719 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
7720 )";
7721 
7722   CompileSuccessfully(GenerateKernelCode(body));
7723   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7724 }
7725 
7726 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
7727   const std::string body = R"(
7728 %val1 = OpExtInst %u32 %extinst nan %u32_3
7729 )";
7730 
7731   CompileSuccessfully(GenerateKernelCode(body));
7732   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7733   EXPECT_THAT(
7734       getDiagnosticString(),
7735       HasSubstr("OpenCL.std nan: "
7736                 "expected Result Type to be a float scalar or vector type"));
7737 }
7738 
7739 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
7740   const std::string body = R"(
7741 %val1 = OpExtInst %f32 %extinst nan %f32_3
7742 )";
7743 
7744   CompileSuccessfully(GenerateKernelCode(body));
7745   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7746   EXPECT_THAT(getDiagnosticString(),
7747               HasSubstr("OpenCL.std nan: "
7748                         "expected Nancode to be an int scalar or vector type"));
7749 }
7750 
7751 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
7752   const std::string body = R"(
7753 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
7754 )";
7755 
7756   CompileSuccessfully(GenerateKernelCode(body));
7757   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7758   EXPECT_THAT(getDiagnosticString(),
7759               HasSubstr("OpenCL.std nan: "
7760                         "expected Nancode to have the same number of "
7761                         "components as Result Type"));
7762 }
7763 
7764 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
7765   const std::string body = R"(
7766 %val1 = OpExtInst %f64 %extinst nan %u32_2
7767 )";
7768 
7769   CompileSuccessfully(GenerateKernelCode(body));
7770   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7771   EXPECT_THAT(
7772       getDiagnosticString(),
7773       HasSubstr("OpenCL.std nan: "
7774                 "expected Nancode to have the same bit width as Result Type"));
7775 }
7776 
7777 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
7778   const std::string ext_inst_name = GetParam();
7779   std::ostringstream ss;
7780   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7781      << " %f32_0 %u32_1\n";
7782   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7783      << " %f32vec2_12 %u32vec2_12\n";
7784 
7785   CompileSuccessfully(GenerateKernelCode(ss.str()));
7786   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7787 }
7788 
7789 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
7790   const std::string ext_inst_name = GetParam();
7791   std::ostringstream ss;
7792   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
7793      << " %f32_0 %u32_1\n";
7794 
7795   CompileSuccessfully(GenerateKernelCode(ss.str()));
7796   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7797   EXPECT_THAT(
7798       getDiagnosticString(),
7799       HasSubstr("OpenCL.std " + ext_inst_name +
7800                 ": expected Result Type to be a float scalar or vector type"));
7801 }
7802 
7803 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
7804   const std::string ext_inst_name = GetParam();
7805   std::ostringstream ss;
7806   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7807      << " %u32_0 %u32_1\n";
7808 
7809   CompileSuccessfully(GenerateKernelCode(ss.str()));
7810   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7811   EXPECT_THAT(
7812       getDiagnosticString(),
7813       HasSubstr("OpenCL.std " + ext_inst_name +
7814                 ": expected type of operand X to be equal to Result Type"));
7815 }
7816 
7817 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
7818   const std::string ext_inst_name = GetParam();
7819   std::ostringstream ss;
7820   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7821      << " %f32_0 %f32_1\n";
7822 
7823   CompileSuccessfully(GenerateKernelCode(ss.str()));
7824   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7825   EXPECT_THAT(
7826       getDiagnosticString(),
7827       HasSubstr("OpenCL.std " + ext_inst_name +
7828                 ": expected the exponent to be a 32-bit int scalar or vector"));
7829 }
7830 
7831 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
7832   const std::string ext_inst_name = GetParam();
7833   std::ostringstream ss;
7834   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7835      << " %f32_0 %u64_1\n";
7836 
7837   CompileSuccessfully(GenerateKernelCode(ss.str()));
7838   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7839   EXPECT_THAT(
7840       getDiagnosticString(),
7841       HasSubstr("OpenCL.std " + ext_inst_name +
7842                 ": expected the exponent to be a 32-bit int scalar or vector"));
7843 }
7844 
7845 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
7846   const std::string ext_inst_name = GetParam();
7847   std::ostringstream ss;
7848   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7849      << " %f32_0 %u32vec2_01\n";
7850 
7851   CompileSuccessfully(GenerateKernelCode(ss.str()));
7852   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7853   EXPECT_THAT(getDiagnosticString(),
7854               HasSubstr("OpenCL.std " + ext_inst_name +
7855                         ": expected the exponent to have the same number of "
7856                         "components as Result Type"));
7857 }
7858 
7859 INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
7860                          ::testing::ValuesIn(std::vector<std::string>{
7861                              "ldexp",
7862                              "pown",
7863                              "rootn",
7864                          }));
7865 
7866 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
7867   const std::string ext_inst_name = GetParam();
7868   std::ostringstream ss;
7869   ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
7870   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
7871      << " %u16_1 %u16_2\n";
7872   ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
7873      << " %u32_1 %u32_2\n";
7874   ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
7875      << " %u32vec2_01 %u32vec2_01\n";
7876 
7877   CompileSuccessfully(GenerateKernelCode(ss.str()));
7878   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7879 }
7880 
7881 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
7882   const std::string ext_inst_name = GetParam();
7883   std::ostringstream ss;
7884   ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
7885      << " %u32_1 %u32_2\n";
7886 
7887   CompileSuccessfully(GenerateKernelCode(ss.str()));
7888   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7889   EXPECT_THAT(
7890       getDiagnosticString(),
7891       HasSubstr("OpenCL.std " + ext_inst_name +
7892                 ": expected Result Type to be an int scalar or vector type"));
7893 }
7894 
7895 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
7896   const std::string ext_inst_name = GetParam();
7897   std::ostringstream ss;
7898   ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
7899 
7900   CompileSuccessfully(GenerateKernelCode(ss.str()));
7901   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7902   EXPECT_THAT(
7903       getDiagnosticString(),
7904       HasSubstr(
7905           "OpenCL.std " + ext_inst_name +
7906           ": expected bit width of Result Type components to be 16, 32 or 64"));
7907 }
7908 
7909 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
7910   const std::string ext_inst_name = GetParam();
7911   std::ostringstream ss;
7912   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
7913      << " %u32_1 %u16_2\n";
7914 
7915   CompileSuccessfully(GenerateKernelCode(ss.str()));
7916   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7917   EXPECT_THAT(getDiagnosticString(),
7918               HasSubstr("OpenCL.std " + ext_inst_name +
7919                         ": expected Hi and Lo operands to have the same type"));
7920 }
7921 
7922 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
7923   const std::string ext_inst_name = GetParam();
7924   std::ostringstream ss;
7925   ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
7926      << " %u32_1 %u32_2\n";
7927 
7928   CompileSuccessfully(GenerateKernelCode(ss.str()));
7929   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7930   EXPECT_THAT(getDiagnosticString(),
7931               HasSubstr("OpenCL.std " + ext_inst_name +
7932                         ": expected Hi and Lo operands to have the same number "
7933                         "of components as Result Type"));
7934 }
7935 
7936 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
7937   const std::string ext_inst_name = GetParam();
7938   std::ostringstream ss;
7939   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
7940      << " %u16_1 %u16_2\n";
7941 
7942   CompileSuccessfully(GenerateKernelCode(ss.str()));
7943   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7944   EXPECT_THAT(
7945       getDiagnosticString(),
7946       HasSubstr("OpenCL.std " + ext_inst_name +
7947                 ": expected bit width of components of Hi and Lo operands to "
7948                 "be half of the bit width of components of Result Type"));
7949 }
7950 
7951 INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
7952                          ::testing::ValuesIn(std::vector<std::string>{
7953                              "u_upsample",
7954                              "s_upsample",
7955                          }));
7956 
7957 }  // namespace
7958 }  // namespace val
7959 }  // namespace spvtools
7960