• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions.
16 // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
17 // by standard SPIR-V).
18 
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 #include "gmock/gmock.h"
24 #include "test/unit_spirv.h"
25 #include "test/val/val_fixtures.h"
26 
27 namespace spvtools {
28 namespace val {
29 namespace {
30 
31 using ::testing::Eq;
32 using ::testing::HasSubstr;
33 using ::testing::Not;
34 
35 using ValidateExtInst = spvtest::ValidateBase<bool>;
36 using ValidateOldDebugInfo = spvtest::ValidateBase<std::string>;
37 using ValidateOpenCL100DebugInfo = spvtest::ValidateBase<std::string>;
38 using ValidateLocalDebugInfoOutOfFunction = spvtest::ValidateBase<std::string>;
39 using ValidateOpenCL100DebugInfoDebugTypedef =
40     spvtest::ValidateBase<std::pair<std::string, std::string>>;
41 using ValidateOpenCL100DebugInfoDebugTypeEnum =
42     spvtest::ValidateBase<std::pair<std::string, std::string>>;
43 using ValidateOpenCL100DebugInfoDebugTypeComposite =
44     spvtest::ValidateBase<std::pair<std::string, std::string>>;
45 using ValidateOpenCL100DebugInfoDebugTypeMember =
46     spvtest::ValidateBase<std::pair<std::string, std::string>>;
47 using ValidateOpenCL100DebugInfoDebugTypeInheritance =
48     spvtest::ValidateBase<std::pair<std::string, std::string>>;
49 using ValidateOpenCL100DebugInfoDebugFunction =
50     spvtest::ValidateBase<std::pair<std::string, std::string>>;
51 using ValidateOpenCL100DebugInfoDebugFunctionDeclaration =
52     spvtest::ValidateBase<std::pair<std::string, std::string>>;
53 using ValidateOpenCL100DebugInfoDebugLexicalBlock =
54     spvtest::ValidateBase<std::pair<std::string, std::string>>;
55 using ValidateOpenCL100DebugInfoDebugLocalVariable =
56     spvtest::ValidateBase<std::pair<std::string, std::string>>;
57 using 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, GlslStd450InterpolateAtCentroidInternalSuccess) {
5208   const std::string body = R"(
5209 %ld1  = OpLoad %f32 %f32_input
5210 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
5211 %ld2  = OpLoad %f32vec2 %f32vec2_input
5212 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
5213 )";
5214 
5215   CompileSuccessfully(
5216       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5217   getValidatorOptions()->before_hlsl_legalization = true;
5218   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5219 }
5220 
5221 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalInvalidDataF32) {
5222   const std::string body = R"(
5223 %ld1  = OpLoad %f32 %f32_input
5224 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
5225 )";
5226 
5227   CompileSuccessfully(
5228       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5229   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5230   EXPECT_THAT(getDiagnosticString(),
5231               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5232                         "expected Interpolant to be a pointer"));
5233 }
5234 
5235 TEST_F(ValidateExtInst,
5236        GlslStd450InterpolateAtCentroidInternalInvalidDataF32Vec2) {
5237   const std::string body = R"(
5238 %ld2  = OpLoad %f32vec2 %f32vec2_input
5239 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
5240 )";
5241 
5242   CompileSuccessfully(
5243       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5244   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5245   EXPECT_THAT(getDiagnosticString(),
5246               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5247                         "expected Interpolant to be a pointer"));
5248 }
5249 
5250 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
5251   const std::string body = R"(
5252 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5253 )";
5254 
5255   CompileSuccessfully(GenerateShaderCode(body));
5256   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5257   EXPECT_THAT(getDiagnosticString(),
5258               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5259                         "capability InterpolationFunction"));
5260 }
5261 
5262 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
5263   const std::string body = R"(
5264 %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
5265 )";
5266 
5267   CompileSuccessfully(
5268       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5269   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5270   EXPECT_THAT(getDiagnosticString(),
5271               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5272                         "expected Result Type to be a 32-bit float scalar "
5273                         "or vector type"));
5274 }
5275 
5276 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
5277   const std::string body = R"(
5278 %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
5279 )";
5280 
5281   CompileSuccessfully(
5282       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5283   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5284   EXPECT_THAT(getDiagnosticString(),
5285               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5286                         "expected Result Type to be a 32-bit float scalar "
5287                         "or vector type"));
5288 }
5289 
5290 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
5291   const std::string body = R"(
5292 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
5293 )";
5294 
5295   CompileSuccessfully(
5296       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5297   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5298   EXPECT_THAT(getDiagnosticString(),
5299               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5300                         "expected Interpolant to be a pointer"));
5301 }
5302 
5303 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
5304   const std::string body = R"(
5305 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
5306 )";
5307 
5308   CompileSuccessfully(
5309       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5310   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5311   EXPECT_THAT(getDiagnosticString(),
5312               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5313                         "expected Interpolant data type to be equal to "
5314                         "Result Type"));
5315 }
5316 
5317 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
5318   const std::string body = R"(
5319 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
5320 )";
5321 
5322   CompileSuccessfully(
5323       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5324   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5325   EXPECT_THAT(getDiagnosticString(),
5326               HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5327                         "expected Interpolant storage class to be Input"));
5328 }
5329 
5330 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
5331   const std::string body = R"(
5332 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5333 )";
5334 
5335   CompileSuccessfully(GenerateShaderCode(
5336       body, "OpCapability InterpolationFunction\n", "Vertex"));
5337   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5338   EXPECT_THAT(getDiagnosticString(),
5339               HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5340                         "Fragment execution model"));
5341 }
5342 
5343 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
5344   const std::string body = R"(
5345 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5346 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
5347 )";
5348 
5349   CompileSuccessfully(
5350       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5351   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5352 }
5353 
5354 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalSuccess) {
5355   const std::string body = R"(
5356 %ld1  = OpLoad %f32 %f32_input
5357 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
5358 %ld2  = OpLoad %f32vec2 %f32vec2_input
5359 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
5360 )";
5361 
5362   CompileSuccessfully(
5363       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5364   getValidatorOptions()->before_hlsl_legalization = true;
5365   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5366 }
5367 
5368 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalInvalidDataF32) {
5369   const std::string body = R"(
5370 %ld1  = OpLoad %f32 %f32_input
5371 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
5372 )";
5373 
5374   CompileSuccessfully(
5375       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5376   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5377   EXPECT_THAT(getDiagnosticString(),
5378               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5379                         "expected Interpolant to be a pointer"));
5380 }
5381 
5382 TEST_F(ValidateExtInst,
5383        GlslStd450InterpolateAtSampleInternalInvalidDataF32Vec2) {
5384   const std::string body = R"(
5385 %ld2  = OpLoad %f32vec2 %f32vec2_input
5386 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
5387 )";
5388 
5389   CompileSuccessfully(
5390       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5391   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5392   EXPECT_THAT(getDiagnosticString(),
5393               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5394                         "expected Interpolant to be a pointer"));
5395 }
5396 
5397 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
5398   const std::string body = R"(
5399 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5400 )";
5401 
5402   CompileSuccessfully(GenerateShaderCode(body));
5403   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5404   EXPECT_THAT(getDiagnosticString(),
5405               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5406                         "capability InterpolationFunction"));
5407 }
5408 
5409 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
5410   const std::string body = R"(
5411 %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
5412 )";
5413 
5414   CompileSuccessfully(
5415       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5416   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5417   EXPECT_THAT(getDiagnosticString(),
5418               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5419                         "expected Result Type to be a 32-bit float scalar "
5420                         "or vector type"));
5421 }
5422 
5423 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
5424   const std::string body = R"(
5425 %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
5426 )";
5427 
5428   CompileSuccessfully(
5429       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5430   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5431   EXPECT_THAT(getDiagnosticString(),
5432               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5433                         "expected Result Type to be a 32-bit float scalar "
5434                         "or vector type"));
5435 }
5436 
5437 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
5438   const std::string body = R"(
5439 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
5440 )";
5441 
5442   CompileSuccessfully(
5443       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5444   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5445   EXPECT_THAT(getDiagnosticString(),
5446               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5447                         "expected Interpolant to be a pointer"));
5448 }
5449 
5450 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
5451   const std::string body = R"(
5452 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
5453 )";
5454 
5455   CompileSuccessfully(
5456       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5457   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5458   EXPECT_THAT(getDiagnosticString(),
5459               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5460                         "expected Interpolant data type to be equal to "
5461                         "Result Type"));
5462 }
5463 
5464 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
5465   const std::string body = R"(
5466 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
5467 )";
5468 
5469   CompileSuccessfully(
5470       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5471   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5472   EXPECT_THAT(getDiagnosticString(),
5473               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5474                         "expected Interpolant storage class to be Input"));
5475 }
5476 
5477 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
5478   const std::string body = R"(
5479 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
5480 )";
5481 
5482   CompileSuccessfully(
5483       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5484   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5485   EXPECT_THAT(getDiagnosticString(),
5486               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5487                         "expected Sample to be 32-bit integer"));
5488 }
5489 
5490 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
5491   const std::string body = R"(
5492 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
5493 )";
5494 
5495   CompileSuccessfully(
5496       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5497   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5498   EXPECT_THAT(getDiagnosticString(),
5499               HasSubstr("GLSL.std.450 InterpolateAtSample: "
5500                         "expected Sample to be 32-bit integer"));
5501 }
5502 
5503 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
5504   const std::string body = R"(
5505 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5506 )";
5507 
5508   CompileSuccessfully(GenerateShaderCode(
5509       body, "OpCapability InterpolationFunction\n", "Vertex"));
5510   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5511   EXPECT_THAT(getDiagnosticString(),
5512               HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5513                         "Fragment execution model"));
5514 }
5515 
5516 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
5517   const std::string body = R"(
5518 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5519 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5520 )";
5521 
5522   CompileSuccessfully(
5523       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5524   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5525 }
5526 
5527 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalSuccess) {
5528   const std::string body = R"(
5529 %ld1  = OpLoad %f32 %f32_input
5530 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
5531 %ld2  = OpLoad %f32vec2 %f32vec2_input
5532 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
5533 )";
5534 
5535   CompileSuccessfully(
5536       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5537   getValidatorOptions()->before_hlsl_legalization = true;
5538   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5539 }
5540 
5541 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32) {
5542   const std::string body = R"(
5543 %ld1  = OpLoad %f32 %f32_input
5544 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
5545 )";
5546 
5547   CompileSuccessfully(
5548       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5549   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5550   EXPECT_THAT(getDiagnosticString(),
5551               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5552                         "expected Interpolant to be a pointer"));
5553 }
5554 
5555 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32Vec2) {
5556   const std::string body = R"(
5557 %ld2  = OpLoad %f32vec2 %f32vec2_input
5558 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
5559 )";
5560 
5561   CompileSuccessfully(
5562       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5563   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5564   EXPECT_THAT(getDiagnosticString(),
5565               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5566                         "expected Interpolant to be a pointer"));
5567 }
5568 
5569 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
5570   const std::string body = R"(
5571 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5572 )";
5573 
5574   CompileSuccessfully(GenerateShaderCode(body));
5575   ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5576   EXPECT_THAT(getDiagnosticString(),
5577               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5578                         "capability InterpolationFunction"));
5579 }
5580 
5581 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
5582   const std::string body = R"(
5583 %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5584 )";
5585 
5586   CompileSuccessfully(
5587       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5588   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5589   EXPECT_THAT(getDiagnosticString(),
5590               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5591                         "expected Result Type to be a 32-bit float scalar "
5592                         "or vector type"));
5593 }
5594 
5595 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
5596   const std::string body = R"(
5597 %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5598 )";
5599 
5600   CompileSuccessfully(
5601       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5602   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5603   EXPECT_THAT(getDiagnosticString(),
5604               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5605                         "expected Result Type to be a 32-bit float scalar "
5606                         "or vector type"));
5607 }
5608 
5609 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
5610   const std::string body = R"(
5611 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
5612 )";
5613 
5614   CompileSuccessfully(
5615       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5616   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5617   EXPECT_THAT(getDiagnosticString(),
5618               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5619                         "expected Interpolant to be a pointer"));
5620 }
5621 
5622 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
5623   const std::string body = R"(
5624 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5625 )";
5626 
5627   CompileSuccessfully(
5628       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5629   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5630   EXPECT_THAT(getDiagnosticString(),
5631               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5632                         "expected Interpolant data type to be equal to "
5633                         "Result Type"));
5634 }
5635 
5636 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
5637   const std::string body = R"(
5638 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
5639 )";
5640 
5641   CompileSuccessfully(
5642       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5643   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5644   EXPECT_THAT(getDiagnosticString(),
5645               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5646                         "expected Interpolant storage class to be Input"));
5647 }
5648 
5649 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
5650   const std::string body = R"(
5651 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
5652 )";
5653 
5654   CompileSuccessfully(
5655       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5656   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5657   EXPECT_THAT(getDiagnosticString(),
5658               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5659                         "expected Offset to be a vector of 2 32-bit floats"));
5660 }
5661 
5662 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
5663   const std::string body = R"(
5664 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
5665 )";
5666 
5667   CompileSuccessfully(
5668       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5669   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5670   EXPECT_THAT(getDiagnosticString(),
5671               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5672                         "expected Offset to be a vector of 2 32-bit floats"));
5673 }
5674 
5675 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
5676   const std::string body = R"(
5677 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
5678 )";
5679 
5680   CompileSuccessfully(
5681       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5682   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5683   EXPECT_THAT(getDiagnosticString(),
5684               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5685                         "expected Offset to be a vector of 2 32-bit floats"));
5686 }
5687 
5688 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
5689   const std::string body = R"(
5690 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
5691 )";
5692 
5693   CompileSuccessfully(
5694       GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5695   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5696   EXPECT_THAT(getDiagnosticString(),
5697               HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5698                         "expected Offset to be a vector of 2 32-bit floats"));
5699 }
5700 
5701 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
5702   const std::string body = R"(
5703 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5704 )";
5705 
5706   CompileSuccessfully(GenerateShaderCode(
5707       body, "OpCapability InterpolationFunction\n", "Vertex"));
5708   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5709   EXPECT_THAT(getDiagnosticString(),
5710               HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5711                         "Fragment execution model"));
5712 }
5713 
5714 TEST_P(ValidateOpenCLStdSqrtLike, Success) {
5715   const std::string ext_inst_name = GetParam();
5716   std::ostringstream ss;
5717   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
5718   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5719      << " %f32vec2_01\n";
5720   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
5721      << " %f32vec4_0123\n";
5722   ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
5723   CompileSuccessfully(GenerateKernelCode(ss.str()));
5724   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5725 }
5726 
5727 TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
5728   const std::string ext_inst_name = GetParam();
5729   const std::string body =
5730       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5731 
5732   CompileSuccessfully(GenerateKernelCode(body));
5733   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5734   EXPECT_THAT(getDiagnosticString(),
5735               HasSubstr("OpenCL.std " + ext_inst_name +
5736                         ": expected Result Type to be a float scalar "
5737                         "or vector type"));
5738 }
5739 
5740 TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
5741   const std::string ext_inst_name = GetParam();
5742   const std::string body =
5743       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5744 
5745   CompileSuccessfully(GenerateKernelCode(body));
5746   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5747   EXPECT_THAT(getDiagnosticString(),
5748               HasSubstr("OpenCL.std " + ext_inst_name +
5749                         ": expected types of all operands to be equal to "
5750                         "Result Type"));
5751 }
5752 
5753 INSTANTIATE_TEST_SUITE_P(
5754     AllSqrtLike, ValidateOpenCLStdSqrtLike,
5755     ::testing::ValuesIn(std::vector<std::string>{
5756         "acos",         "acosh",       "acospi",       "asin",
5757         "asinh",        "asinpi",      "atan",         "atanh",
5758         "atanpi",       "cbrt",        "ceil",         "cos",
5759         "cosh",         "cospi",       "erfc",         "erf",
5760         "exp",          "exp2",        "exp10",        "expm1",
5761         "fabs",         "floor",       "log",          "log2",
5762         "log10",        "log1p",       "logb",         "rint",
5763         "round",        "rsqrt",       "sin",          "sinh",
5764         "sinpi",        "sqrt",        "tan",          "tanh",
5765         "tanpi",        "tgamma",      "trunc",        "half_cos",
5766         "half_exp",     "half_exp2",   "half_exp10",   "half_log",
5767         "half_log2",    "half_log10",  "half_recip",   "half_rsqrt",
5768         "half_sin",     "half_sqrt",   "half_tan",     "lgamma",
5769         "native_cos",   "native_exp",  "native_exp2",  "native_exp10",
5770         "native_log",   "native_log2", "native_log10", "native_recip",
5771         "native_rsqrt", "native_sin",  "native_sqrt",  "native_tan",
5772         "degrees",      "radians",     "sign",
5773     }));
5774 
5775 TEST_P(ValidateOpenCLStdFMinLike, Success) {
5776   const std::string ext_inst_name = GetParam();
5777   std::ostringstream ss;
5778   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5779      << " %f32_0 %f32_1\n";
5780   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5781      << " %f32vec2_01 %f32vec2_12\n";
5782   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5783      << " %f64_0 %f64_0\n";
5784   CompileSuccessfully(GenerateKernelCode(ss.str()));
5785   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5786 }
5787 
5788 TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
5789   const std::string ext_inst_name = GetParam();
5790   const std::string body =
5791       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
5792 
5793   CompileSuccessfully(GenerateKernelCode(body));
5794   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5795   EXPECT_THAT(getDiagnosticString(),
5796               HasSubstr("OpenCL.std " + ext_inst_name +
5797                         ": expected Result Type to be a float scalar "
5798                         "or vector type"));
5799 }
5800 
5801 TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
5802   const std::string ext_inst_name = GetParam();
5803   const std::string body =
5804       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
5805 
5806   CompileSuccessfully(GenerateKernelCode(body));
5807   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5808   EXPECT_THAT(getDiagnosticString(),
5809               HasSubstr("OpenCL.std " + ext_inst_name +
5810                         ": expected types of all operands to be equal to "
5811                         "Result Type"));
5812 }
5813 
5814 TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
5815   const std::string ext_inst_name = GetParam();
5816   const std::string body =
5817       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
5818 
5819   CompileSuccessfully(GenerateKernelCode(body));
5820   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5821   EXPECT_THAT(getDiagnosticString(),
5822               HasSubstr("OpenCL.std " + ext_inst_name +
5823                         ": expected types of all operands to be equal to "
5824                         "Result Type"));
5825 }
5826 
5827 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
5828                          ::testing::ValuesIn(std::vector<std::string>{
5829                              "atan2",     "atan2pi",       "copysign",
5830                              "fdim",      "fmax",          "fmin",
5831                              "fmod",      "maxmag",        "minmag",
5832                              "hypot",     "nextafter",     "pow",
5833                              "powr",      "remainder",     "half_divide",
5834                              "half_powr", "native_divide", "native_powr",
5835                              "step",      "fmax_common",   "fmin_common",
5836                          }));
5837 
5838 TEST_P(ValidateOpenCLStdFClampLike, Success) {
5839   const std::string ext_inst_name = GetParam();
5840   std::ostringstream ss;
5841   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5842      << " %f32_0 %f32_1 %f32_2\n";
5843   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5844      << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
5845   ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5846      << " %f64_0 %f64_0 %f64_1\n";
5847   CompileSuccessfully(GenerateKernelCode(ss.str()));
5848   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5849 }
5850 
5851 TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
5852   const std::string ext_inst_name = GetParam();
5853   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5854                            " %f32_0 %f32_1 %f32_2\n";
5855 
5856   CompileSuccessfully(GenerateKernelCode(body));
5857   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5858   EXPECT_THAT(getDiagnosticString(),
5859               HasSubstr("OpenCL.std " + ext_inst_name +
5860                         ": expected Result Type to be a float scalar "
5861                         "or vector type"));
5862 }
5863 
5864 TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
5865   const std::string ext_inst_name = GetParam();
5866   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5867                            " %u32_0 %f32_0 %f32_1\n";
5868 
5869   CompileSuccessfully(GenerateKernelCode(body));
5870   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5871   EXPECT_THAT(getDiagnosticString(),
5872               HasSubstr("OpenCL.std " + ext_inst_name +
5873                         ": expected types of all operands to be equal to "
5874                         "Result Type"));
5875 }
5876 
5877 TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
5878   const std::string ext_inst_name = GetParam();
5879   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5880                            " %f32_0 %u32_0 %f32_1\n";
5881 
5882   CompileSuccessfully(GenerateKernelCode(body));
5883   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5884   EXPECT_THAT(getDiagnosticString(),
5885               HasSubstr("OpenCL.std " + ext_inst_name +
5886                         ": expected types of all operands to be equal to "
5887                         "Result Type"));
5888 }
5889 
5890 TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
5891   const std::string ext_inst_name = GetParam();
5892   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5893                            " %f32_1 %f32_0 %u32_2\n";
5894 
5895   CompileSuccessfully(GenerateKernelCode(body));
5896   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5897   EXPECT_THAT(getDiagnosticString(),
5898               HasSubstr("OpenCL.std " + ext_inst_name +
5899                         ": expected types of all operands to be equal to "
5900                         "Result Type"));
5901 }
5902 
5903 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
5904                          ::testing::ValuesIn(std::vector<std::string>{
5905                              "fma",
5906                              "mad",
5907                              "fclamp",
5908                              "mix",
5909                              "smoothstep",
5910                          }));
5911 
5912 TEST_P(ValidateOpenCLStdSAbsLike, Success) {
5913   const std::string ext_inst_name = GetParam();
5914   std::ostringstream ss;
5915   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5916   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5917   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5918   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5919   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5920      << " %u32vec2_01\n";
5921   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5922      << " %u32vec2_01\n";
5923   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5924      << " %u32vec2_01\n";
5925   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5926      << " %u32vec2_01\n";
5927   CompileSuccessfully(GenerateKernelCode(ss.str()));
5928   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5929 }
5930 
5931 TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
5932   const std::string ext_inst_name = GetParam();
5933   const std::string body =
5934       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5935 
5936   CompileSuccessfully(GenerateKernelCode(body));
5937   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5938   EXPECT_THAT(getDiagnosticString(),
5939               HasSubstr("OpenCL.std " + ext_inst_name +
5940                         ": expected Result Type to be an int scalar "
5941                         "or vector type"));
5942 }
5943 
5944 TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
5945   const std::string ext_inst_name = GetParam();
5946   const std::string body =
5947       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5948 
5949   CompileSuccessfully(GenerateKernelCode(body));
5950   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5951   EXPECT_THAT(
5952       getDiagnosticString(),
5953       HasSubstr("OpenCL.std " + ext_inst_name +
5954                 ": expected types of all operands to be equal to Result Type"));
5955 }
5956 
5957 TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
5958   const std::string ext_inst_name = GetParam();
5959   const std::string body =
5960       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
5961 
5962   CompileSuccessfully(GenerateKernelCode(body));
5963   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5964   EXPECT_THAT(
5965       getDiagnosticString(),
5966       HasSubstr("OpenCL.std " + ext_inst_name +
5967                 ": expected types of all operands to be equal to Result Type"));
5968 }
5969 
5970 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
5971                          ::testing::ValuesIn(std::vector<std::string>{
5972                              "s_abs",
5973                              "clz",
5974                              "ctz",
5975                              "popcount",
5976                              "u_abs",
5977                          }));
5978 
5979 TEST_P(ValidateOpenCLStdUMinLike, Success) {
5980   const std::string ext_inst_name = GetParam();
5981   std::ostringstream ss;
5982   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5983      << " %u32_1 %u32_2\n";
5984   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5985      << " %u32_1 %u32_2\n";
5986   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5987      << " %u32_1 %u32_2\n";
5988   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5989      << " %u32_1 %u32_2\n";
5990   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5991      << " %u32vec2_01 %u32vec2_01\n";
5992   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5993      << " %u32vec2_01 %u32vec2_01\n";
5994   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5995      << " %u32vec2_01 %u32vec2_01\n";
5996   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5997      << " %u32vec2_01 %u32vec2_01\n";
5998   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5999      << " %u64_1 %u64_0\n";
6000   CompileSuccessfully(GenerateKernelCode(ss.str()));
6001   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6002 }
6003 
6004 TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
6005   const std::string ext_inst_name = GetParam();
6006   const std::string body =
6007       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
6008 
6009   CompileSuccessfully(GenerateKernelCode(body));
6010   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6011   EXPECT_THAT(getDiagnosticString(),
6012               HasSubstr("OpenCL.std " + ext_inst_name +
6013                         ": expected Result Type to be an int scalar "
6014                         "or vector type"));
6015 }
6016 
6017 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
6018   const std::string ext_inst_name = GetParam();
6019   const std::string body =
6020       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
6021 
6022   CompileSuccessfully(GenerateKernelCode(body));
6023   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6024   EXPECT_THAT(
6025       getDiagnosticString(),
6026       HasSubstr("OpenCL.std " + ext_inst_name +
6027                 ": expected types of all operands to be equal to Result Type"));
6028 }
6029 
6030 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
6031   const std::string ext_inst_name = GetParam();
6032   const std::string body =
6033       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
6034 
6035   CompileSuccessfully(GenerateKernelCode(body));
6036   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6037   EXPECT_THAT(
6038       getDiagnosticString(),
6039       HasSubstr("OpenCL.std " + ext_inst_name +
6040                 ": expected types of all operands to be equal to Result Type"));
6041 }
6042 
6043 TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
6044   const std::string ext_inst_name = GetParam();
6045   const std::string body =
6046       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
6047 
6048   CompileSuccessfully(GenerateKernelCode(body));
6049   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6050   EXPECT_THAT(
6051       getDiagnosticString(),
6052       HasSubstr("OpenCL.std " + ext_inst_name +
6053                 ": expected types of all operands to be equal to Result Type"));
6054 }
6055 
6056 TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
6057   const std::string ext_inst_name = GetParam();
6058   const std::string body =
6059       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
6060 
6061   CompileSuccessfully(GenerateKernelCode(body));
6062   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6063   EXPECT_THAT(
6064       getDiagnosticString(),
6065       HasSubstr("OpenCL.std " + ext_inst_name +
6066                 ": expected types of all operands to be equal to Result Type"));
6067 }
6068 
6069 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
6070                          ::testing::ValuesIn(std::vector<std::string>{
6071                              "s_max",
6072                              "u_max",
6073                              "s_min",
6074                              "u_min",
6075                              "s_abs_diff",
6076                              "s_add_sat",
6077                              "u_add_sat",
6078                              "s_mul_hi",
6079                              "rotate",
6080                              "s_sub_sat",
6081                              "u_sub_sat",
6082                              "s_hadd",
6083                              "u_hadd",
6084                              "s_rhadd",
6085                              "u_rhadd",
6086                              "u_abs_diff",
6087                              "u_mul_hi",
6088                          }));
6089 
6090 TEST_P(ValidateOpenCLStdUClampLike, Success) {
6091   const std::string ext_inst_name = GetParam();
6092   std::ostringstream ss;
6093   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6094      << " %u32_0 %u32_1 %u32_2\n";
6095   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6096      << " %u32_0 %u32_1 %u32_2\n";
6097   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6098      << " %u32_0 %u32_1 %u32_2\n";
6099   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6100      << " %u32_0 %u32_1 %u32_2\n";
6101   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6102      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6103   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6104      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6105   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6106      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6107   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6108      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6109   ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
6110      << " %u64_1 %u64_0 %u64_1\n";
6111   CompileSuccessfully(GenerateKernelCode(ss.str()));
6112   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6113 }
6114 
6115 TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
6116   const std::string ext_inst_name = GetParam();
6117   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6118                            " %u32_0 %u32_0 %u32_1\n";
6119 
6120   CompileSuccessfully(GenerateKernelCode(body));
6121   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6122   EXPECT_THAT(getDiagnosticString(),
6123               HasSubstr("OpenCL.std " + ext_inst_name +
6124                         ": expected Result Type to be an int scalar "
6125                         "or vector type"));
6126 }
6127 
6128 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
6129   const std::string ext_inst_name = GetParam();
6130   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6131                            " %f32_0 %u32_0 %u32_1\n";
6132 
6133   CompileSuccessfully(GenerateKernelCode(body));
6134   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6135   EXPECT_THAT(
6136       getDiagnosticString(),
6137       HasSubstr("OpenCL.std " + ext_inst_name +
6138                 ": expected types of all operands to be equal to Result Type"));
6139 }
6140 
6141 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
6142   const std::string ext_inst_name = GetParam();
6143   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6144                            " %u32_0 %f32_0 %u32_1\n";
6145 
6146   CompileSuccessfully(GenerateKernelCode(body));
6147   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6148   EXPECT_THAT(
6149       getDiagnosticString(),
6150       HasSubstr("OpenCL.std " + ext_inst_name +
6151                 ": expected types of all operands to be equal to Result Type"));
6152 }
6153 
6154 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
6155   const std::string ext_inst_name = GetParam();
6156   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6157                            " %u32_0 %u32_0 %f32_1\n";
6158 
6159   CompileSuccessfully(GenerateKernelCode(body));
6160   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6161   EXPECT_THAT(
6162       getDiagnosticString(),
6163       HasSubstr("OpenCL.std " + ext_inst_name +
6164                 ": expected types of all operands to be equal to Result Type"));
6165 }
6166 
6167 TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
6168   const std::string ext_inst_name = GetParam();
6169   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6170                            " %f32_0 %u32_0 %u64_1\n";
6171 
6172   CompileSuccessfully(GenerateKernelCode(body));
6173   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6174   EXPECT_THAT(
6175       getDiagnosticString(),
6176       HasSubstr("OpenCL.std " + ext_inst_name +
6177                 ": expected types of all operands to be equal to Result Type"));
6178 }
6179 
6180 TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
6181   const std::string ext_inst_name = GetParam();
6182   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6183                            " %u32_0 %f32_0 %u64_1\n";
6184 
6185   CompileSuccessfully(GenerateKernelCode(body));
6186   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6187   EXPECT_THAT(
6188       getDiagnosticString(),
6189       HasSubstr("OpenCL.std " + ext_inst_name +
6190                 ": expected types of all operands to be equal to Result Type"));
6191 }
6192 
6193 TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
6194   const std::string ext_inst_name = GetParam();
6195   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6196                            " %u32_0 %u32_0 %u64_1\n";
6197 
6198   CompileSuccessfully(GenerateKernelCode(body));
6199   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6200   EXPECT_THAT(
6201       getDiagnosticString(),
6202       HasSubstr("OpenCL.std " + ext_inst_name +
6203                 ": expected types of all operands to be equal to Result Type"));
6204 }
6205 
6206 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
6207                          ::testing::ValuesIn(std::vector<std::string>{
6208                              "s_clamp",
6209                              "u_clamp",
6210                              "s_mad_hi",
6211                              "u_mad_sat",
6212                              "s_mad_sat",
6213                              "u_mad_hi",
6214                          }));
6215 
6216 // -------------------------------------------------------------
6217 TEST_P(ValidateOpenCLStdUMul24Like, Success) {
6218   const std::string ext_inst_name = GetParam();
6219   std::ostringstream ss;
6220   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6221      << " %u32_1 %u32_2\n";
6222   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6223      << " %u32_1 %u32_2\n";
6224   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6225      << " %u32_1 %u32_2\n";
6226   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6227      << " %u32_1 %u32_2\n";
6228   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6229      << " %u32vec2_01 %u32vec2_01\n";
6230   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6231      << " %u32vec2_01 %u32vec2_01\n";
6232   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6233      << " %u32vec2_01 %u32vec2_01\n";
6234   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6235      << " %u32vec2_01 %u32vec2_01\n";
6236   CompileSuccessfully(GenerateKernelCode(ss.str()));
6237   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6238 }
6239 
6240 TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
6241   const std::string ext_inst_name = GetParam();
6242   const std::string body =
6243       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
6244 
6245   CompileSuccessfully(GenerateKernelCode(body));
6246   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6247   EXPECT_THAT(
6248       getDiagnosticString(),
6249       HasSubstr(
6250           "OpenCL.std " + ext_inst_name +
6251           ": expected Result Type to be a 32-bit int scalar or vector type"));
6252 }
6253 
6254 TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
6255   const std::string ext_inst_name = GetParam();
6256   const std::string body =
6257       "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
6258 
6259   CompileSuccessfully(GenerateKernelCode(body));
6260   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6261   EXPECT_THAT(
6262       getDiagnosticString(),
6263       HasSubstr(
6264           "OpenCL.std " + ext_inst_name +
6265           ": expected Result Type to be a 32-bit int scalar or vector type"));
6266 }
6267 
6268 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
6269   const std::string ext_inst_name = GetParam();
6270   const std::string body =
6271       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
6272 
6273   CompileSuccessfully(GenerateKernelCode(body));
6274   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6275   EXPECT_THAT(
6276       getDiagnosticString(),
6277       HasSubstr("OpenCL.std " + ext_inst_name +
6278                 ": expected types of all operands to be equal to Result Type"));
6279 }
6280 
6281 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
6282   const std::string ext_inst_name = GetParam();
6283   const std::string body =
6284       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
6285 
6286   CompileSuccessfully(GenerateKernelCode(body));
6287   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6288   EXPECT_THAT(
6289       getDiagnosticString(),
6290       HasSubstr("OpenCL.std " + ext_inst_name +
6291                 ": expected types of all operands to be equal to Result Type"));
6292 }
6293 
6294 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
6295   const std::string ext_inst_name = GetParam();
6296   const std::string body =
6297       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
6298 
6299   CompileSuccessfully(GenerateKernelCode(body));
6300   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6301   EXPECT_THAT(
6302       getDiagnosticString(),
6303       HasSubstr("OpenCL.std " + ext_inst_name +
6304                 ": expected types of all operands to be equal to Result Type"));
6305 }
6306 
6307 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
6308   const std::string ext_inst_name = GetParam();
6309   const std::string body =
6310       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
6311 
6312   CompileSuccessfully(GenerateKernelCode(body));
6313   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6314   EXPECT_THAT(
6315       getDiagnosticString(),
6316       HasSubstr("OpenCL.std " + ext_inst_name +
6317                 ": expected types of all operands to be equal to Result Type"));
6318 }
6319 
6320 INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
6321                          ::testing::ValuesIn(std::vector<std::string>{
6322                              "s_mul24",
6323                              "u_mul24",
6324                          }));
6325 
6326 TEST_P(ValidateOpenCLStdUMad24Like, Success) {
6327   const std::string ext_inst_name = GetParam();
6328   std::ostringstream ss;
6329   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6330      << " %u32_0 %u32_1 %u32_2\n";
6331   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6332      << " %u32_0 %u32_1 %u32_2\n";
6333   ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6334      << " %u32_0 %u32_1 %u32_2\n";
6335   ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6336      << " %u32_0 %u32_1 %u32_2\n";
6337   ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6338      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6339   ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6340      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6341   ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6342      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6343   ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6344      << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6345   CompileSuccessfully(GenerateKernelCode(ss.str()));
6346   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6347 }
6348 
6349 TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
6350   const std::string ext_inst_name = GetParam();
6351   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6352                            " %u32_0 %u32_0 %u32_1\n";
6353 
6354   CompileSuccessfully(GenerateKernelCode(body));
6355   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6356   EXPECT_THAT(
6357       getDiagnosticString(),
6358       HasSubstr(
6359           "OpenCL.std " + ext_inst_name +
6360           ": expected Result Type to be a 32-bit int scalar or vector type"));
6361 }
6362 
6363 TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
6364   const std::string ext_inst_name = GetParam();
6365   const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
6366                            " %u64_0 %u64_0 %u64_1\n";
6367 
6368   CompileSuccessfully(GenerateKernelCode(body));
6369   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6370   EXPECT_THAT(
6371       getDiagnosticString(),
6372       HasSubstr(
6373           "OpenCL.std " + ext_inst_name +
6374           ": expected Result Type to be a 32-bit int scalar or vector type"));
6375 }
6376 
6377 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
6378   const std::string ext_inst_name = GetParam();
6379   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6380                            " %f32_0 %u32_0 %u32_1\n";
6381 
6382   CompileSuccessfully(GenerateKernelCode(body));
6383   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6384   EXPECT_THAT(
6385       getDiagnosticString(),
6386       HasSubstr("OpenCL.std " + ext_inst_name +
6387                 ": expected types of all operands to be equal to Result Type"));
6388 }
6389 
6390 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
6391   const std::string ext_inst_name = GetParam();
6392   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6393                            " %u32_0 %f32_0 %u32_1\n";
6394 
6395   CompileSuccessfully(GenerateKernelCode(body));
6396   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6397   EXPECT_THAT(
6398       getDiagnosticString(),
6399       HasSubstr("OpenCL.std " + ext_inst_name +
6400                 ": expected types of all operands to be equal to Result Type"));
6401 }
6402 
6403 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
6404   const std::string ext_inst_name = GetParam();
6405   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6406                            " %u32_0 %u32_0 %f32_1\n";
6407 
6408   CompileSuccessfully(GenerateKernelCode(body));
6409   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6410   EXPECT_THAT(
6411       getDiagnosticString(),
6412       HasSubstr("OpenCL.std " + ext_inst_name +
6413                 ": expected types of all operands to be equal to Result Type"));
6414 }
6415 
6416 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
6417   const std::string ext_inst_name = GetParam();
6418   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6419                            " %f32_0 %u32_0 %u64_1\n";
6420 
6421   CompileSuccessfully(GenerateKernelCode(body));
6422   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6423   EXPECT_THAT(
6424       getDiagnosticString(),
6425       HasSubstr("OpenCL.std " + ext_inst_name +
6426                 ": expected types of all operands to be equal to Result Type"));
6427 }
6428 
6429 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
6430   const std::string ext_inst_name = GetParam();
6431   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6432                            " %u32_0 %f32_0 %u64_1\n";
6433 
6434   CompileSuccessfully(GenerateKernelCode(body));
6435   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6436   EXPECT_THAT(
6437       getDiagnosticString(),
6438       HasSubstr("OpenCL.std " + ext_inst_name +
6439                 ": expected types of all operands to be equal to Result Type"));
6440 }
6441 
6442 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
6443   const std::string ext_inst_name = GetParam();
6444   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6445                            " %u32_0 %u32_0 %u64_1\n";
6446 
6447   CompileSuccessfully(GenerateKernelCode(body));
6448   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6449   EXPECT_THAT(
6450       getDiagnosticString(),
6451       HasSubstr("OpenCL.std " + ext_inst_name +
6452                 ": expected types of all operands to be equal to Result Type"));
6453 }
6454 
6455 INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
6456                          ::testing::ValuesIn(std::vector<std::string>{
6457                              "s_mad24",
6458                              "u_mad24",
6459                          }));
6460 
6461 TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
6462   const std::string body = R"(
6463 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6464 %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
6465 )";
6466 
6467   CompileSuccessfully(GenerateKernelCode(body));
6468   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6469 }
6470 
6471 TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
6472   const std::string body = R"(
6473 %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6474 )";
6475 
6476   CompileSuccessfully(GenerateKernelCode(body));
6477   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6478   EXPECT_THAT(getDiagnosticString(),
6479               HasSubstr("OpenCL.std cross: "
6480                         "expected Result Type to be a float vector type"));
6481 }
6482 
6483 TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
6484   const std::string body = R"(
6485 %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
6486 )";
6487 
6488   CompileSuccessfully(GenerateKernelCode(body));
6489   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6490   EXPECT_THAT(getDiagnosticString(),
6491               HasSubstr("OpenCL.std cross: "
6492                         "expected Result Type to have 3 or 4 components"));
6493 }
6494 
6495 TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
6496   const std::string body = R"(
6497 %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
6498 )";
6499 
6500   CompileSuccessfully(GenerateKernelCode(body));
6501   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6502   EXPECT_THAT(getDiagnosticString(),
6503               HasSubstr("OpenCL.std cross: "
6504                         "expected operand X type to be equal to Result Type"));
6505 }
6506 
6507 TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
6508   const std::string body = R"(
6509 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
6510 )";
6511 
6512   CompileSuccessfully(GenerateKernelCode(body));
6513   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6514   EXPECT_THAT(getDiagnosticString(),
6515               HasSubstr("OpenCL.std cross: "
6516                         "expected operand Y type to be equal to Result Type"));
6517 }
6518 
6519 TEST_P(ValidateOpenCLStdLengthLike, Success) {
6520   const std::string ext_inst_name = GetParam();
6521   std::ostringstream ss;
6522   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
6523   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6524      << " %f32vec4_0123\n";
6525 
6526   CompileSuccessfully(GenerateKernelCode(ss.str()));
6527   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6528 }
6529 
6530 TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
6531   const std::string ext_inst_name = GetParam();
6532   const std::string body =
6533       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
6534 
6535   CompileSuccessfully(GenerateKernelCode(body));
6536   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6537   EXPECT_THAT(getDiagnosticString(),
6538               HasSubstr("OpenCL.std " + ext_inst_name +
6539                         ": "
6540                         "expected Result Type to be a float scalar type"));
6541 }
6542 
6543 TEST_P(ValidateOpenCLStdLengthLike, IntX) {
6544   const std::string ext_inst_name = GetParam();
6545   const std::string body =
6546       "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
6547 
6548   CompileSuccessfully(GenerateKernelCode(body));
6549   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6550   EXPECT_THAT(getDiagnosticString(),
6551               HasSubstr("OpenCL.std " + ext_inst_name +
6552                         ": "
6553                         "expected operand P to be a float scalar or vector"));
6554 }
6555 
6556 TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
6557   const std::string ext_inst_name = GetParam();
6558   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6559                            " %f32vec8_01010101\n";
6560 
6561   CompileSuccessfully(GenerateKernelCode(body));
6562   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6563   EXPECT_THAT(
6564       getDiagnosticString(),
6565       HasSubstr("OpenCL.std " + ext_inst_name +
6566                 ": "
6567                 "expected operand P to have no more than 4 components"));
6568 }
6569 
6570 TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
6571   const std::string ext_inst_name = GetParam();
6572   const std::string body =
6573       "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
6574 
6575   CompileSuccessfully(GenerateKernelCode(body));
6576   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6577   EXPECT_THAT(getDiagnosticString(),
6578               HasSubstr("OpenCL.std " + ext_inst_name +
6579                         ": "
6580                         "expected operand P component type to be equal to "
6581                         "Result Type"));
6582 }
6583 
6584 INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
6585                          ::testing::ValuesIn(std::vector<std::string>{
6586                              "length",
6587                              "fast_length",
6588                          }));
6589 
6590 TEST_P(ValidateOpenCLStdDistanceLike, Success) {
6591   const std::string ext_inst_name = GetParam();
6592   std::ostringstream ss;
6593   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6594      << " %f32vec2_01 %f32vec2_01\n";
6595   ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6596      << " %f32vec4_0123 %f32vec4_1234\n";
6597   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
6598      << " %f32_0 %f32_1\n";
6599 
6600   CompileSuccessfully(GenerateKernelCode(ss.str()));
6601   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6602 }
6603 
6604 TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
6605   const std::string ext_inst_name = GetParam();
6606   const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6607                            " %f32vec2_01 %f32vec2_12\n";
6608 
6609   CompileSuccessfully(GenerateKernelCode(body));
6610   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6611   EXPECT_THAT(getDiagnosticString(),
6612               HasSubstr("OpenCL.std " + ext_inst_name +
6613                         ": "
6614                         "expected Result Type to be a float scalar type"));
6615 }
6616 
6617 TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
6618   const std::string ext_inst_name = GetParam();
6619   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6620                            " %u32vec2_01 %f32vec2_12\n";
6621 
6622   CompileSuccessfully(GenerateKernelCode(body));
6623   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6624   EXPECT_THAT(
6625       getDiagnosticString(),
6626       HasSubstr("OpenCL.std " + ext_inst_name +
6627                 ": "
6628                 "expected operand P0 to be of float scalar or vector type"));
6629 }
6630 
6631 TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
6632   const std::string ext_inst_name = GetParam();
6633   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6634                            " %f32vec8_01010101 %f32vec8_01010101\n";
6635 
6636   CompileSuccessfully(GenerateKernelCode(body));
6637   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6638   EXPECT_THAT(
6639       getDiagnosticString(),
6640       HasSubstr("OpenCL.std " + ext_inst_name +
6641                 ": "
6642                 "expected operand P0 to have no more than 4 components"));
6643 }
6644 
6645 TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
6646   const std::string ext_inst_name = GetParam();
6647   const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6648                            " %f64vec2_01 %f32vec2_12\n";
6649 
6650   CompileSuccessfully(GenerateKernelCode(body));
6651   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6652   EXPECT_THAT(
6653       getDiagnosticString(),
6654       HasSubstr(
6655           "OpenCL.std " + ext_inst_name +
6656           ": "
6657           "expected operand P0 component type to be equal to Result Type"));
6658 }
6659 
6660 TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
6661   const std::string ext_inst_name = GetParam();
6662   const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
6663                            " %f64vec2_01 %f32vec2_12\n";
6664 
6665   CompileSuccessfully(GenerateKernelCode(body));
6666   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6667   EXPECT_THAT(getDiagnosticString(),
6668               HasSubstr("OpenCL.std " + ext_inst_name +
6669                         ": "
6670                         "expected operands P0 and P1 to be of the same type"));
6671 }
6672 
6673 INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
6674                          ::testing::ValuesIn(std::vector<std::string>{
6675                              "distance",
6676                              "fast_distance",
6677                          }));
6678 
6679 TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
6680   const std::string ext_inst_name = GetParam();
6681   std::ostringstream ss;
6682   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6683      << " %f32vec2_01\n";
6684   ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
6685      << " %f32vec4_0123\n";
6686   ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
6687 
6688   CompileSuccessfully(GenerateKernelCode(ss.str()));
6689   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6690 }
6691 
6692 TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
6693   const std::string ext_inst_name = GetParam();
6694   const std::string body =
6695       "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
6696 
6697   CompileSuccessfully(GenerateKernelCode(body));
6698   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6699   EXPECT_THAT(
6700       getDiagnosticString(),
6701       HasSubstr("OpenCL.std " + ext_inst_name +
6702                 ": "
6703                 "expected Result Type to be a float scalar or vector type"));
6704 }
6705 
6706 TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
6707   const std::string ext_inst_name = GetParam();
6708   const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
6709                            ext_inst_name + " %f32vec8_01010101\n";
6710 
6711   CompileSuccessfully(GenerateKernelCode(body));
6712   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6713   EXPECT_THAT(
6714       getDiagnosticString(),
6715       HasSubstr("OpenCL.std " + ext_inst_name +
6716                 ": "
6717                 "expected Result Type to have no more than 4 components"));
6718 }
6719 
6720 TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
6721   const std::string ext_inst_name = GetParam();
6722   const std::string body =
6723       "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
6724 
6725   CompileSuccessfully(GenerateKernelCode(body));
6726   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6727   EXPECT_THAT(getDiagnosticString(),
6728               HasSubstr("OpenCL.std " + ext_inst_name +
6729                         ": "
6730                         "expected operand P type to be equal to Result Type"));
6731 }
6732 
6733 INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
6734                          ::testing::ValuesIn(std::vector<std::string>{
6735                              "normalize",
6736                              "fast_normalize",
6737                          }));
6738 
6739 TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
6740   const std::string body = R"(
6741 %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
6742 %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
6743 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
6744 %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6745 %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
6746 )";
6747 
6748   CompileSuccessfully(GenerateKernelCode(body));
6749   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6750 }
6751 
6752 TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
6753   const std::string body = R"(
6754 %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
6755 )";
6756 
6757   CompileSuccessfully(GenerateKernelCode(body));
6758   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6759   EXPECT_THAT(
6760       getDiagnosticString(),
6761       HasSubstr(
6762           "OpenCL.std bitselect: "
6763           "expected Result Type to be an int or float scalar or vector type"));
6764 }
6765 
6766 TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
6767   const std::string body = R"(
6768 %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
6769 )";
6770 
6771   CompileSuccessfully(GenerateKernelCode(body));
6772   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6773   EXPECT_THAT(
6774       getDiagnosticString(),
6775       HasSubstr("OpenCL.std bitselect: "
6776                 "expected types of all operands to be equal to Result Type"));
6777 }
6778 
6779 TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
6780   const std::string body = R"(
6781 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
6782 )";
6783 
6784   CompileSuccessfully(GenerateKernelCode(body));
6785   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6786   EXPECT_THAT(
6787       getDiagnosticString(),
6788       HasSubstr("OpenCL.std bitselect: "
6789                 "expected types of all operands to be equal to Result Type"));
6790 }
6791 
6792 TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
6793   const std::string body = R"(
6794 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
6795 )";
6796 
6797   CompileSuccessfully(GenerateKernelCode(body));
6798   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6799   EXPECT_THAT(
6800       getDiagnosticString(),
6801       HasSubstr("OpenCL.std bitselect: "
6802                 "expected types of all operands to be equal to Result Type"));
6803 }
6804 
6805 TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
6806   const std::string body = R"(
6807 %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
6808 %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
6809 %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
6810 %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6811 %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
6812 )";
6813 
6814   CompileSuccessfully(GenerateKernelCode(body));
6815   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6816 }
6817 
6818 TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
6819   const std::string body = R"(
6820 %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
6821 )";
6822 
6823   CompileSuccessfully(GenerateKernelCode(body));
6824   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6825   EXPECT_THAT(
6826       getDiagnosticString(),
6827       HasSubstr(
6828           "OpenCL.std select: "
6829           "expected Result Type to be an int or float scalar or vector type"));
6830 }
6831 
6832 TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
6833   const std::string body = R"(
6834 %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
6835 )";
6836 
6837   CompileSuccessfully(GenerateKernelCode(body));
6838   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6839   EXPECT_THAT(getDiagnosticString(),
6840               HasSubstr("OpenCL.std select: "
6841                         "expected operand A type to be equal to Result Type"));
6842 }
6843 
6844 TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
6845   const std::string body = R"(
6846 %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
6847 )";
6848 
6849   CompileSuccessfully(GenerateKernelCode(body));
6850   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6851   EXPECT_THAT(getDiagnosticString(),
6852               HasSubstr("OpenCL.std select: "
6853                         "expected operand B type to be equal to Result Type"));
6854 }
6855 
6856 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
6857   const std::string body = R"(
6858 %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
6859 )";
6860 
6861   CompileSuccessfully(GenerateKernelCode(body));
6862   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6863   EXPECT_THAT(getDiagnosticString(),
6864               HasSubstr("OpenCL.std select: "
6865                         "expected operand C to be an int scalar or vector"));
6866 }
6867 
6868 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
6869   const std::string body = R"(
6870 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
6871 )";
6872 
6873   CompileSuccessfully(GenerateKernelCode(body));
6874   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6875   EXPECT_THAT(getDiagnosticString(),
6876               HasSubstr("OpenCL.std select: "
6877                         "expected operand C to have the same number of "
6878                         "components as Result Type"));
6879 }
6880 
6881 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
6882   const std::string body = R"(
6883 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
6884 )";
6885 
6886   CompileSuccessfully(GenerateKernelCode(body));
6887   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6888   EXPECT_THAT(
6889       getDiagnosticString(),
6890       HasSubstr(
6891           "OpenCL.std select: "
6892           "expected operand C to have the same bit width as Result Type"));
6893 }
6894 
6895 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
6896   const std::string ext_inst_name = GetParam();
6897   const std::string rounding_mode =
6898       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6899 
6900   std::ostringstream ss;
6901   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6902   if (std::string::npos == ext_inst_name.find("halfn")) {
6903     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6904        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6905     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6906        << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
6907   } else {
6908     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6909        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6910     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6911        << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
6912     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6913        << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
6914   }
6915 
6916   CompileSuccessfully(GenerateKernelCode(ss.str()));
6917   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6918 }
6919 
6920 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
6921   const std::string ext_inst_name = GetParam();
6922   const std::string rounding_mode =
6923       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6924 
6925   std::ostringstream ss;
6926   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6927   if (std::string::npos == ext_inst_name.find("halfn")) {
6928     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6929        << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
6930     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6931        << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
6932   } else {
6933     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6934        << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
6935     ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6936        << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
6937     ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6938        << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
6939   }
6940 
6941   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6942   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6943 }
6944 
6945 TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
6946   const std::string ext_inst_name = GetParam();
6947   const std::string rounding_mode =
6948       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6949 
6950   std::ostringstream ss;
6951   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6952   if (std::string::npos == ext_inst_name.find("halfn")) {
6953     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6954        << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6955   } else {
6956     ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6957        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6958   }
6959 
6960   CompileSuccessfully(GenerateKernelCode(ss.str()));
6961   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6962   EXPECT_THAT(getDiagnosticString(),
6963               HasSubstr("OpenCL.std " + ext_inst_name +
6964                         ": expected Result Type to be void"));
6965 }
6966 
6967 TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
6968   const std::string ext_inst_name = GetParam();
6969   const std::string rounding_mode =
6970       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6971 
6972   std::ostringstream ss;
6973   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6974   if (std::string::npos == ext_inst_name.find("halfn")) {
6975     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6976        << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6977     CompileSuccessfully(GenerateKernelCode(ss.str()));
6978     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6979     EXPECT_THAT(getDiagnosticString(),
6980                 HasSubstr("OpenCL.std " + ext_inst_name +
6981                           ": expected Data to be a 32 or 64-bit float scalar"));
6982   } else {
6983     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6984        << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
6985     CompileSuccessfully(GenerateKernelCode(ss.str()));
6986     ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6987     EXPECT_THAT(getDiagnosticString(),
6988                 HasSubstr("OpenCL.std " + ext_inst_name +
6989                           ": expected Data to be a 32 or 64-bit float vector"));
6990   }
6991 }
6992 
6993 TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
6994   const std::string ext_inst_name = GetParam();
6995   const std::string rounding_mode =
6996       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6997 
6998   std::ostringstream ss;
6999   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7000   if (std::string::npos == ext_inst_name.find("halfn")) {
7001     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7002        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7003   } else {
7004     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7005        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7006   }
7007 
7008   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7009   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7010   EXPECT_THAT(getDiagnosticString(),
7011               HasSubstr("OpenCL.std " + ext_inst_name +
7012                         " can only be used with physical addressing models"));
7013 }
7014 
7015 TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
7016   const std::string ext_inst_name = GetParam();
7017   const std::string rounding_mode =
7018       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7019 
7020   std::ostringstream ss;
7021   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7022   if (std::string::npos == ext_inst_name.find("halfn")) {
7023     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7024        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7025   } else {
7026     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7027        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7028   }
7029 
7030   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7031   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7032   EXPECT_THAT(
7033       getDiagnosticString(),
7034       HasSubstr("OpenCL.std " + ext_inst_name +
7035                 ": "
7036                 "expected operand Offset to be of type size_t (64-bit integer "
7037                 "for the addressing model used in the module)"));
7038 }
7039 
7040 TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
7041   const std::string ext_inst_name = GetParam();
7042   const std::string rounding_mode =
7043       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7044 
7045   std::ostringstream ss;
7046   if (std::string::npos == ext_inst_name.find("halfn")) {
7047     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7048        << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
7049   } else {
7050     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7051        << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
7052   }
7053 
7054   CompileSuccessfully(GenerateKernelCode(ss.str()));
7055   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7056   EXPECT_THAT(getDiagnosticString(),
7057               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
7058 }
7059 
7060 TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
7061   const std::string ext_inst_name = GetParam();
7062   const std::string rounding_mode =
7063       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7064 
7065   std::ostringstream ss;
7066   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7067         "%f16vec8_uniform_constant %u32_1\n";
7068   if (std::string::npos == ext_inst_name.find("halfn")) {
7069     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7070        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7071   } else {
7072     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7073        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7074   }
7075 
7076   CompileSuccessfully(GenerateKernelCode(ss.str()));
7077   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7078   EXPECT_THAT(getDiagnosticString(),
7079               HasSubstr("OpenCL.std " + ext_inst_name +
7080                         ": expected operand P storage class to be Generic, "
7081                         "CrossWorkgroup, Workgroup or Function"));
7082 }
7083 
7084 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
7085   const std::string ext_inst_name = GetParam();
7086   const std::string rounding_mode =
7087       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7088 
7089   std::ostringstream ss;
7090   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7091   if (std::string::npos == ext_inst_name.find("halfn")) {
7092     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7093        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7094   } else {
7095     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7096        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7097   }
7098 
7099   CompileSuccessfully(GenerateKernelCode(ss.str()));
7100   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7101   EXPECT_THAT(
7102       getDiagnosticString(),
7103       HasSubstr("OpenCL.std " + ext_inst_name +
7104                 ": expected operand P data type to be 16-bit float scalar"));
7105 }
7106 
7107 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
7108   const std::string ext_inst_name = GetParam();
7109   const std::string rounding_mode =
7110       ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7111 
7112   std::ostringstream ss;
7113   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7114   if (std::string::npos == ext_inst_name.find("halfn")) {
7115     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7116        << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7117   } else {
7118     ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7119        << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7120   }
7121 
7122   CompileSuccessfully(GenerateKernelCode(ss.str()));
7123   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7124   EXPECT_THAT(
7125       getDiagnosticString(),
7126       HasSubstr("OpenCL.std " + ext_inst_name +
7127                 ": expected operand P data type to be 16-bit float scalar"));
7128 }
7129 
7130 INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
7131                          ::testing::ValuesIn(std::vector<std::string>{
7132                              "vstore_half",
7133                              "vstore_half_r",
7134                              "vstore_halfn",
7135                              "vstore_halfn_r",
7136                              "vstorea_halfn",
7137                              "vstorea_halfn_r",
7138                          }));
7139 
7140 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
7141   const std::string ext_inst_name = GetParam();
7142 
7143   std::ostringstream ss;
7144   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7145   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7146      << " %u32_1 %ptr 2\n";
7147   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7148      << " %u32_1 %ptr 3\n";
7149   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7150      << " %u32_1 %ptr 4\n";
7151 
7152   CompileSuccessfully(GenerateKernelCode(ss.str()));
7153   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7154 }
7155 
7156 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
7157   const std::string ext_inst_name = GetParam();
7158 
7159   std::ostringstream ss;
7160   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7161   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7162      << " %u64_1 %ptr 2\n";
7163   ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7164      << " %u64_1 %ptr 3\n";
7165   ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7166      << " %u64_1 %ptr 4\n";
7167 
7168   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7169   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7170 }
7171 
7172 TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
7173   const std::string ext_inst_name = GetParam();
7174 
7175   std::ostringstream ss;
7176   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7177   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7178      << " %u32_1 %ptr 1\n";
7179 
7180   CompileSuccessfully(GenerateKernelCode(ss.str()));
7181   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7182   EXPECT_THAT(getDiagnosticString(),
7183               HasSubstr("OpenCL.std " + ext_inst_name +
7184                         ": expected Result Type to be a float vector type"));
7185 }
7186 
7187 TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
7188   const std::string ext_inst_name = GetParam();
7189 
7190   std::ostringstream ss;
7191   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7192   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7193      << " %u32_1 %ptr 2\n";
7194 
7195   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7196   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7197   EXPECT_THAT(getDiagnosticString(),
7198               HasSubstr("OpenCL.std " + ext_inst_name +
7199                         " can only be used with physical addressing models"));
7200 }
7201 
7202 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
7203   const std::string ext_inst_name = GetParam();
7204 
7205   std::ostringstream ss;
7206   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7207   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7208      << " %u64_1 %ptr 2\n";
7209 
7210   CompileSuccessfully(GenerateKernelCode(ss.str()));
7211   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7212   EXPECT_THAT(
7213       getDiagnosticString(),
7214       HasSubstr("OpenCL.std " + ext_inst_name +
7215                 ": expected operand Offset to be of type size_t (32-bit "
7216                 "integer for the addressing model used in the module)"));
7217 }
7218 
7219 TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
7220   const std::string ext_inst_name = GetParam();
7221 
7222   std::ostringstream ss;
7223   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7224      << " %u32_1 %f16_ptr_workgroup 2\n";
7225 
7226   CompileSuccessfully(GenerateKernelCode(ss.str()));
7227   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7228   EXPECT_THAT(getDiagnosticString(),
7229               HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
7230 }
7231 
7232 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
7233   const std::string ext_inst_name = GetParam();
7234 
7235   std::ostringstream ss;
7236   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7237   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7238      << " %u32_1 %ptr 2\n";
7239 
7240   CompileSuccessfully(GenerateKernelCode(ss.str()));
7241   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7242   EXPECT_THAT(
7243       getDiagnosticString(),
7244       HasSubstr("OpenCL.std " + ext_inst_name +
7245                 ": expected operand P storage class to be UniformConstant, "
7246                 "Generic, CrossWorkgroup, Workgroup or Function"));
7247 }
7248 
7249 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
7250   const std::string ext_inst_name = GetParam();
7251 
7252   std::ostringstream ss;
7253   ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7254   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7255      << " %u32_1 %ptr 2\n";
7256 
7257   CompileSuccessfully(GenerateKernelCode(ss.str()));
7258   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7259   EXPECT_THAT(
7260       getDiagnosticString(),
7261       HasSubstr("OpenCL.std " + ext_inst_name +
7262                 ": expected operand P data type to be 16-bit float scalar"));
7263 }
7264 
7265 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
7266   const std::string ext_inst_name = GetParam();
7267 
7268   std::ostringstream ss;
7269   ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7270   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7271      << " %u32_1 %ptr 2\n";
7272 
7273   CompileSuccessfully(GenerateKernelCode(ss.str()));
7274   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7275   EXPECT_THAT(
7276       getDiagnosticString(),
7277       HasSubstr("OpenCL.std " + ext_inst_name +
7278                 ": expected operand P data type to be 16-bit float scalar"));
7279 }
7280 
7281 TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
7282   const std::string ext_inst_name = GetParam();
7283 
7284   std::ostringstream ss;
7285   ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7286   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7287      << " %u32_1 %ptr 3\n";
7288 
7289   CompileSuccessfully(GenerateKernelCode(ss.str()));
7290   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7291   EXPECT_THAT(getDiagnosticString(),
7292               HasSubstr("OpenCL.std " + ext_inst_name +
7293                         ": expected literal N to be equal to the number of "
7294                         "components of Result Type"));
7295 }
7296 
7297 INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
7298                          ::testing::ValuesIn(std::vector<std::string>{
7299                              "vload_halfn",
7300                              "vloada_halfn",
7301                          }));
7302 
7303 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
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 2\n";
7308   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7309   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7310 
7311   CompileSuccessfully(GenerateKernelCode(ss.str()));
7312   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7313 }
7314 
7315 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
7316   std::ostringstream ss;
7317   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7318         "%u32vec8_uniform_constant %u32_1\n";
7319   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7320   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7321   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7322 
7323   CompileSuccessfully(GenerateKernelCode(ss.str()));
7324   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7325 }
7326 
7327 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
7328   std::ostringstream ss;
7329   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7330         "%f32vec8_uniform_constant %u32_1\n";
7331   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7332   ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7333   ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7334 
7335   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7336   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7337 }
7338 
7339 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
7340   std::ostringstream ss;
7341   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7342         "%u32vec8_uniform_constant %u32_1\n";
7343   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7344   ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7345   ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7346 
7347   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7348   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7349 }
7350 
7351 TEST_F(ValidateExtInst, VLoadNWrongResultType) {
7352   std::ostringstream ss;
7353   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7354         "%f32vec8_uniform_constant %u32_1\n";
7355   ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
7356 
7357   CompileSuccessfully(GenerateKernelCode(ss.str()));
7358   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7359   EXPECT_THAT(
7360       getDiagnosticString(),
7361       HasSubstr("OpenCL.std vloadn: "
7362                 "expected Result Type to be an int or float vector type"));
7363 }
7364 
7365 TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
7366   std::ostringstream ss;
7367   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7368         "%f32vec8_uniform_constant %u32_1\n";
7369   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7370 
7371   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7372   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7373   EXPECT_THAT(getDiagnosticString(),
7374               HasSubstr("OpenCL.std vloadn can only be used with physical "
7375                         "addressing models"));
7376 }
7377 
7378 TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
7379   std::ostringstream ss;
7380   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7381         "%f32vec8_uniform_constant %u32_1\n";
7382   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7383 
7384   CompileSuccessfully(GenerateKernelCode(ss.str()));
7385   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7386   EXPECT_THAT(
7387       getDiagnosticString(),
7388       HasSubstr(
7389           "OpenCL.std vloadn: expected operand Offset to be of type size_t "
7390           "(32-bit integer for the addressing model used in the module)"));
7391 }
7392 
7393 TEST_F(ValidateExtInst, VLoadNPNotPointer) {
7394   std::ostringstream ss;
7395   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
7396         "%f32_ptr_uniform_constant 2\n";
7397 
7398   CompileSuccessfully(GenerateKernelCode(ss.str()));
7399   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7400   EXPECT_THAT(getDiagnosticString(),
7401               HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
7402                         "type"));
7403 }
7404 
7405 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
7406   std::ostringstream ss;
7407   ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
7408   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7409 
7410   CompileSuccessfully(GenerateKernelCode(ss.str()));
7411   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7412   EXPECT_THAT(getDiagnosticString(),
7413               HasSubstr("OpenCL.std vloadn: expected operand P storage class "
7414                         "to be UniformConstant, Generic, CrossWorkgroup, "
7415                         "Workgroup or Function"));
7416 }
7417 
7418 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
7419   std::ostringstream ss;
7420   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7421         "%f32vec8_uniform_constant %u32_1\n";
7422   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7423 
7424   CompileSuccessfully(GenerateKernelCode(ss.str()));
7425   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7426   EXPECT_THAT(getDiagnosticString(),
7427               HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
7428                         "equal to component type of Result Type"));
7429 }
7430 
7431 TEST_F(ValidateExtInst, VLoadNWrongN) {
7432   std::ostringstream ss;
7433   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7434         "%f32vec8_uniform_constant %u32_1\n";
7435   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
7436 
7437   CompileSuccessfully(GenerateKernelCode(ss.str()));
7438   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7439   EXPECT_THAT(getDiagnosticString(),
7440               HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
7441                         "the number of components of Result Type"));
7442 }
7443 
7444 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
7445   std::ostringstream ss;
7446   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7447         "%f16vec8_uniform_constant %u32_1\n";
7448   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7449   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
7450 
7451   CompileSuccessfully(GenerateKernelCode(ss.str()));
7452   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7453 }
7454 
7455 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
7456   std::ostringstream ss;
7457   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7458         "%f16vec8_uniform_constant %u32_1\n";
7459   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7460   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
7461 
7462   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7463   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7464 }
7465 
7466 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
7467   std::ostringstream ss;
7468   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7469         "%f16vec8_uniform_constant %u32_1\n";
7470   ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
7471 
7472   CompileSuccessfully(GenerateKernelCode(ss.str()));
7473   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7474   EXPECT_THAT(getDiagnosticString(),
7475               HasSubstr("OpenCL.std vload_half: "
7476                         "expected Result Type to be a float scalar type"));
7477 }
7478 
7479 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
7480   std::ostringstream ss;
7481   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7482         "%f16vec8_uniform_constant %u32_1\n";
7483   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7484 
7485   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7486   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7487   EXPECT_THAT(getDiagnosticString(),
7488               HasSubstr("OpenCL.std vload_half can only be used with physical "
7489                         "addressing models"));
7490 }
7491 
7492 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
7493   std::ostringstream ss;
7494   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7495         "%f16vec8_uniform_constant %u32_1\n";
7496   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7497 
7498   CompileSuccessfully(GenerateKernelCode(ss.str()));
7499   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7500   EXPECT_THAT(
7501       getDiagnosticString(),
7502       HasSubstr(
7503           "OpenCL.std vload_half: expected operand Offset to be of type size_t "
7504           "(32-bit integer for the addressing model used in the module)"));
7505 }
7506 
7507 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
7508   std::ostringstream ss;
7509   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
7510         "%f16_ptr_uniform_constant\n";
7511 
7512   CompileSuccessfully(GenerateKernelCode(ss.str()));
7513   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7514   EXPECT_THAT(getDiagnosticString(),
7515               HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
7516                         "type"));
7517 }
7518 
7519 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
7520   std::ostringstream ss;
7521   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7522   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7523 
7524   CompileSuccessfully(GenerateKernelCode(ss.str()));
7525   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7526   EXPECT_THAT(
7527       getDiagnosticString(),
7528       HasSubstr(
7529           "OpenCL.std vload_half: expected operand P storage class to be "
7530           "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
7531 }
7532 
7533 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
7534   std::ostringstream ss;
7535   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7536         "%u32vec8_uniform_constant %u32_1\n";
7537   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7538 
7539   CompileSuccessfully(GenerateKernelCode(ss.str()));
7540   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7541   EXPECT_THAT(getDiagnosticString(),
7542               HasSubstr("OpenCL.std vload_half: expected operand P data type "
7543                         "to be 16-bit float scalar"));
7544 }
7545 
7546 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
7547   std::ostringstream ss;
7548   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7549         "%f32vec8_uniform_constant %u32_1\n";
7550   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7551 
7552   CompileSuccessfully(GenerateKernelCode(ss.str()));
7553   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7554   EXPECT_THAT(getDiagnosticString(),
7555               HasSubstr("OpenCL.std vload_half: expected operand P data type "
7556                         "to be 16-bit float scalar"));
7557 }
7558 
7559 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
7560   std::ostringstream ss;
7561   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7562   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7563   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7564   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
7565         "%ptr_g\n";
7566 
7567   CompileSuccessfully(GenerateKernelCode(ss.str()));
7568   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7569 }
7570 
7571 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
7572   std::ostringstream ss;
7573   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7574   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7575   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
7576   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
7577         "%ptr_g\n";
7578 
7579   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7580   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7581 }
7582 
7583 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
7584   std::ostringstream ss;
7585   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7586   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7587   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7588   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
7589         "%ptr_g\n";
7590 
7591   CompileSuccessfully(GenerateKernelCode(ss.str()));
7592   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7593 }
7594 
7595 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
7596   std::ostringstream ss;
7597   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7598   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7599   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
7600   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
7601         "%ptr_g\n";
7602 
7603   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7604   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7605 }
7606 
7607 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
7608   std::ostringstream ss;
7609   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7610   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7611   ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7612 
7613   CompileSuccessfully(GenerateKernelCode(ss.str()));
7614   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7615   EXPECT_THAT(getDiagnosticString(),
7616               HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
7617 }
7618 
7619 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
7620   std::ostringstream ss;
7621   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7622   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7623   ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
7624 
7625   CompileSuccessfully(GenerateKernelCode(ss.str()));
7626   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7627   EXPECT_THAT(
7628       getDiagnosticString(),
7629       HasSubstr(
7630           "OpenCL.std vstoren: expected Data to be an int or float vector"));
7631 }
7632 
7633 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
7634   std::ostringstream ss;
7635   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7636   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7637   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7638 
7639   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7640   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7641   EXPECT_THAT(getDiagnosticString(),
7642               HasSubstr("OpenCL.std vstoren can only be used with physical "
7643                         "addressing models"));
7644 }
7645 
7646 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
7647   std::ostringstream ss;
7648   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7649   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7650   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7651 
7652   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7653   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7654   EXPECT_THAT(
7655       getDiagnosticString(),
7656       HasSubstr(
7657           "OpenCL.std vstoren: expected operand Offset to be of type size_t "
7658           "(64-bit integer for the addressing model used in the module)"));
7659 }
7660 
7661 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
7662   std::ostringstream ss;
7663   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
7664         "%f32_ptr_generic\n";
7665 
7666   CompileSuccessfully(GenerateKernelCode(ss.str()));
7667   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7668   EXPECT_THAT(getDiagnosticString(),
7669               HasSubstr("Operand 127[%_ptr_Generic_float] cannot be a type"));
7670 }
7671 
7672 TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
7673   std::ostringstream ss;
7674   ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
7675         "%f32vec8_uniform_constant %u32_1\n";
7676   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
7677 
7678   CompileSuccessfully(GenerateKernelCode(ss.str()));
7679   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7680   EXPECT_THAT(
7681       getDiagnosticString(),
7682       HasSubstr("OpenCL.std vstoren: expected operand P storage class "
7683                 "to be Generic, CrossWorkgroup, Workgroup or Function"));
7684 }
7685 
7686 TEST_F(ValidateExtInst, VStorePWrongDataType) {
7687   std::ostringstream ss;
7688   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7689   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7690   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7691 
7692   CompileSuccessfully(GenerateKernelCode(ss.str()));
7693   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7694   EXPECT_THAT(getDiagnosticString(),
7695               HasSubstr("OpenCL.std vstoren: expected operand P data type to "
7696                         "be equal to the type of operand Data components"));
7697 }
7698 
7699 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
7700   const std::string body = R"(
7701 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
7702 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
7703 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
7704 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
7705 )";
7706 
7707   CompileSuccessfully(GenerateKernelCode(body));
7708   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7709 }
7710 
7711 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
7712   const std::string body = R"(
7713 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
7714 )";
7715 
7716   CompileSuccessfully(GenerateKernelCode(body));
7717   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7718   EXPECT_THAT(
7719       getDiagnosticString(),
7720       HasSubstr("OpenCL.std shuffle: "
7721                 "expected Result Type to be an int or float vector type"));
7722 }
7723 
7724 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
7725   const std::string body = R"(
7726 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
7727 )";
7728 
7729   CompileSuccessfully(GenerateKernelCode(body));
7730   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7731   EXPECT_THAT(
7732       getDiagnosticString(),
7733       HasSubstr("OpenCL.std shuffle: "
7734                 "expected Result Type to have 2, 4, 8 or 16 components"));
7735 }
7736 
7737 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
7738   const std::string body = R"(
7739 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
7740 )";
7741 
7742   CompileSuccessfully(GenerateKernelCode(body));
7743   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7744   EXPECT_THAT(getDiagnosticString(),
7745               HasSubstr("OpenCL.std shuffle: "
7746                         "expected operand X to be an int or float vector"));
7747 }
7748 
7749 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
7750   const std::string body = R"(
7751 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
7752 )";
7753 
7754   CompileSuccessfully(GenerateKernelCode(body));
7755   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7756   EXPECT_THAT(getDiagnosticString(),
7757               HasSubstr("OpenCL.std shuffle: "
7758                         "expected operand X to have 2, 4, 8 or 16 components"));
7759 }
7760 
7761 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
7762   const std::string body = R"(
7763 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7764 )";
7765 
7766   CompileSuccessfully(GenerateKernelCode(body));
7767   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7768   EXPECT_THAT(
7769       getDiagnosticString(),
7770       HasSubstr(
7771           "OpenCL.std shuffle: "
7772           "expected operand X and Result Type to have equal component types"));
7773 }
7774 
7775 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
7776   const std::string body = R"(
7777 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
7778 )";
7779 
7780   CompileSuccessfully(GenerateKernelCode(body));
7781   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7782   EXPECT_THAT(getDiagnosticString(),
7783               HasSubstr("OpenCL.std shuffle: "
7784                         "expected operand Shuffle Mask to be an int vector"));
7785 }
7786 
7787 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
7788   const std::string body = R"(
7789 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
7790 )";
7791 
7792   CompileSuccessfully(GenerateKernelCode(body));
7793   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7794   EXPECT_THAT(getDiagnosticString(),
7795               HasSubstr("OpenCL.std shuffle: "
7796                         "expected operand Shuffle Mask to have the same number "
7797                         "of components as Result Type"));
7798 }
7799 
7800 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
7801   const std::string body = R"(
7802 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7803 )";
7804 
7805   CompileSuccessfully(GenerateKernelCode(body));
7806   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7807   EXPECT_THAT(getDiagnosticString(),
7808               HasSubstr("OpenCL.std shuffle: "
7809                         "expected operand Shuffle Mask components to have the "
7810                         "same bit width as Result Type components"));
7811 }
7812 
7813 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
7814   const std::string body = R"(
7815 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7816 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
7817 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
7818 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
7819 )";
7820 
7821   CompileSuccessfully(GenerateKernelCode(body));
7822   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7823 }
7824 
7825 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
7826   const std::string body = R"(
7827 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7828 )";
7829 
7830   CompileSuccessfully(GenerateKernelCode(body));
7831   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7832   EXPECT_THAT(
7833       getDiagnosticString(),
7834       HasSubstr("OpenCL.std shuffle2: "
7835                 "expected Result Type to be an int or float vector type"));
7836 }
7837 
7838 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
7839   const std::string body = R"(
7840 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
7841 )";
7842 
7843   CompileSuccessfully(GenerateKernelCode(body));
7844   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7845   EXPECT_THAT(
7846       getDiagnosticString(),
7847       HasSubstr("OpenCL.std shuffle2: "
7848                 "expected Result Type to have 2, 4, 8 or 16 components"));
7849 }
7850 
7851 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
7852   const std::string body = R"(
7853 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
7854 )";
7855 
7856   CompileSuccessfully(GenerateKernelCode(body));
7857   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7858   EXPECT_THAT(getDiagnosticString(),
7859               HasSubstr("OpenCL.std shuffle2: "
7860                         "expected operand X to be an int or float vector"));
7861 }
7862 
7863 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
7864   const std::string body = R"(
7865 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
7866 )";
7867 
7868   CompileSuccessfully(GenerateKernelCode(body));
7869   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7870   EXPECT_THAT(getDiagnosticString(),
7871               HasSubstr("OpenCL.std shuffle2: "
7872                         "expected operands X and Y to be of the same type"));
7873 }
7874 
7875 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
7876   const std::string body = R"(
7877 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
7878 )";
7879 
7880   CompileSuccessfully(GenerateKernelCode(body));
7881   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7882   EXPECT_THAT(getDiagnosticString(),
7883               HasSubstr("OpenCL.std shuffle2: "
7884                         "expected operand X to have 2, 4, 8 or 16 components"));
7885 }
7886 
7887 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
7888   const std::string body = R"(
7889 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7890 )";
7891 
7892   CompileSuccessfully(GenerateKernelCode(body));
7893   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7894   EXPECT_THAT(
7895       getDiagnosticString(),
7896       HasSubstr(
7897           "OpenCL.std shuffle2: "
7898           "expected operand X and Result Type to have equal component types"));
7899 }
7900 
7901 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
7902   const std::string body = R"(
7903 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
7904 )";
7905 
7906   CompileSuccessfully(GenerateKernelCode(body));
7907   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7908   EXPECT_THAT(getDiagnosticString(),
7909               HasSubstr("OpenCL.std shuffle2: "
7910                         "expected operand Shuffle Mask to be an int vector"));
7911 }
7912 
7913 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
7914   const std::string body = R"(
7915 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7916 )";
7917 
7918   CompileSuccessfully(GenerateKernelCode(body));
7919   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7920   EXPECT_THAT(getDiagnosticString(),
7921               HasSubstr("OpenCL.std shuffle2: "
7922                         "expected operand Shuffle Mask to have the same number "
7923                         "of components as Result Type"));
7924 }
7925 
7926 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
7927   const std::string body = R"(
7928 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7929 )";
7930 
7931   CompileSuccessfully(GenerateKernelCode(body));
7932   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7933   EXPECT_THAT(getDiagnosticString(),
7934               HasSubstr("OpenCL.std shuffle2: "
7935                         "expected operand Shuffle Mask components to have the "
7936                         "same bit width as Result Type components"));
7937 }
7938 
7939 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
7940   const std::string body = R"(
7941 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7942 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7943 )";
7944 
7945   CompileSuccessfully(GenerateKernelCode(body));
7946   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7947 }
7948 
7949 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
7950   const std::string body = R"(
7951 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7952 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
7953 )";
7954 
7955   CompileSuccessfully(GenerateKernelCode(body));
7956   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7957   EXPECT_THAT(
7958       getDiagnosticString(),
7959       HasSubstr(
7960           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7961 }
7962 
7963 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
7964   const std::string body = R"(
7965 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7966 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
7967 )";
7968 
7969   CompileSuccessfully(GenerateKernelCode(body));
7970   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7971   EXPECT_THAT(
7972       getDiagnosticString(),
7973       HasSubstr(
7974           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7975 }
7976 
7977 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
7978   const std::string body = R"(
7979 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
7980 )";
7981 
7982   CompileSuccessfully(GenerateKernelCode(body));
7983   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7984   EXPECT_THAT(getDiagnosticString(),
7985               HasSubstr("Operand 137[%_ptr_UniformConstant_uchar] cannot be a "
7986                         "type"));
7987 }
7988 
7989 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
7990   const std::string body = R"(
7991 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7992 %format = OpBitcast %u8_ptr_generic %format_const
7993 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7994 )";
7995 
7996   CompileSuccessfully(GenerateKernelCode(body));
7997   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7998   EXPECT_THAT(getDiagnosticString(),
7999               HasSubstr("OpenCL.std printf: expected Format storage class to "
8000                         "be UniformConstant"));
8001 }
8002 
8003 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
8004   const std::string body = R"(
8005 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
8006 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
8007 )";
8008 
8009   CompileSuccessfully(GenerateKernelCode(body));
8010   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8011   EXPECT_THAT(
8012       getDiagnosticString(),
8013       HasSubstr(
8014           "OpenCL.std printf: expected Format data type to be 8-bit int"));
8015 }
8016 
8017 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
8018   const std::string body = R"(
8019 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8020 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8021 )";
8022 
8023   CompileSuccessfully(GenerateKernelCode(body));
8024   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8025 }
8026 
8027 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
8028   const std::string body = R"(
8029 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8030 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
8031 )";
8032 
8033   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
8034   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8035 }
8036 
8037 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
8038   const std::string body = R"(
8039 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
8040 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8041 )";
8042 
8043   CompileSuccessfully(GenerateKernelCode(body));
8044   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8045 }
8046 
8047 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
8048   const std::string body = R"(
8049 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
8050 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8051 )";
8052 
8053   CompileSuccessfully(GenerateKernelCode(body));
8054   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8055 }
8056 
8057 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
8058   const std::string body = R"(
8059 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8060 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
8061 )";
8062 
8063   CompileSuccessfully(GenerateKernelCode(body));
8064   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8065   EXPECT_THAT(
8066       getDiagnosticString(),
8067       HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
8068 }
8069 
8070 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
8071   const std::string body = R"(
8072 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
8073 )";
8074 
8075   CompileSuccessfully(GenerateKernelCode(body));
8076   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8077   EXPECT_THAT(getDiagnosticString(),
8078               HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
8079                         "type"));
8080 }
8081 
8082 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
8083   const std::string body = R"(
8084 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
8085 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8086 )";
8087 
8088   CompileSuccessfully(GenerateKernelCode(body));
8089   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8090   EXPECT_THAT(getDiagnosticString(),
8091               HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
8092                         "class to be CrossWorkgroup"));
8093 }
8094 
8095 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
8096   const std::string body = R"(
8097 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
8098 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8099 )";
8100 
8101   CompileSuccessfully(GenerateKernelCode(body));
8102   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8103   EXPECT_THAT(getDiagnosticString(),
8104               HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
8105                         "or float scalar or vector"));
8106 }
8107 
8108 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
8109   const std::string body = R"(
8110 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8111 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8112 )";
8113 
8114   CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
8115   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8116   EXPECT_THAT(getDiagnosticString(),
8117               HasSubstr("OpenCL.std prefetch can only be used with physical "
8118                         "addressing models"));
8119 }
8120 
8121 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
8122   const std::string body = R"(
8123 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
8124 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8125 )";
8126 
8127   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
8128   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8129   EXPECT_THAT(getDiagnosticString(),
8130               HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
8131                         "be of type size_t (64-bit integer for the addressing "
8132                         "model used in the module)"));
8133 }
8134 
8135 TEST_P(ValidateOpenCLStdFractLike, Success) {
8136   const std::string ext_inst_name = GetParam();
8137   std::ostringstream ss;
8138   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8139   ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
8140   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8141      << " %f32_0 %var_f32\n";
8142   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8143      << " %f32vec2_01 %var_f32vec2\n";
8144 
8145   CompileSuccessfully(GenerateKernelCode(ss.str()));
8146   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8147 }
8148 
8149 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
8150   const std::string ext_inst_name = GetParam();
8151   std::ostringstream ss;
8152   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8153   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8154      << " %f32_0 %var_f32\n";
8155 
8156   CompileSuccessfully(GenerateKernelCode(ss.str()));
8157   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8158   EXPECT_THAT(
8159       getDiagnosticString(),
8160       HasSubstr("OpenCL.std " + ext_inst_name +
8161                 ": expected Result Type to be a float scalar or vector type"));
8162 }
8163 
8164 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
8165   const std::string ext_inst_name = GetParam();
8166   std::ostringstream ss;
8167   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8168   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8169      << " %f64_0 %var_f32\n";
8170 
8171   CompileSuccessfully(GenerateKernelCode(ss.str()));
8172   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8173   EXPECT_THAT(
8174       getDiagnosticString(),
8175       HasSubstr("OpenCL.std " + ext_inst_name +
8176                 ": expected type of operand X to be equal to Result Type"));
8177 }
8178 
8179 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
8180   const std::string ext_inst_name = GetParam();
8181   std::ostringstream ss;
8182   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8183   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8184      << " %f32_0 %f32_1\n";
8185 
8186   CompileSuccessfully(GenerateKernelCode(ss.str()));
8187   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8188   EXPECT_THAT(getDiagnosticString(),
8189               HasSubstr("OpenCL.std " + ext_inst_name +
8190                         ": expected the last operand to be a pointer"));
8191 }
8192 
8193 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
8194   const std::string ext_inst_name = GetParam();
8195   std::ostringstream ss;
8196   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8197         "%f32vec8_uniform_constant %u32_1\n";
8198   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8199 
8200   CompileSuccessfully(GenerateKernelCode(ss.str()));
8201   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8202   EXPECT_THAT(getDiagnosticString(),
8203               HasSubstr("OpenCL.std " + ext_inst_name +
8204                         ": expected storage class of the pointer to be "
8205                         "Generic, CrossWorkgroup, Workgroup or Function"));
8206 }
8207 
8208 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
8209   const std::string ext_inst_name = GetParam();
8210   std::ostringstream ss;
8211   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8212   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8213      << " %f32_0 %var_u32\n";
8214 
8215   CompileSuccessfully(GenerateKernelCode(ss.str()));
8216   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8217   EXPECT_THAT(
8218       getDiagnosticString(),
8219       HasSubstr(
8220           "OpenCL.std " + ext_inst_name +
8221           ": expected data type of the pointer to be equal to Result Type"));
8222 }
8223 
8224 INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
8225                          ::testing::ValuesIn(std::vector<std::string>{
8226                              "fract",
8227                              "modf",
8228                              "sincos",
8229                          }));
8230 
8231 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
8232   const std::string body = R"(
8233 %var_u32 = OpVariable %u32_ptr_function Function
8234 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8235 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
8236 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
8237 )";
8238 
8239   CompileSuccessfully(GenerateKernelCode(body));
8240   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8241 }
8242 
8243 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
8244   const std::string body = R"(
8245 %var_u32 = OpVariable %u32_ptr_function Function
8246 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
8247 )";
8248 
8249   CompileSuccessfully(GenerateKernelCode(body));
8250   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8251   EXPECT_THAT(
8252       getDiagnosticString(),
8253       HasSubstr("OpenCL.std remquo: "
8254                 "expected Result Type to be a float scalar or vector type"));
8255 }
8256 
8257 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
8258   const std::string body = R"(
8259 %var_u32 = OpVariable %f32_ptr_function Function
8260 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
8261 )";
8262 
8263   CompileSuccessfully(GenerateKernelCode(body));
8264   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8265   EXPECT_THAT(
8266       getDiagnosticString(),
8267       HasSubstr("OpenCL.std remquo: "
8268                 "expected type of operand X to be equal to Result Type"));
8269 }
8270 
8271 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
8272   const std::string body = R"(
8273 %var_u32 = OpVariable %f32_ptr_function Function
8274 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
8275 )";
8276 
8277   CompileSuccessfully(GenerateKernelCode(body));
8278   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8279   EXPECT_THAT(
8280       getDiagnosticString(),
8281       HasSubstr("OpenCL.std remquo: "
8282                 "expected type of operand Y to be equal to Result Type"));
8283 }
8284 
8285 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
8286   const std::string body = R"(
8287 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
8288 )";
8289 
8290   CompileSuccessfully(GenerateKernelCode(body));
8291   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8292   EXPECT_THAT(getDiagnosticString(),
8293               HasSubstr("OpenCL.std remquo: "
8294                         "expected the last operand to be a pointer"));
8295 }
8296 
8297 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
8298   const std::string body = R"(
8299 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
8300 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
8301 )";
8302 
8303   CompileSuccessfully(GenerateKernelCode(body));
8304   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8305   EXPECT_THAT(getDiagnosticString(),
8306               HasSubstr("OpenCL.std remquo: "
8307                         "expected storage class of the pointer to be Generic, "
8308                         "CrossWorkgroup, Workgroup or Function"));
8309 }
8310 
8311 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
8312   const std::string body = R"(
8313 %var_f32 = OpVariable %f32_ptr_function Function
8314 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
8315 )";
8316 
8317   CompileSuccessfully(GenerateKernelCode(body));
8318   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8319   EXPECT_THAT(getDiagnosticString(),
8320               HasSubstr("OpenCL.std remquo: "
8321                         "expected data type of the pointer to be a 32-bit int "
8322                         "scalar or vector type"));
8323 }
8324 
8325 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
8326   const std::string body = R"(
8327 %var_u64 = OpVariable %u64_ptr_function Function
8328 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
8329 )";
8330   CompileSuccessfully(GenerateKernelCode(body));
8331   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8332   EXPECT_THAT(getDiagnosticString(),
8333               HasSubstr("OpenCL.std remquo: "
8334                         "expected data type of the pointer to be a 32-bit int "
8335                         "scalar or vector type"));
8336 }
8337 
8338 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
8339   const std::string body = R"(
8340 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8341 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
8342 )";
8343 
8344   CompileSuccessfully(GenerateKernelCode(body));
8345   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8346   EXPECT_THAT(
8347       getDiagnosticString(),
8348       HasSubstr("OpenCL.std remquo: "
8349                 "expected data type of the pointer to have the same number "
8350                 "of components as Result Type"));
8351 }
8352 
8353 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
8354   const std::string ext_inst_name = GetParam();
8355   std::ostringstream ss;
8356   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8357   ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
8358   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8359      << " %f32_0 %var_u32\n";
8360   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8361      << " %f32vec2_01 %var_u32vec2\n";
8362 
8363   CompileSuccessfully(GenerateKernelCode(ss.str()));
8364   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8365 }
8366 
8367 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
8368   const std::string ext_inst_name = GetParam();
8369   std::ostringstream ss;
8370   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8371   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8372      << " %f32_0 %var_u32\n";
8373 
8374   CompileSuccessfully(GenerateKernelCode(ss.str()));
8375   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8376   EXPECT_THAT(
8377       getDiagnosticString(),
8378       HasSubstr("OpenCL.std " + ext_inst_name +
8379                 ": expected Result Type to be a float scalar or vector type"));
8380 }
8381 
8382 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
8383   const std::string ext_inst_name = GetParam();
8384   std::ostringstream ss;
8385   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8386   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8387      << " %f64_0 %var_u32\n";
8388 
8389   CompileSuccessfully(GenerateKernelCode(ss.str()));
8390   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8391   EXPECT_THAT(
8392       getDiagnosticString(),
8393       HasSubstr("OpenCL.std " + ext_inst_name +
8394                 ": expected type of operand X to be equal to Result Type"));
8395 }
8396 
8397 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
8398   const std::string ext_inst_name = GetParam();
8399   std::ostringstream ss;
8400   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8401      << " %f32_0 %u32_1\n";
8402 
8403   CompileSuccessfully(GenerateKernelCode(ss.str()));
8404   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8405   EXPECT_THAT(getDiagnosticString(),
8406               HasSubstr("OpenCL.std " + ext_inst_name +
8407                         ": expected the last operand to be a pointer"));
8408 }
8409 
8410 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
8411   const std::string ext_inst_name = GetParam();
8412   std::ostringstream ss;
8413   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8414         "%f32vec8_uniform_constant %u32_1\n";
8415   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8416 
8417   CompileSuccessfully(GenerateKernelCode(ss.str()));
8418   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8419   EXPECT_THAT(getDiagnosticString(),
8420               HasSubstr("OpenCL.std " + ext_inst_name +
8421                         ": expected storage class of the pointer to be "
8422                         "Generic, CrossWorkgroup, Workgroup or Function"));
8423 }
8424 
8425 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
8426   const std::string ext_inst_name = GetParam();
8427   std::ostringstream ss;
8428   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8429   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8430      << " %f32_0 %var_f32\n";
8431 
8432   CompileSuccessfully(GenerateKernelCode(ss.str()));
8433   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8434   EXPECT_THAT(getDiagnosticString(),
8435               HasSubstr("OpenCL.std " + ext_inst_name +
8436                         ": expected data type of the pointer to be a 32-bit "
8437                         "int scalar or vector type"));
8438 }
8439 
8440 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
8441   const std::string ext_inst_name = GetParam();
8442   std::ostringstream ss;
8443   ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
8444   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8445      << " %f32_0 %var_u64\n";
8446 
8447   CompileSuccessfully(GenerateKernelCode(ss.str()));
8448   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8449   EXPECT_THAT(getDiagnosticString(),
8450               HasSubstr("OpenCL.std " + ext_inst_name +
8451                         ": expected data type of the pointer to be a 32-bit "
8452                         "int scalar or vector type"));
8453 }
8454 
8455 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
8456   const std::string ext_inst_name = GetParam();
8457   std::ostringstream ss;
8458   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8459   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8460      << " %f32vec2_01 %var_u32\n";
8461 
8462   CompileSuccessfully(GenerateKernelCode(ss.str()));
8463   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8464   EXPECT_THAT(getDiagnosticString(),
8465               HasSubstr("OpenCL.std " + ext_inst_name +
8466                         ": expected data type of the pointer to have the same "
8467                         "number of components as Result Type"));
8468 }
8469 
8470 INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
8471                          ::testing::ValuesIn(std::vector<std::string>{
8472                              "frexp",
8473                              "lgamma_r",
8474                          }));
8475 
8476 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
8477   const std::string body = R"(
8478 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
8479 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
8480 )";
8481 
8482   CompileSuccessfully(GenerateKernelCode(body));
8483   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8484 }
8485 
8486 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
8487   const std::string body = R"(
8488 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
8489 )";
8490 
8491   CompileSuccessfully(GenerateKernelCode(body));
8492   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8493   EXPECT_THAT(
8494       getDiagnosticString(),
8495       HasSubstr(
8496           "OpenCL.std ilogb: "
8497           "expected Result Type to be a 32-bit int scalar or vector type"));
8498 }
8499 
8500 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
8501   const std::string body = R"(
8502 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
8503 )";
8504 
8505   CompileSuccessfully(GenerateKernelCode(body));
8506   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8507   EXPECT_THAT(getDiagnosticString(),
8508               HasSubstr("OpenCL.std ilogb: "
8509                         "expected operand X to be a float scalar or vector"));
8510 }
8511 
8512 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
8513   const std::string body = R"(
8514 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
8515 )";
8516 
8517   CompileSuccessfully(GenerateKernelCode(body));
8518   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8519   EXPECT_THAT(getDiagnosticString(),
8520               HasSubstr("OpenCL.std ilogb: "
8521                         "expected operand X to have the same number of "
8522                         "components as Result Type"));
8523 }
8524 
8525 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
8526   const std::string body = R"(
8527 %val1 = OpExtInst %f32 %extinst nan %u32_3
8528 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
8529 )";
8530 
8531   CompileSuccessfully(GenerateKernelCode(body));
8532   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8533 }
8534 
8535 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
8536   const std::string body = R"(
8537 %val1 = OpExtInst %u32 %extinst nan %u32_3
8538 )";
8539 
8540   CompileSuccessfully(GenerateKernelCode(body));
8541   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8542   EXPECT_THAT(
8543       getDiagnosticString(),
8544       HasSubstr("OpenCL.std nan: "
8545                 "expected Result Type to be a float scalar or vector type"));
8546 }
8547 
8548 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
8549   const std::string body = R"(
8550 %val1 = OpExtInst %f32 %extinst nan %f32_3
8551 )";
8552 
8553   CompileSuccessfully(GenerateKernelCode(body));
8554   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8555   EXPECT_THAT(getDiagnosticString(),
8556               HasSubstr("OpenCL.std nan: "
8557                         "expected Nancode to be an int scalar or vector type"));
8558 }
8559 
8560 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
8561   const std::string body = R"(
8562 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
8563 )";
8564 
8565   CompileSuccessfully(GenerateKernelCode(body));
8566   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8567   EXPECT_THAT(getDiagnosticString(),
8568               HasSubstr("OpenCL.std nan: "
8569                         "expected Nancode to have the same number of "
8570                         "components as Result Type"));
8571 }
8572 
8573 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
8574   const std::string body = R"(
8575 %val1 = OpExtInst %f64 %extinst nan %u32_2
8576 )";
8577 
8578   CompileSuccessfully(GenerateKernelCode(body));
8579   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8580   EXPECT_THAT(
8581       getDiagnosticString(),
8582       HasSubstr("OpenCL.std nan: "
8583                 "expected Nancode to have the same bit width as Result Type"));
8584 }
8585 
8586 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
8587   const std::string ext_inst_name = GetParam();
8588   std::ostringstream ss;
8589   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8590      << " %f32_0 %u32_1\n";
8591   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8592      << " %f32vec2_12 %u32vec2_12\n";
8593 
8594   CompileSuccessfully(GenerateKernelCode(ss.str()));
8595   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8596 }
8597 
8598 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
8599   const std::string ext_inst_name = GetParam();
8600   std::ostringstream ss;
8601   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8602      << " %f32_0 %u32_1\n";
8603 
8604   CompileSuccessfully(GenerateKernelCode(ss.str()));
8605   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8606   EXPECT_THAT(
8607       getDiagnosticString(),
8608       HasSubstr("OpenCL.std " + ext_inst_name +
8609                 ": expected Result Type to be a float scalar or vector type"));
8610 }
8611 
8612 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
8613   const std::string ext_inst_name = GetParam();
8614   std::ostringstream ss;
8615   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8616      << " %u32_0 %u32_1\n";
8617 
8618   CompileSuccessfully(GenerateKernelCode(ss.str()));
8619   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8620   EXPECT_THAT(
8621       getDiagnosticString(),
8622       HasSubstr("OpenCL.std " + ext_inst_name +
8623                 ": expected type of operand X to be equal to Result Type"));
8624 }
8625 
8626 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
8627   const std::string ext_inst_name = GetParam();
8628   std::ostringstream ss;
8629   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8630      << " %f32_0 %f32_1\n";
8631 
8632   CompileSuccessfully(GenerateKernelCode(ss.str()));
8633   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8634   EXPECT_THAT(
8635       getDiagnosticString(),
8636       HasSubstr("OpenCL.std " + ext_inst_name +
8637                 ": expected the exponent to be a 32-bit int scalar or vector"));
8638 }
8639 
8640 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
8641   const std::string ext_inst_name = GetParam();
8642   std::ostringstream ss;
8643   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8644      << " %f32_0 %u64_1\n";
8645 
8646   CompileSuccessfully(GenerateKernelCode(ss.str()));
8647   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8648   EXPECT_THAT(
8649       getDiagnosticString(),
8650       HasSubstr("OpenCL.std " + ext_inst_name +
8651                 ": expected the exponent to be a 32-bit int scalar or vector"));
8652 }
8653 
8654 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
8655   const std::string ext_inst_name = GetParam();
8656   std::ostringstream ss;
8657   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8658      << " %f32_0 %u32vec2_01\n";
8659 
8660   CompileSuccessfully(GenerateKernelCode(ss.str()));
8661   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8662   EXPECT_THAT(getDiagnosticString(),
8663               HasSubstr("OpenCL.std " + ext_inst_name +
8664                         ": expected the exponent to have the same number of "
8665                         "components as Result Type"));
8666 }
8667 
8668 INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
8669                          ::testing::ValuesIn(std::vector<std::string>{
8670                              "ldexp",
8671                              "pown",
8672                              "rootn",
8673                          }));
8674 
8675 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
8676   const std::string ext_inst_name = GetParam();
8677   std::ostringstream ss;
8678   ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8679   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
8680      << " %u16_1 %u16_2\n";
8681   ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
8682      << " %u32_1 %u32_2\n";
8683   ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8684      << " %u32vec2_01 %u32vec2_01\n";
8685 
8686   CompileSuccessfully(GenerateKernelCode(ss.str()));
8687   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8688 }
8689 
8690 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
8691   const std::string ext_inst_name = GetParam();
8692   std::ostringstream ss;
8693   ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
8694      << " %u32_1 %u32_2\n";
8695 
8696   CompileSuccessfully(GenerateKernelCode(ss.str()));
8697   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8698   EXPECT_THAT(
8699       getDiagnosticString(),
8700       HasSubstr("OpenCL.std " + ext_inst_name +
8701                 ": expected Result Type to be an int scalar or vector type"));
8702 }
8703 
8704 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
8705   const std::string ext_inst_name = GetParam();
8706   std::ostringstream ss;
8707   ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8708 
8709   CompileSuccessfully(GenerateKernelCode(ss.str()));
8710   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8711   EXPECT_THAT(
8712       getDiagnosticString(),
8713       HasSubstr(
8714           "OpenCL.std " + ext_inst_name +
8715           ": expected bit width of Result Type components to be 16, 32 or 64"));
8716 }
8717 
8718 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
8719   const std::string ext_inst_name = GetParam();
8720   std::ostringstream ss;
8721   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8722      << " %u32_1 %u16_2\n";
8723 
8724   CompileSuccessfully(GenerateKernelCode(ss.str()));
8725   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8726   EXPECT_THAT(getDiagnosticString(),
8727               HasSubstr("OpenCL.std " + ext_inst_name +
8728                         ": expected Hi and Lo operands to have the same type"));
8729 }
8730 
8731 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
8732   const std::string ext_inst_name = GetParam();
8733   std::ostringstream ss;
8734   ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8735      << " %u32_1 %u32_2\n";
8736 
8737   CompileSuccessfully(GenerateKernelCode(ss.str()));
8738   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8739   EXPECT_THAT(getDiagnosticString(),
8740               HasSubstr("OpenCL.std " + ext_inst_name +
8741                         ": expected Hi and Lo operands to have the same number "
8742                         "of components as Result Type"));
8743 }
8744 
8745 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
8746   const std::string ext_inst_name = GetParam();
8747   std::ostringstream ss;
8748   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8749      << " %u16_1 %u16_2\n";
8750 
8751   CompileSuccessfully(GenerateKernelCode(ss.str()));
8752   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8753   EXPECT_THAT(
8754       getDiagnosticString(),
8755       HasSubstr("OpenCL.std " + ext_inst_name +
8756                 ": expected bit width of components of Hi and Lo operands to "
8757                 "be half of the bit width of components of Result Type"));
8758 }
8759 
8760 INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
8761                          ::testing::ValuesIn(std::vector<std::string>{
8762                              "u_upsample",
8763                              "s_upsample",
8764                          }));
8765 
8766 TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) {
8767   const std::string text = R"(
8768 OpCapability Shader
8769 OpCapability Linkage
8770 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
8771 OpMemoryModel Logical GLSL450
8772 )";
8773 
8774   CompileSuccessfully(text);
8775   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8776   EXPECT_THAT(getDiagnosticString(),
8777               HasSubstr("NonSemantic extended instruction sets cannot be "
8778                         "declared without SPV_KHR_non_semantic_info"));
8779 }
8780 
8781 TEST_F(ValidateClspvReflection, MissingVersion) {
8782   const std::string text = R"(
8783 OpCapability Shader
8784 OpCapability Linkage
8785 OpExtension "SPV_KHR_non_semantic_info"
8786 %1 = OpExtInstImport "NonSemantic.ClspvReflection."
8787 OpMemoryModel Logical GLSL450
8788 %2 = OpTypeVoid
8789 %3 = OpTypeInt 32 0
8790 %4 = OpConstant %3 1
8791 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8792 )";
8793 
8794   CompileSuccessfully(text);
8795   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8796   EXPECT_THAT(getDiagnosticString(),
8797               HasSubstr("Missing NonSemantic.ClspvReflection import version"));
8798 }
8799 
8800 TEST_F(ValidateClspvReflection, BadVersion0) {
8801   const std::string text = R"(
8802 OpCapability Shader
8803 OpCapability Linkage
8804 OpExtension "SPV_KHR_non_semantic_info"
8805 %1 = OpExtInstImport "NonSemantic.ClspvReflection.0"
8806 OpMemoryModel Logical GLSL450
8807 %2 = OpTypeVoid
8808 %3 = OpTypeInt 32 0
8809 %4 = OpConstant %3 1
8810 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8811 )";
8812 
8813   CompileSuccessfully(text);
8814   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8815   EXPECT_THAT(getDiagnosticString(),
8816               HasSubstr("Unknown NonSemantic.ClspvReflection import version"));
8817 }
8818 
8819 TEST_F(ValidateClspvReflection, BadVersionNotANumber) {
8820   const std::string text = R"(
8821 OpCapability Shader
8822 OpCapability Linkage
8823 OpExtension "SPV_KHR_non_semantic_info"
8824 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a"
8825 OpMemoryModel Logical GLSL450
8826 %2 = OpTypeVoid
8827 %3 = OpTypeInt 32 0
8828 %4 = OpConstant %3 1
8829 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8830 )";
8831 
8832   CompileSuccessfully(text);
8833   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8834   EXPECT_THAT(getDiagnosticString(),
8835               HasSubstr("NonSemantic.ClspvReflection import does not encode "
8836                         "the version correctly"));
8837 }
8838 
8839 TEST_F(ValidateClspvReflection, Kernel) {
8840   const std::string text = R"(
8841 OpCapability Shader
8842 OpExtension "SPV_KHR_non_semantic_info"
8843 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8844 OpMemoryModel Logical GLSL450
8845 OpEntryPoint GLCompute %foo "foo"
8846 OpExecutionMode %foo LocalSize 1 1 1
8847 %foo_name = OpString "foo"
8848 %void = OpTypeVoid
8849 %void_fn = OpTypeFunction %void
8850 %foo = OpFunction %void None %void_fn
8851 %entry = OpLabel
8852 OpReturn
8853 OpFunctionEnd
8854 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8855 )";
8856 
8857   CompileSuccessfully(text);
8858   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8859 }
8860 
8861 TEST_F(ValidateClspvReflection, KernelNotAFunction) {
8862   const std::string text = R"(
8863 OpCapability Shader
8864 OpExtension "SPV_KHR_non_semantic_info"
8865 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8866 OpMemoryModel Logical GLSL450
8867 OpEntryPoint GLCompute %foo "foo"
8868 OpExecutionMode %foo LocalSize 1 1 1
8869 %foo_name = OpString "foo"
8870 %void = OpTypeVoid
8871 %void_fn = OpTypeFunction %void
8872 %foo = OpFunction %void None %void_fn
8873 %entry = OpLabel
8874 OpReturn
8875 OpFunctionEnd
8876 %decl = OpExtInst %void %ext Kernel %foo_name %foo_name
8877 )";
8878 
8879   CompileSuccessfully(text);
8880   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8881   EXPECT_THAT(getDiagnosticString(),
8882               HasSubstr("Kernel does not reference a function"));
8883 }
8884 
8885 TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) {
8886   const std::string text = R"(
8887 OpCapability Shader
8888 OpExtension "SPV_KHR_non_semantic_info"
8889 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8890 OpMemoryModel Logical GLSL450
8891 OpEntryPoint GLCompute %foo "foo"
8892 OpExecutionMode %foo LocalSize 1 1 1
8893 %foo_name = OpString "foo"
8894 %void = OpTypeVoid
8895 %void_fn = OpTypeFunction %void
8896 %foo = OpFunction %void None %void_fn
8897 %entry = OpLabel
8898 OpReturn
8899 OpFunctionEnd
8900 %bar = OpFunction %void None %void_fn
8901 %bar_entry = OpLabel
8902 OpReturn
8903 OpFunctionEnd
8904 %decl = OpExtInst %void %ext Kernel %bar %foo_name
8905 )";
8906 
8907   CompileSuccessfully(text);
8908   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8909   EXPECT_THAT(getDiagnosticString(),
8910               HasSubstr("Kernel does not reference an entry-point"));
8911 }
8912 
8913 TEST_F(ValidateClspvReflection, KernelNotGLCompute) {
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 Fragment %foo "foo"
8920 OpExecutionMode %foo OriginUpperLeft
8921 %foo_name = OpString "foo"
8922 %void = OpTypeVoid
8923 %void_fn = OpTypeFunction %void
8924 %foo = OpFunction %void None %void_fn
8925 %entry = OpLabel
8926 OpReturn
8927 OpFunctionEnd
8928 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8929 )";
8930 
8931   CompileSuccessfully(text);
8932   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8933   EXPECT_THAT(getDiagnosticString(),
8934               HasSubstr("Kernel must refer only to GLCompute entry-points"));
8935 }
8936 
8937 TEST_F(ValidateClspvReflection, KernelNameMismatch) {
8938   const std::string text = R"(
8939 OpCapability Shader
8940 OpExtension "SPV_KHR_non_semantic_info"
8941 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8942 OpMemoryModel Logical GLSL450
8943 OpEntryPoint GLCompute %foo "foo"
8944 OpExecutionMode %foo LocalSize 1 1 1
8945 %foo_name = OpString "bar"
8946 %void = OpTypeVoid
8947 %void_fn = OpTypeFunction %void
8948 %foo = OpFunction %void None %void_fn
8949 %entry = OpLabel
8950 OpReturn
8951 OpFunctionEnd
8952 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8953 )";
8954 
8955   CompileSuccessfully(text);
8956   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8957   EXPECT_THAT(getDiagnosticString(),
8958               HasSubstr("Name must match an entry-point for Kernel"));
8959 }
8960 
8961 using ArgumentBasics =
8962     spvtest::ValidateBase<std::pair<std::string, std::string>>;
8963 
8964 INSTANTIATE_TEST_SUITE_P(
8965     ValidateClspvReflectionArgumentKernel, ArgumentBasics,
8966     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
8967         std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"),
8968         std::make_pair("ArgumentUniform", "%int_0 %int_0"),
8969         std::make_pair("ArgumentPodStorageBuffer",
8970                        "%int_0 %int_0 %int_0 %int_4"),
8971         std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"),
8972         std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"),
8973         std::make_pair("ArgumentSampledImage", "%int_0 %int_0"),
8974         std::make_pair("ArgumentStorageImage", "%int_0 %int_0"),
8975         std::make_pair("ArgumentSampler", "%int_0 %int_0"),
8976         std::make_pair("ArgumentWorkgroup", "%int_0 %int_0")}));
8977 
8978 TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) {
8979   const std::string ext_inst = std::get<0>(GetParam());
8980   const std::string extra = std::get<1>(GetParam());
8981   const std::string text = R"(
8982 OpCapability Shader
8983 OpExtension "SPV_KHR_non_semantic_info"
8984 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8985 OpMemoryModel Logical GLSL450
8986 OpEntryPoint GLCompute %foo "foo"
8987 OpExecutionMode %foo LocalSize 1 1 1
8988 %foo_name = OpString "foo"
8989 %void = OpTypeVoid
8990 %int = OpTypeInt 32 0
8991 %int_0 = OpConstant %int 0
8992 %int_4 = OpConstant %int 4
8993 %void_fn = OpTypeFunction %void
8994 %foo = OpFunction %void None %void_fn
8995 %entry = OpLabel
8996 OpReturn
8997 OpFunctionEnd
8998 %in = OpExtInst %void %ext )" +
8999                            ext_inst + " %int_0 %int_0 " + extra;
9000 
9001   CompileSuccessfully(text);
9002   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9003   EXPECT_THAT(getDiagnosticString(),
9004               HasSubstr("Kernel must be a Kernel extended instruction"));
9005 }
9006 
9007 TEST_P(ArgumentBasics, KernelFromDifferentImport) {
9008   const std::string ext_inst = std::get<0>(GetParam());
9009   const std::string extra = std::get<1>(GetParam());
9010   const std::string text = R"(
9011 OpCapability Shader
9012 OpExtension "SPV_KHR_non_semantic_info"
9013 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9014 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
9015 OpMemoryModel Logical GLSL450
9016 OpEntryPoint GLCompute %foo "foo"
9017 OpExecutionMode %foo LocalSize 1 1 1
9018 %foo_name = OpString "foo"
9019 %void = OpTypeVoid
9020 %int = OpTypeInt 32 0
9021 %int_0 = OpConstant %int 0
9022 %int_4 = OpConstant %int 4
9023 %void_fn = OpTypeFunction %void
9024 %foo = OpFunction %void None %void_fn
9025 %entry = OpLabel
9026 OpReturn
9027 OpFunctionEnd
9028 %decl = OpExtInst %void %ext2 Kernel %foo %foo_name
9029 %in = OpExtInst %void %ext )" +
9030                            ext_inst + " %decl %int_0 " + extra;
9031 
9032   CompileSuccessfully(text);
9033   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9034   EXPECT_THAT(
9035       getDiagnosticString(),
9036       HasSubstr("Kernel must be from the same extended instruction import"));
9037 }
9038 
9039 TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) {
9040   const std::string ext_inst = std::get<0>(GetParam());
9041   const std::string extra = std::get<1>(GetParam());
9042   const std::string text = R"(
9043 OpCapability Shader
9044 OpExtension "SPV_KHR_non_semantic_info"
9045 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9046 OpMemoryModel Logical GLSL450
9047 OpEntryPoint GLCompute %foo "foo"
9048 OpExecutionMode %foo LocalSize 1 1 1
9049 %foo_name = OpString "foo"
9050 %void = OpTypeVoid
9051 %int = OpTypeInt 32 0
9052 %int_0 = OpConstant %int 0
9053 %int_4 = OpConstant %int 4
9054 %void_fn = OpTypeFunction %void
9055 %foo = OpFunction %void None %void_fn
9056 %entry = OpLabel
9057 OpReturn
9058 OpFunctionEnd
9059 %decl = OpExtInst %void %ext ArgumentInfo %foo_name
9060 %in = OpExtInst %void %ext )" +
9061                            ext_inst + " %decl %int_0 " + extra;
9062 
9063   CompileSuccessfully(text);
9064   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9065   EXPECT_THAT(getDiagnosticString(),
9066               HasSubstr("Kernel must be a Kernel extended instruction"));
9067 }
9068 
9069 TEST_P(ArgumentBasics, ArgumentInfo) {
9070   const std::string ext_inst = std::get<0>(GetParam());
9071   const std::string operands = std::get<1>(GetParam());
9072   const std::string text = R"(
9073 OpCapability Shader
9074 OpExtension "SPV_KHR_non_semantic_info"
9075 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9076 OpMemoryModel Logical GLSL450
9077 OpEntryPoint GLCompute %foo "foo"
9078 OpExecutionMode %foo LocalSize 1 1 1
9079 %foo_name = OpString "foo"
9080 %in_name = OpString "in"
9081 %void = OpTypeVoid
9082 %int = OpTypeInt 32 0
9083 %int_0 = OpConstant %int 0
9084 %int_4 = OpConstant %int 4
9085 %void_fn = OpTypeFunction %void
9086 %foo = OpFunction %void None %void_fn
9087 %entry = OpLabel
9088 OpReturn
9089 OpFunctionEnd
9090 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9091 %info = OpExtInst %void %ext ArgumentInfo %in_name
9092 %in = OpExtInst %void %ext )" +
9093                            ext_inst + " %decl %int_0 " + operands + " %info";
9094 
9095   CompileSuccessfully(text);
9096   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
9097 }
9098 
9099 TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) {
9100   const std::string ext_inst = std::get<0>(GetParam());
9101   const std::string operands = std::get<1>(GetParam());
9102   const std::string text = R"(
9103 OpCapability Shader
9104 OpExtension "SPV_KHR_non_semantic_info"
9105 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9106 OpMemoryModel Logical GLSL450
9107 OpEntryPoint GLCompute %foo "foo"
9108 OpExecutionMode %foo LocalSize 1 1 1
9109 %foo_name = OpString "foo"
9110 %void = OpTypeVoid
9111 %int = OpTypeInt 32 0
9112 %int_0 = OpConstant %int 0
9113 %int_4 = OpConstant %int 4
9114 %void_fn = OpTypeFunction %void
9115 %foo = OpFunction %void None %void_fn
9116 %entry = OpLabel
9117 OpReturn
9118 OpFunctionEnd
9119 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9120 %in = OpExtInst %void %ext )" +
9121                            ext_inst + " %decl %int_0 " + operands + " %int_0";
9122 
9123   CompileSuccessfully(text);
9124   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9125   EXPECT_THAT(
9126       getDiagnosticString(),
9127       HasSubstr("ArgInfo must be an ArgumentInfo extended instruction"));
9128 }
9129 
9130 TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) {
9131   const std::string ext_inst = std::get<0>(GetParam());
9132   const std::string operands = std::get<1>(GetParam());
9133   const std::string text = R"(
9134 OpCapability Shader
9135 OpExtension "SPV_KHR_non_semantic_info"
9136 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9137 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
9138 OpMemoryModel Logical GLSL450
9139 OpEntryPoint GLCompute %foo "foo"
9140 OpExecutionMode %foo LocalSize 1 1 1
9141 %foo_name = OpString "foo"
9142 %in_name = OpString "in"
9143 %void = OpTypeVoid
9144 %int = OpTypeInt 32 0
9145 %int_0 = OpConstant %int 0
9146 %int_4 = OpConstant %int 4
9147 %void_fn = OpTypeFunction %void
9148 %foo = OpFunction %void None %void_fn
9149 %entry = OpLabel
9150 OpReturn
9151 OpFunctionEnd
9152 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9153 %info = OpExtInst %void %ext2 ArgumentInfo %in_name
9154 %in = OpExtInst %void %ext )" +
9155                            ext_inst + " %decl %int_0 " + operands + " %info";
9156 
9157   CompileSuccessfully(text);
9158   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9159   EXPECT_THAT(
9160       getDiagnosticString(),
9161       HasSubstr("ArgInfo must be from the same extended instruction import"));
9162 }
9163 
9164 using Uint32Constant =
9165     spvtest::ValidateBase<std::pair<std::string, std::string>>;
9166 
9167 INSTANTIATE_TEST_SUITE_P(
9168     ValidateClspvReflectionUint32Constants, Uint32Constant,
9169     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9170         std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0",
9171                        "Ordinal"),
9172         std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0",
9173                        "Ordinal"),
9174         std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0",
9175                        "DescriptorSet"),
9176         std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0",
9177                        "DescriptorSet"),
9178         std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0",
9179                        "Binding"),
9180         std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null",
9181                        "Binding"),
9182         std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0",
9183                        "Ordinal"),
9184         std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"),
9185         std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0",
9186                        "DescriptorSet"),
9187         std::make_pair("ArgumentUniform %decl %int_0 %null %int_0",
9188                        "DescriptorSet"),
9189         std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0",
9190                        "Binding"),
9191         std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"),
9192         std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0",
9193                        "Ordinal"),
9194         std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0",
9195                        "Ordinal"),
9196         std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0",
9197                        "DescriptorSet"),
9198         std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0",
9199                        "DescriptorSet"),
9200         std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0",
9201                        "Binding"),
9202         std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null",
9203                        "Binding"),
9204         std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0",
9205                        "Ordinal"),
9206         std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0",
9207                        "Ordinal"),
9208         std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0",
9209                        "DescriptorSet"),
9210         std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0",
9211                        "DescriptorSet"),
9212         std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0",
9213                        "Binding"),
9214         std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null",
9215                        "Binding"),
9216         std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0",
9217                        "Ordinal"),
9218         std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"),
9219         std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0",
9220                        "DescriptorSet"),
9221         std::make_pair("ArgumentSampler %decl %int_0 %null %int_0",
9222                        "DescriptorSet"),
9223         std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0",
9224                        "Binding"),
9225         std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"),
9226         std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 "
9227                        "%int_0 %int_4",
9228                        "Ordinal"),
9229         std::make_pair(
9230             "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4",
9231             "Ordinal"),
9232         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 "
9233                        "%int_0 %int_4",
9234                        "DescriptorSet"),
9235         std::make_pair(
9236             "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4",
9237             "DescriptorSet"),
9238         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 "
9239                        "%int_0 %int_4",
9240                        "Binding"),
9241         std::make_pair(
9242             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4",
9243             "Binding"),
9244         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9245                        "%float_0 %int_4",
9246                        "Offset"),
9247         std::make_pair(
9248             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4",
9249             "Offset"),
9250         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9251                        "%int_0 %float_0",
9252                        "Size"),
9253         std::make_pair(
9254             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null",
9255             "Size"),
9256         std::make_pair(
9257             "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
9258             "Ordinal"),
9259         std::make_pair(
9260             "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4",
9261             "Ordinal"),
9262         std::make_pair(
9263             "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
9264             "DescriptorSet"),
9265         std::make_pair(
9266             "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4",
9267             "DescriptorSet"),
9268         std::make_pair(
9269             "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
9270             "Binding"),
9271         std::make_pair(
9272             "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4",
9273             "Binding"),
9274         std::make_pair(
9275             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
9276             "Offset"),
9277         std::make_pair(
9278             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4",
9279             "Offset"),
9280         std::make_pair(
9281             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
9282             "Size"),
9283         std::make_pair(
9284             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
9285             "Size"),
9286         std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4",
9287                        "Ordinal"),
9288         std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4",
9289                        "Ordinal"),
9290         std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4",
9291                        "Offset"),
9292         std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4",
9293                        "Offset"),
9294         std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0",
9295                        "Size"),
9296         std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null",
9297                        "Size"),
9298         std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4",
9299                        "Ordinal"),
9300         std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4",
9301                        "Ordinal"),
9302         std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4",
9303                        "SpecId"),
9304         std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"),
9305         std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0",
9306                        "ElemSize"),
9307         std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null",
9308                        "ElemSize"),
9309         std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"),
9310         std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"),
9311         std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"),
9312         std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"),
9313         std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"),
9314         std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"),
9315         std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"),
9316         std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"),
9317         std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"),
9318         std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"),
9319         std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"),
9320         std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"),
9321         std::make_pair("SpecConstantWorkDim %float_0", "Dim"),
9322         std::make_pair("SpecConstantWorkDim %null", "Dim"),
9323         std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"),
9324         std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"),
9325         std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"),
9326         std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"),
9327         std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0",
9328                        "Offset"),
9329         std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"),
9330         std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"),
9331         std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"),
9332         std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"),
9333         std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"),
9334         std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"),
9335         std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"),
9336         std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"),
9337         std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"),
9338         std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"),
9339         std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"),
9340         std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"),
9341         std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"),
9342         std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"),
9343         std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"),
9344         std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0",
9345                        "Offset"),
9346         std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"),
9347         std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"),
9348         std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"),
9349         std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data",
9350                        "DescriptorSet"),
9351         std::make_pair("ConstantDataStorageBuffer %null %int_0 %data",
9352                        "DescriptorSet"),
9353         std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data",
9354                        "Binding"),
9355         std::make_pair("ConstantDataStorageBuffer %int_0 %null %data",
9356                        "Binding"),
9357         std::make_pair("ConstantDataUniform %float_0 %int_0 %data",
9358                        "DescriptorSet"),
9359         std::make_pair("ConstantDataUniform %null %int_0 %data",
9360                        "DescriptorSet"),
9361         std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"),
9362         std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"),
9363         std::make_pair("LiteralSampler %float_0 %int_0 %int_4",
9364                        "DescriptorSet"),
9365         std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"),
9366         std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"),
9367         std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"),
9368         std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"),
9369         std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"),
9370         std::make_pair(
9371             "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"),
9372         std::make_pair(
9373             "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"),
9374         std::make_pair(
9375             "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"),
9376         std::make_pair(
9377             "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"),
9378         std::make_pair(
9379             "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"),
9380         std::make_pair(
9381             "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z")}));
9382 
9383 TEST_P(Uint32Constant, Invalid) {
9384   const std::string ext_inst = std::get<0>(GetParam());
9385   const std::string name = std::get<1>(GetParam());
9386   const std::string text = R"(
9387 OpCapability Shader
9388 OpExtension "SPV_KHR_non_semantic_info"
9389 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9390 OpMemoryModel Logical GLSL450
9391 OpEntryPoint GLCompute %foo "foo"
9392 OpExecutionMode %foo LocalSize 1 1 1
9393 %foo_name = OpString "foo"
9394 %data = OpString "1234"
9395 %void = OpTypeVoid
9396 %int = OpTypeInt 32 0
9397 %int_0 = OpConstant %int 0
9398 %int_1 = OpConstant %int 1
9399 %int_4 = OpConstant %int 4
9400 %null = OpConstantNull %int
9401 %float = OpTypeFloat 32
9402 %float_0 = OpConstant %float 0
9403 %void_fn = OpTypeFunction %void
9404 %foo = OpFunction %void None %void_fn
9405 %entry = OpLabel
9406 OpReturn
9407 OpFunctionEnd
9408 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9409 %inst = OpExtInst %void %ext )" +
9410                            ext_inst;
9411 
9412   CompileSuccessfully(text);
9413   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9414   EXPECT_THAT(
9415       getDiagnosticString(),
9416       HasSubstr(name + " must be a 32-bit unsigned integer OpConstant"));
9417 }
9418 
9419 using StringOperand =
9420     spvtest::ValidateBase<std::pair<std::string, std::string>>;
9421 
9422 INSTANTIATE_TEST_SUITE_P(
9423     ValidateClspvReflectionStringOperands, StringOperand,
9424     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9425         std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0",
9426                        "Data"),
9427         std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data")}));
9428 
9429 TEST_P(StringOperand, Invalid) {
9430   const std::string ext_inst = std::get<0>(GetParam());
9431   const std::string name = std::get<1>(GetParam());
9432   const std::string text = R"(
9433 OpCapability Shader
9434 OpExtension "SPV_KHR_non_semantic_info"
9435 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9436 OpMemoryModel Logical GLSL450
9437 OpEntryPoint GLCompute %foo "foo"
9438 OpExecutionMode %foo LocalSize 1 1 1
9439 %foo_name = OpString "foo"
9440 %data = OpString "1234"
9441 %void = OpTypeVoid
9442 %int = OpTypeInt 32 0
9443 %int_0 = OpConstant %int 0
9444 %int_1 = OpConstant %int 1
9445 %int_4 = OpConstant %int 4
9446 %null = OpConstantNull %int
9447 %float = OpTypeFloat 32
9448 %float_0 = OpConstant %float 0
9449 %void_fn = OpTypeFunction %void
9450 %foo = OpFunction %void None %void_fn
9451 %entry = OpLabel
9452 OpReturn
9453 OpFunctionEnd
9454 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9455 %inst = OpExtInst %void %ext )" +
9456                            ext_inst;
9457 
9458   CompileSuccessfully(text);
9459   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9460   EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString"));
9461 }
9462 
9463 }  // namespace
9464 }  // namespace val
9465 }  // namespace spvtools
9466