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