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