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(getDiagnosticString(),
4668               HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
4669                         "type"));
4670 }
4671 
TEST_F(ValidateExtInst,VLoadNWrongStorageClass)4672 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
4673   std::ostringstream ss;
4674   ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
4675   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
4676 
4677   CompileSuccessfully(GenerateKernelCode(ss.str()));
4678   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4679   EXPECT_THAT(getDiagnosticString(),
4680               HasSubstr("OpenCL.std vloadn: expected operand P storage class "
4681                         "to be UniformConstant, Generic, CrossWorkgroup, "
4682                         "Workgroup or Function"));
4683 }
4684 
TEST_F(ValidateExtInst,VLoadNWrongComponentType)4685 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
4686   std::ostringstream ss;
4687   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
4688         "%f32vec8_uniform_constant %u32_1\n";
4689   ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
4690 
4691   CompileSuccessfully(GenerateKernelCode(ss.str()));
4692   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4693   EXPECT_THAT(getDiagnosticString(),
4694               HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
4695                         "equal to component type of Result Type"));
4696 }
4697 
TEST_F(ValidateExtInst,VLoadNWrongN)4698 TEST_F(ValidateExtInst, VLoadNWrongN) {
4699   std::ostringstream ss;
4700   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
4701         "%f32vec8_uniform_constant %u32_1\n";
4702   ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
4703 
4704   CompileSuccessfully(GenerateKernelCode(ss.str()));
4705   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4706   EXPECT_THAT(getDiagnosticString(),
4707               HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
4708                         "the number of components of Result Type"));
4709 }
4710 
TEST_F(ValidateExtInst,VLoadHalfSuccessPhysical32)4711 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
4712   std::ostringstream ss;
4713   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
4714         "%f16vec8_uniform_constant %u32_1\n";
4715   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
4716   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
4717 
4718   CompileSuccessfully(GenerateKernelCode(ss.str()));
4719   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4720 }
4721 
TEST_F(ValidateExtInst,VLoadHalfSuccessPhysical64)4722 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
4723   std::ostringstream ss;
4724   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
4725         "%f16vec8_uniform_constant %u32_1\n";
4726   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
4727   ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
4728 
4729   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
4730   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4731 }
4732 
TEST_F(ValidateExtInst,VLoadHalfWrongResultType)4733 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
4734   std::ostringstream ss;
4735   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
4736         "%f16vec8_uniform_constant %u32_1\n";
4737   ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
4738 
4739   CompileSuccessfully(GenerateKernelCode(ss.str()));
4740   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4741   EXPECT_THAT(getDiagnosticString(),
4742               HasSubstr("OpenCL.std vload_half: "
4743                         "expected Result Type to be a float scalar type"));
4744 }
4745 
TEST_F(ValidateExtInst,VLoadHalfAddressingModelLogical)4746 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
4747   std::ostringstream ss;
4748   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
4749         "%f16vec8_uniform_constant %u32_1\n";
4750   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
4751 
4752   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
4753   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4754   EXPECT_THAT(getDiagnosticString(),
4755               HasSubstr("OpenCL.std vload_half can only be used with physical "
4756                         "addressing models"));
4757 }
4758 
TEST_F(ValidateExtInst,VLoadHalfOffsetNotSizeT)4759 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
4760   std::ostringstream ss;
4761   ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
4762         "%f16vec8_uniform_constant %u32_1\n";
4763   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
4764 
4765   CompileSuccessfully(GenerateKernelCode(ss.str()));
4766   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4767   EXPECT_THAT(
4768       getDiagnosticString(),
4769       HasSubstr(
4770           "OpenCL.std vload_half: expected operand Offset to be of type size_t "
4771           "(32-bit integer for the addressing model used in the module)"));
4772 }
4773 
TEST_F(ValidateExtInst,VLoadHalfPNotPointer)4774 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
4775   std::ostringstream ss;
4776   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
4777         "%f16_ptr_uniform_constant\n";
4778 
4779   CompileSuccessfully(GenerateKernelCode(ss.str()));
4780   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4781   EXPECT_THAT(getDiagnosticString(),
4782               HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
4783                         "type"));
4784 }
4785 
TEST_F(ValidateExtInst,VLoadHalfWrongStorageClass)4786 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
4787   std::ostringstream ss;
4788   ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
4789   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
4790 
4791   CompileSuccessfully(GenerateKernelCode(ss.str()));
4792   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4793   EXPECT_THAT(
4794       getDiagnosticString(),
4795       HasSubstr(
4796           "OpenCL.std vload_half: expected operand P storage class to be "
4797           "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
4798 }
4799 
TEST_F(ValidateExtInst,VLoadHalfPDataTypeInt)4800 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
4801   std::ostringstream ss;
4802   ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
4803         "%u32vec8_uniform_constant %u32_1\n";
4804   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
4805 
4806   CompileSuccessfully(GenerateKernelCode(ss.str()));
4807   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4808   EXPECT_THAT(getDiagnosticString(),
4809               HasSubstr("OpenCL.std vload_half: expected operand P data type "
4810                         "to be 16-bit float scalar"));
4811 }
4812 
TEST_F(ValidateExtInst,VLoadHalfPDataTypeFloat32)4813 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
4814   std::ostringstream ss;
4815   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
4816         "%f32vec8_uniform_constant %u32_1\n";
4817   ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
4818 
4819   CompileSuccessfully(GenerateKernelCode(ss.str()));
4820   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4821   EXPECT_THAT(getDiagnosticString(),
4822               HasSubstr("OpenCL.std vload_half: expected operand P data type "
4823                         "to be 16-bit float scalar"));
4824 }
4825 
TEST_F(ValidateExtInst,VStoreNSuccessFloatPhysical32)4826 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
4827   std::ostringstream ss;
4828   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4829   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4830   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
4831   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
4832         "%ptr_g\n";
4833 
4834   CompileSuccessfully(GenerateKernelCode(ss.str()));
4835   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4836 }
4837 
TEST_F(ValidateExtInst,VStoreNSuccessFloatPhysical64)4838 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
4839   std::ostringstream ss;
4840   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4841   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4842   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
4843   ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
4844         "%ptr_g\n";
4845 
4846   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
4847   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4848 }
4849 
TEST_F(ValidateExtInst,VStoreNSuccessIntPhysical32)4850 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
4851   std::ostringstream ss;
4852   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
4853   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
4854   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
4855   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
4856         "%ptr_g\n";
4857 
4858   CompileSuccessfully(GenerateKernelCode(ss.str()));
4859   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4860 }
4861 
TEST_F(ValidateExtInst,VStoreNSuccessIntPhysical64)4862 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
4863   std::ostringstream ss;
4864   ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
4865   ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
4866   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
4867   ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
4868         "%ptr_g\n";
4869 
4870   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
4871   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4872 }
4873 
TEST_F(ValidateExtInst,VStoreNResultTypeNotVoid)4874 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
4875   std::ostringstream ss;
4876   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4877   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4878   ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
4879 
4880   CompileSuccessfully(GenerateKernelCode(ss.str()));
4881   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4882   EXPECT_THAT(getDiagnosticString(),
4883               HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
4884 }
4885 
TEST_F(ValidateExtInst,VStoreNDataWrongType)4886 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
4887   std::ostringstream ss;
4888   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4889   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4890   ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
4891 
4892   CompileSuccessfully(GenerateKernelCode(ss.str()));
4893   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4894   EXPECT_THAT(
4895       getDiagnosticString(),
4896       HasSubstr(
4897           "OpenCL.std vstoren: expected Data to be an int or float vector"));
4898 }
4899 
TEST_F(ValidateExtInst,VStoreNAddressingModelLogical)4900 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
4901   std::ostringstream ss;
4902   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4903   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4904   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
4905 
4906   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
4907   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4908   EXPECT_THAT(getDiagnosticString(),
4909               HasSubstr("OpenCL.std vstoren can only be used with physical "
4910                         "addressing models"));
4911 }
4912 
TEST_F(ValidateExtInst,VStoreNOffsetNotSizeT)4913 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
4914   std::ostringstream ss;
4915   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4916   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4917   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
4918 
4919   CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
4920   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4921   EXPECT_THAT(
4922       getDiagnosticString(),
4923       HasSubstr(
4924           "OpenCL.std vstoren: expected operand Offset to be of type size_t "
4925           "(64-bit integer for the addressing model used in the module)"));
4926 }
4927 
TEST_F(ValidateExtInst,VStoreNPNotPointer)4928 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
4929   std::ostringstream ss;
4930   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
4931         "%f32_ptr_generic\n";
4932 
4933   CompileSuccessfully(GenerateKernelCode(ss.str()));
4934   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4935   EXPECT_THAT(getDiagnosticString(),
4936               HasSubstr("Operand 127[%_ptr_Generic_float] cannot be a type"));
4937 }
4938 
TEST_F(ValidateExtInst,VStoreNWrongStorageClass)4939 TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
4940   std::ostringstream ss;
4941   ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
4942         "%f32vec8_uniform_constant %u32_1\n";
4943   ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
4944 
4945   CompileSuccessfully(GenerateKernelCode(ss.str()));
4946   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4947   EXPECT_THAT(
4948       getDiagnosticString(),
4949       HasSubstr("OpenCL.std vstoren: expected operand P storage class "
4950                 "to be Generic, CrossWorkgroup, Workgroup or Function"));
4951 }
4952 
TEST_F(ValidateExtInst,VStorePWrongDataType)4953 TEST_F(ValidateExtInst, VStorePWrongDataType) {
4954   std::ostringstream ss;
4955   ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
4956   ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
4957   ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
4958 
4959   CompileSuccessfully(GenerateKernelCode(ss.str()));
4960   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4961   EXPECT_THAT(getDiagnosticString(),
4962               HasSubstr("OpenCL.std vstoren: expected operand P data type to "
4963                         "be equal to the type of operand Data components"));
4964 }
4965 
TEST_F(ValidateExtInst,OpenCLStdShuffleSuccess)4966 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
4967   const std::string body = R"(
4968 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
4969 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
4970 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
4971 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
4972 )";
4973 
4974   CompileSuccessfully(GenerateKernelCode(body));
4975   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4976 }
4977 
TEST_F(ValidateExtInst,OpenCLStdShuffleWrongResultType)4978 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
4979   const std::string body = R"(
4980 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
4981 )";
4982 
4983   CompileSuccessfully(GenerateKernelCode(body));
4984   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4985   EXPECT_THAT(
4986       getDiagnosticString(),
4987       HasSubstr("OpenCL.std shuffle: "
4988                 "expected Result Type to be an int or float vector type"));
4989 }
4990 
TEST_F(ValidateExtInst,OpenCLStdShuffleResultTypeInvalidNumComponents)4991 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
4992   const std::string body = R"(
4993 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
4994 )";
4995 
4996   CompileSuccessfully(GenerateKernelCode(body));
4997   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4998   EXPECT_THAT(
4999       getDiagnosticString(),
5000       HasSubstr("OpenCL.std shuffle: "
5001                 "expected Result Type to have 2, 4, 8 or 16 components"));
5002 }
5003 
TEST_F(ValidateExtInst,OpenCLStdShuffleXWrongType)5004 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
5005   const std::string body = R"(
5006 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
5007 )";
5008 
5009   CompileSuccessfully(GenerateKernelCode(body));
5010   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5011   EXPECT_THAT(getDiagnosticString(),
5012               HasSubstr("OpenCL.std shuffle: "
5013                         "expected operand X to be an int or float vector"));
5014 }
5015 
TEST_F(ValidateExtInst,OpenCLStdShuffleXInvalidNumComponents)5016 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
5017   const std::string body = R"(
5018 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
5019 )";
5020 
5021   CompileSuccessfully(GenerateKernelCode(body));
5022   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5023   EXPECT_THAT(getDiagnosticString(),
5024               HasSubstr("OpenCL.std shuffle: "
5025                         "expected operand X to have 2, 4, 8 or 16 components"));
5026 }
5027 
TEST_F(ValidateExtInst,OpenCLStdShuffleXInvalidComponentType)5028 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
5029   const std::string body = R"(
5030 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
5031 )";
5032 
5033   CompileSuccessfully(GenerateKernelCode(body));
5034   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5035   EXPECT_THAT(
5036       getDiagnosticString(),
5037       HasSubstr(
5038           "OpenCL.std shuffle: "
5039           "expected operand X and Result Type to have equal component types"));
5040 }
5041 
TEST_F(ValidateExtInst,OpenCLStdShuffleShuffleMaskNotIntVector)5042 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
5043   const std::string body = R"(
5044 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
5045 )";
5046 
5047   CompileSuccessfully(GenerateKernelCode(body));
5048   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5049   EXPECT_THAT(getDiagnosticString(),
5050               HasSubstr("OpenCL.std shuffle: "
5051                         "expected operand Shuffle Mask to be an int vector"));
5052 }
5053 
TEST_F(ValidateExtInst,OpenCLStdShuffleShuffleMaskInvalidNumComponents)5054 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
5055   const std::string body = R"(
5056 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
5057 )";
5058 
5059   CompileSuccessfully(GenerateKernelCode(body));
5060   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5061   EXPECT_THAT(getDiagnosticString(),
5062               HasSubstr("OpenCL.std shuffle: "
5063                         "expected operand Shuffle Mask to have the same number "
5064                         "of components as Result Type"));
5065 }
5066 
TEST_F(ValidateExtInst,OpenCLStdShuffleShuffleMaskInvalidBitWidth)5067 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
5068   const std::string body = R"(
5069 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
5070 )";
5071 
5072   CompileSuccessfully(GenerateKernelCode(body));
5073   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5074   EXPECT_THAT(getDiagnosticString(),
5075               HasSubstr("OpenCL.std shuffle: "
5076                         "expected operand Shuffle Mask components to have the "
5077                         "same bit width as Result Type components"));
5078 }
5079 
TEST_F(ValidateExtInst,OpenCLStdShuffle2Success)5080 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
5081   const std::string body = R"(
5082 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
5083 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
5084 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
5085 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
5086 )";
5087 
5088   CompileSuccessfully(GenerateKernelCode(body));
5089   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5090 }
5091 
TEST_F(ValidateExtInst,OpenCLStdShuffle2WrongResultType)5092 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
5093   const std::string body = R"(
5094 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
5095 )";
5096 
5097   CompileSuccessfully(GenerateKernelCode(body));
5098   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5099   EXPECT_THAT(
5100       getDiagnosticString(),
5101       HasSubstr("OpenCL.std shuffle2: "
5102                 "expected Result Type to be an int or float vector type"));
5103 }
5104 
TEST_F(ValidateExtInst,OpenCLStdShuffle2ResultTypeInvalidNumComponents)5105 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
5106   const std::string body = R"(
5107 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
5108 )";
5109 
5110   CompileSuccessfully(GenerateKernelCode(body));
5111   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5112   EXPECT_THAT(
5113       getDiagnosticString(),
5114       HasSubstr("OpenCL.std shuffle2: "
5115                 "expected Result Type to have 2, 4, 8 or 16 components"));
5116 }
5117 
TEST_F(ValidateExtInst,OpenCLStdShuffle2XWrongType)5118 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
5119   const std::string body = R"(
5120 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
5121 )";
5122 
5123   CompileSuccessfully(GenerateKernelCode(body));
5124   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5125   EXPECT_THAT(getDiagnosticString(),
5126               HasSubstr("OpenCL.std shuffle2: "
5127                         "expected operand X to be an int or float vector"));
5128 }
5129 
TEST_F(ValidateExtInst,OpenCLStdShuffle2YTypeDifferentFromX)5130 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
5131   const std::string body = R"(
5132 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
5133 )";
5134 
5135   CompileSuccessfully(GenerateKernelCode(body));
5136   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5137   EXPECT_THAT(getDiagnosticString(),
5138               HasSubstr("OpenCL.std shuffle2: "
5139                         "expected operands X and Y to be of the same type"));
5140 }
5141 
TEST_F(ValidateExtInst,OpenCLStdShuffle2XInvalidNumComponents)5142 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
5143   const std::string body = R"(
5144 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
5145 )";
5146 
5147   CompileSuccessfully(GenerateKernelCode(body));
5148   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5149   EXPECT_THAT(getDiagnosticString(),
5150               HasSubstr("OpenCL.std shuffle2: "
5151                         "expected operand X to have 2, 4, 8 or 16 components"));
5152 }
5153 
TEST_F(ValidateExtInst,OpenCLStdShuffle2XInvalidComponentType)5154 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
5155   const std::string body = R"(
5156 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
5157 )";
5158 
5159   CompileSuccessfully(GenerateKernelCode(body));
5160   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5161   EXPECT_THAT(
5162       getDiagnosticString(),
5163       HasSubstr(
5164           "OpenCL.std shuffle2: "
5165           "expected operand X and Result Type to have equal component types"));
5166 }
5167 
TEST_F(ValidateExtInst,OpenCLStdShuffle2ShuffleMaskNotIntVector)5168 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
5169   const std::string body = R"(
5170 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
5171 )";
5172 
5173   CompileSuccessfully(GenerateKernelCode(body));
5174   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5175   EXPECT_THAT(getDiagnosticString(),
5176               HasSubstr("OpenCL.std shuffle2: "
5177                         "expected operand Shuffle Mask to be an int vector"));
5178 }
5179 
TEST_F(ValidateExtInst,OpenCLStdShuffle2ShuffleMaskInvalidNumComponents)5180 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
5181   const std::string body = R"(
5182 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
5183 )";
5184 
5185   CompileSuccessfully(GenerateKernelCode(body));
5186   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5187   EXPECT_THAT(getDiagnosticString(),
5188               HasSubstr("OpenCL.std shuffle2: "
5189                         "expected operand Shuffle Mask to have the same number "
5190                         "of components as Result Type"));
5191 }
5192 
TEST_F(ValidateExtInst,OpenCLStdShuffle2ShuffleMaskInvalidBitWidth)5193 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
5194   const std::string body = R"(
5195 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
5196 )";
5197 
5198   CompileSuccessfully(GenerateKernelCode(body));
5199   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5200   EXPECT_THAT(getDiagnosticString(),
5201               HasSubstr("OpenCL.std shuffle2: "
5202                         "expected operand Shuffle Mask components to have the "
5203                         "same bit width as Result Type components"));
5204 }
5205 
TEST_F(ValidateExtInst,OpenCLStdPrintfSuccess)5206 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
5207   const std::string body = R"(
5208 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
5209 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
5210 )";
5211 
5212   CompileSuccessfully(GenerateKernelCode(body));
5213   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5214 }
5215 
TEST_F(ValidateExtInst,OpenCLStdPrintfBoolResultType)5216 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
5217   const std::string body = R"(
5218 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
5219 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
5220 )";
5221 
5222   CompileSuccessfully(GenerateKernelCode(body));
5223   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5224   EXPECT_THAT(
5225       getDiagnosticString(),
5226       HasSubstr(
5227           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
5228 }
5229 
TEST_F(ValidateExtInst,OpenCLStdPrintfU64ResultType)5230 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
5231   const std::string body = R"(
5232 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
5233 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
5234 )";
5235 
5236   CompileSuccessfully(GenerateKernelCode(body));
5237   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5238   EXPECT_THAT(
5239       getDiagnosticString(),
5240       HasSubstr(
5241           "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
5242 }
5243 
TEST_F(ValidateExtInst,OpenCLStdPrintfFormatNotPointer)5244 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
5245   const std::string body = R"(
5246 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
5247 )";
5248 
5249   CompileSuccessfully(GenerateKernelCode(body));
5250   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5251   EXPECT_THAT(getDiagnosticString(),
5252               HasSubstr("Operand 137[%_ptr_UniformConstant_uchar] cannot be a "
5253                         "type"));
5254 }
5255 
TEST_F(ValidateExtInst,OpenCLStdPrintfFormatNotUniformConstStorageClass)5256 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
5257   const std::string body = R"(
5258 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
5259 %format = OpBitcast %u8_ptr_generic %format_const
5260 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
5261 )";
5262 
5263   CompileSuccessfully(GenerateKernelCode(body));
5264   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5265   EXPECT_THAT(getDiagnosticString(),
5266               HasSubstr("OpenCL.std printf: expected Format storage class to "
5267                         "be UniformConstant"));
5268 }
5269 
TEST_F(ValidateExtInst,OpenCLStdPrintfFormatNotU8Pointer)5270 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
5271   const std::string body = R"(
5272 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
5273 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
5274 )";
5275 
5276   CompileSuccessfully(GenerateKernelCode(body));
5277   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5278   EXPECT_THAT(
5279       getDiagnosticString(),
5280       HasSubstr(
5281           "OpenCL.std printf: expected Format data type to be 8-bit int"));
5282 }
5283 
TEST_F(ValidateExtInst,OpenCLStdPrefetchU32Success)5284 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
5285   const std::string body = R"(
5286 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
5287 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5288 )";
5289 
5290   CompileSuccessfully(GenerateKernelCode(body));
5291   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5292 }
5293 
TEST_F(ValidateExtInst,OpenCLStdPrefetchU32Physical64Success)5294 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
5295   const std::string body = R"(
5296 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
5297 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
5298 )";
5299 
5300   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
5301   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5302 }
5303 
TEST_F(ValidateExtInst,OpenCLStdPrefetchF32Success)5304 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
5305   const std::string body = R"(
5306 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
5307 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5308 )";
5309 
5310   CompileSuccessfully(GenerateKernelCode(body));
5311   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5312 }
5313 
TEST_F(ValidateExtInst,OpenCLStdPrefetchF32Vec2Success)5314 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
5315   const std::string body = R"(
5316 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
5317 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5318 )";
5319 
5320   CompileSuccessfully(GenerateKernelCode(body));
5321   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5322 }
5323 
TEST_F(ValidateExtInst,OpenCLStdPrefetchResultTypeNotVoid)5324 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
5325   const std::string body = R"(
5326 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
5327 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
5328 )";
5329 
5330   CompileSuccessfully(GenerateKernelCode(body));
5331   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5332   EXPECT_THAT(
5333       getDiagnosticString(),
5334       HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
5335 }
5336 
TEST_F(ValidateExtInst,OpenCLStdPrefetchPtrNotPointer)5337 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
5338   const std::string body = R"(
5339 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
5340 )";
5341 
5342   CompileSuccessfully(GenerateKernelCode(body));
5343   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5344   EXPECT_THAT(getDiagnosticString(),
5345               HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
5346                         "type"));
5347 }
5348 
TEST_F(ValidateExtInst,OpenCLStdPrefetchPtrNotCrossWorkgroup)5349 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
5350   const std::string body = R"(
5351 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
5352 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5353 )";
5354 
5355   CompileSuccessfully(GenerateKernelCode(body));
5356   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5357   EXPECT_THAT(getDiagnosticString(),
5358               HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
5359                         "class to be CrossWorkgroup"));
5360 }
5361 
TEST_F(ValidateExtInst,OpenCLStdPrefetchInvalidDataType)5362 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
5363   const std::string body = R"(
5364 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
5365 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5366 )";
5367 
5368   CompileSuccessfully(GenerateKernelCode(body));
5369   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5370   EXPECT_THAT(getDiagnosticString(),
5371               HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
5372                         "or float scalar or vector"));
5373 }
5374 
TEST_F(ValidateExtInst,OpenCLStdPrefetchAddressingModelLogical)5375 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
5376   const std::string body = R"(
5377 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
5378 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5379 )";
5380 
5381   CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
5382   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5383   EXPECT_THAT(getDiagnosticString(),
5384               HasSubstr("OpenCL.std prefetch can only be used with physical "
5385                         "addressing models"));
5386 }
5387 
TEST_F(ValidateExtInst,OpenCLStdPrefetchNumElementsNotSizeT)5388 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
5389   const std::string body = R"(
5390 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
5391 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
5392 )";
5393 
5394   CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
5395   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5396   EXPECT_THAT(getDiagnosticString(),
5397               HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
5398                         "be of type size_t (64-bit integer for the addressing "
5399                         "model used in the module)"));
5400 }
5401 
TEST_P(ValidateOpenCLStdFractLike,Success)5402 TEST_P(ValidateOpenCLStdFractLike, Success) {
5403   const std::string ext_inst_name = GetParam();
5404   std::ostringstream ss;
5405   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
5406   ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
5407   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5408      << " %f32_0 %var_f32\n";
5409   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5410      << " %f32vec2_01 %var_f32vec2\n";
5411 
5412   CompileSuccessfully(GenerateKernelCode(ss.str()));
5413   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5414 }
5415 
TEST_P(ValidateOpenCLStdFractLike,IntResultType)5416 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
5417   const std::string ext_inst_name = GetParam();
5418   std::ostringstream ss;
5419   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
5420   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5421      << " %f32_0 %var_f32\n";
5422 
5423   CompileSuccessfully(GenerateKernelCode(ss.str()));
5424   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5425   EXPECT_THAT(
5426       getDiagnosticString(),
5427       HasSubstr("OpenCL.std " + ext_inst_name +
5428                 ": expected Result Type to be a float scalar or vector type"));
5429 }
5430 
TEST_P(ValidateOpenCLStdFractLike,XWrongType)5431 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
5432   const std::string ext_inst_name = GetParam();
5433   std::ostringstream ss;
5434   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
5435   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5436      << " %f64_0 %var_f32\n";
5437 
5438   CompileSuccessfully(GenerateKernelCode(ss.str()));
5439   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5440   EXPECT_THAT(
5441       getDiagnosticString(),
5442       HasSubstr("OpenCL.std " + ext_inst_name +
5443                 ": expected type of operand X to be equal to Result Type"));
5444 }
5445 
TEST_P(ValidateOpenCLStdFractLike,NotPointer)5446 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
5447   const std::string ext_inst_name = GetParam();
5448   std::ostringstream ss;
5449   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
5450   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5451      << " %f32_0 %f32_1\n";
5452 
5453   CompileSuccessfully(GenerateKernelCode(ss.str()));
5454   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5455   EXPECT_THAT(getDiagnosticString(),
5456               HasSubstr("OpenCL.std " + ext_inst_name +
5457                         ": expected the last operand to be a pointer"));
5458 }
5459 
TEST_P(ValidateOpenCLStdFractLike,PointerInvalidStorageClass)5460 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
5461   const std::string ext_inst_name = GetParam();
5462   std::ostringstream ss;
5463   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
5464         "%f32vec8_uniform_constant %u32_1\n";
5465   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
5466 
5467   CompileSuccessfully(GenerateKernelCode(ss.str()));
5468   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5469   EXPECT_THAT(getDiagnosticString(),
5470               HasSubstr("OpenCL.std " + ext_inst_name +
5471                         ": expected storage class of the pointer to be "
5472                         "Generic, CrossWorkgroup, Workgroup or Function"));
5473 }
5474 
TEST_P(ValidateOpenCLStdFractLike,PointerWrongDataType)5475 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
5476   const std::string ext_inst_name = GetParam();
5477   std::ostringstream ss;
5478   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
5479   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5480      << " %f32_0 %var_u32\n";
5481 
5482   CompileSuccessfully(GenerateKernelCode(ss.str()));
5483   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5484   EXPECT_THAT(
5485       getDiagnosticString(),
5486       HasSubstr(
5487           "OpenCL.std " + ext_inst_name +
5488           ": expected data type of the pointer to be equal to Result Type"));
5489 }
5490 
5491 INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
5492                          ::testing::ValuesIn(std::vector<std::string>{
5493                              "fract",
5494                              "modf",
5495                              "sincos",
5496                          }));
5497 
TEST_F(ValidateExtInst,OpenCLStdRemquoSuccess)5498 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
5499   const std::string body = R"(
5500 %var_u32 = OpVariable %u32_ptr_function Function
5501 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
5502 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
5503 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
5504 )";
5505 
5506   CompileSuccessfully(GenerateKernelCode(body));
5507   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5508 }
5509 
TEST_F(ValidateExtInst,OpenCLStdRemquoIntResultType)5510 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
5511   const std::string body = R"(
5512 %var_u32 = OpVariable %u32_ptr_function Function
5513 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
5514 )";
5515 
5516   CompileSuccessfully(GenerateKernelCode(body));
5517   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5518   EXPECT_THAT(
5519       getDiagnosticString(),
5520       HasSubstr("OpenCL.std remquo: "
5521                 "expected Result Type to be a float scalar or vector type"));
5522 }
5523 
TEST_F(ValidateExtInst,OpenCLStdRemquoXWrongType)5524 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
5525   const std::string body = R"(
5526 %var_u32 = OpVariable %f32_ptr_function Function
5527 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
5528 )";
5529 
5530   CompileSuccessfully(GenerateKernelCode(body));
5531   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5532   EXPECT_THAT(
5533       getDiagnosticString(),
5534       HasSubstr("OpenCL.std remquo: "
5535                 "expected type of operand X to be equal to Result Type"));
5536 }
5537 
TEST_F(ValidateExtInst,OpenCLStdRemquoYWrongType)5538 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
5539   const std::string body = R"(
5540 %var_u32 = OpVariable %f32_ptr_function Function
5541 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
5542 )";
5543 
5544   CompileSuccessfully(GenerateKernelCode(body));
5545   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5546   EXPECT_THAT(
5547       getDiagnosticString(),
5548       HasSubstr("OpenCL.std remquo: "
5549                 "expected type of operand Y to be equal to Result Type"));
5550 }
5551 
TEST_F(ValidateExtInst,OpenCLStdRemquoNotPointer)5552 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
5553   const std::string body = R"(
5554 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
5555 )";
5556 
5557   CompileSuccessfully(GenerateKernelCode(body));
5558   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5559   EXPECT_THAT(getDiagnosticString(),
5560               HasSubstr("OpenCL.std remquo: "
5561                         "expected the last operand to be a pointer"));
5562 }
5563 
TEST_F(ValidateExtInst,OpenCLStdRemquoPointerWrongStorageClass)5564 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
5565   const std::string body = R"(
5566 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
5567 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
5568 )";
5569 
5570   CompileSuccessfully(GenerateKernelCode(body));
5571   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5572   EXPECT_THAT(getDiagnosticString(),
5573               HasSubstr("OpenCL.std remquo: "
5574                         "expected storage class of the pointer to be Generic, "
5575                         "CrossWorkgroup, Workgroup or Function"));
5576 }
5577 
TEST_F(ValidateExtInst,OpenCLStdRemquoPointerWrongDataType)5578 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
5579   const std::string body = R"(
5580 %var_f32 = OpVariable %f32_ptr_function Function
5581 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
5582 )";
5583 
5584   CompileSuccessfully(GenerateKernelCode(body));
5585   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5586   EXPECT_THAT(getDiagnosticString(),
5587               HasSubstr("OpenCL.std remquo: "
5588                         "expected data type of the pointer to be a 32-bit int "
5589                         "scalar or vector type"));
5590 }
5591 
TEST_F(ValidateExtInst,OpenCLStdRemquoPointerWrongDataTypeWidth)5592 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
5593   const std::string body = R"(
5594 %var_u64 = OpVariable %u64_ptr_function Function
5595 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
5596 )";
5597   CompileSuccessfully(GenerateKernelCode(body));
5598   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5599   EXPECT_THAT(getDiagnosticString(),
5600               HasSubstr("OpenCL.std remquo: "
5601                         "expected data type of the pointer to be a 32-bit int "
5602                         "scalar or vector type"));
5603 }
5604 
TEST_F(ValidateExtInst,OpenCLStdRemquoPointerWrongNumberOfComponents)5605 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
5606   const std::string body = R"(
5607 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
5608 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
5609 )";
5610 
5611   CompileSuccessfully(GenerateKernelCode(body));
5612   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5613   EXPECT_THAT(
5614       getDiagnosticString(),
5615       HasSubstr("OpenCL.std remquo: "
5616                 "expected data type of the pointer to have the same number "
5617                 "of components as Result Type"));
5618 }
5619 
TEST_P(ValidateOpenCLStdFrexpLike,Success)5620 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
5621   const std::string ext_inst_name = GetParam();
5622   std::ostringstream ss;
5623   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
5624   ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
5625   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5626      << " %f32_0 %var_u32\n";
5627   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5628      << " %f32vec2_01 %var_u32vec2\n";
5629 
5630   CompileSuccessfully(GenerateKernelCode(ss.str()));
5631   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5632 }
5633 
TEST_P(ValidateOpenCLStdFrexpLike,IntResultType)5634 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
5635   const std::string ext_inst_name = GetParam();
5636   std::ostringstream ss;
5637   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
5638   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5639      << " %f32_0 %var_u32\n";
5640 
5641   CompileSuccessfully(GenerateKernelCode(ss.str()));
5642   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5643   EXPECT_THAT(
5644       getDiagnosticString(),
5645       HasSubstr("OpenCL.std " + ext_inst_name +
5646                 ": expected Result Type to be a float scalar or vector type"));
5647 }
5648 
TEST_P(ValidateOpenCLStdFrexpLike,XWrongType)5649 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
5650   const std::string ext_inst_name = GetParam();
5651   std::ostringstream ss;
5652   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
5653   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5654      << " %f64_0 %var_u32\n";
5655 
5656   CompileSuccessfully(GenerateKernelCode(ss.str()));
5657   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5658   EXPECT_THAT(
5659       getDiagnosticString(),
5660       HasSubstr("OpenCL.std " + ext_inst_name +
5661                 ": expected type of operand X to be equal to Result Type"));
5662 }
5663 
TEST_P(ValidateOpenCLStdFrexpLike,NotPointer)5664 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
5665   const std::string ext_inst_name = GetParam();
5666   std::ostringstream ss;
5667   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5668      << " %f32_0 %u32_1\n";
5669 
5670   CompileSuccessfully(GenerateKernelCode(ss.str()));
5671   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5672   EXPECT_THAT(getDiagnosticString(),
5673               HasSubstr("OpenCL.std " + ext_inst_name +
5674                         ": expected the last operand to be a pointer"));
5675 }
5676 
TEST_P(ValidateOpenCLStdFrexpLike,PointerInvalidStorageClass)5677 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
5678   const std::string ext_inst_name = GetParam();
5679   std::ostringstream ss;
5680   ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
5681         "%f32vec8_uniform_constant %u32_1\n";
5682   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
5683 
5684   CompileSuccessfully(GenerateKernelCode(ss.str()));
5685   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5686   EXPECT_THAT(getDiagnosticString(),
5687               HasSubstr("OpenCL.std " + ext_inst_name +
5688                         ": expected storage class of the pointer to be "
5689                         "Generic, CrossWorkgroup, Workgroup or Function"));
5690 }
5691 
TEST_P(ValidateOpenCLStdFrexpLike,PointerDataTypeFloat)5692 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
5693   const std::string ext_inst_name = GetParam();
5694   std::ostringstream ss;
5695   ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
5696   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5697      << " %f32_0 %var_f32\n";
5698 
5699   CompileSuccessfully(GenerateKernelCode(ss.str()));
5700   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5701   EXPECT_THAT(getDiagnosticString(),
5702               HasSubstr("OpenCL.std " + ext_inst_name +
5703                         ": expected data type of the pointer to be a 32-bit "
5704                         "int scalar or vector type"));
5705 }
5706 
TEST_P(ValidateOpenCLStdFrexpLike,PointerDataTypeU64)5707 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
5708   const std::string ext_inst_name = GetParam();
5709   std::ostringstream ss;
5710   ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
5711   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5712      << " %f32_0 %var_u64\n";
5713 
5714   CompileSuccessfully(GenerateKernelCode(ss.str()));
5715   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5716   EXPECT_THAT(getDiagnosticString(),
5717               HasSubstr("OpenCL.std " + ext_inst_name +
5718                         ": expected data type of the pointer to be a 32-bit "
5719                         "int scalar or vector type"));
5720 }
5721 
TEST_P(ValidateOpenCLStdFrexpLike,PointerDataTypeDiffSize)5722 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
5723   const std::string ext_inst_name = GetParam();
5724   std::ostringstream ss;
5725   ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
5726   ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5727      << " %f32vec2_01 %var_u32\n";
5728 
5729   CompileSuccessfully(GenerateKernelCode(ss.str()));
5730   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5731   EXPECT_THAT(getDiagnosticString(),
5732               HasSubstr("OpenCL.std " + ext_inst_name +
5733                         ": expected data type of the pointer to have the same "
5734                         "number of components as Result Type"));
5735 }
5736 
5737 INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
5738                          ::testing::ValuesIn(std::vector<std::string>{
5739                              "frexp",
5740                              "lgamma_r",
5741                          }));
5742 
TEST_F(ValidateExtInst,OpenCLStdIlogbSuccess)5743 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
5744   const std::string body = R"(
5745 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
5746 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
5747 )";
5748 
5749   CompileSuccessfully(GenerateKernelCode(body));
5750   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5751 }
5752 
TEST_F(ValidateExtInst,OpenCLStdIlogbFloatResultType)5753 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
5754   const std::string body = R"(
5755 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
5756 )";
5757 
5758   CompileSuccessfully(GenerateKernelCode(body));
5759   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5760   EXPECT_THAT(
5761       getDiagnosticString(),
5762       HasSubstr(
5763           "OpenCL.std ilogb: "
5764           "expected Result Type to be a 32-bit int scalar or vector type"));
5765 }
5766 
TEST_F(ValidateExtInst,OpenCLStdIlogbIntX)5767 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
5768   const std::string body = R"(
5769 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
5770 )";
5771 
5772   CompileSuccessfully(GenerateKernelCode(body));
5773   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5774   EXPECT_THAT(getDiagnosticString(),
5775               HasSubstr("OpenCL.std ilogb: "
5776                         "expected operand X to be a float scalar or vector"));
5777 }
5778 
TEST_F(ValidateExtInst,OpenCLStdIlogbDiffSize)5779 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
5780   const std::string body = R"(
5781 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
5782 )";
5783 
5784   CompileSuccessfully(GenerateKernelCode(body));
5785   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5786   EXPECT_THAT(getDiagnosticString(),
5787               HasSubstr("OpenCL.std ilogb: "
5788                         "expected operand X to have the same number of "
5789                         "components as Result Type"));
5790 }
5791 
TEST_F(ValidateExtInst,OpenCLStdNanSuccess)5792 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
5793   const std::string body = R"(
5794 %val1 = OpExtInst %f32 %extinst nan %u32_3
5795 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
5796 )";
5797 
5798   CompileSuccessfully(GenerateKernelCode(body));
5799   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5800 }
5801 
TEST_F(ValidateExtInst,OpenCLStdNanIntResultType)5802 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
5803   const std::string body = R"(
5804 %val1 = OpExtInst %u32 %extinst nan %u32_3
5805 )";
5806 
5807   CompileSuccessfully(GenerateKernelCode(body));
5808   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5809   EXPECT_THAT(
5810       getDiagnosticString(),
5811       HasSubstr("OpenCL.std nan: "
5812                 "expected Result Type to be a float scalar or vector type"));
5813 }
5814 
TEST_F(ValidateExtInst,OpenCLStdNanFloatNancode)5815 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
5816   const std::string body = R"(
5817 %val1 = OpExtInst %f32 %extinst nan %f32_3
5818 )";
5819 
5820   CompileSuccessfully(GenerateKernelCode(body));
5821   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5822   EXPECT_THAT(getDiagnosticString(),
5823               HasSubstr("OpenCL.std nan: "
5824                         "expected Nancode to be an int scalar or vector type"));
5825 }
5826 
TEST_F(ValidateExtInst,OpenCLStdNanFloatDiffSize)5827 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
5828   const std::string body = R"(
5829 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
5830 )";
5831 
5832   CompileSuccessfully(GenerateKernelCode(body));
5833   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5834   EXPECT_THAT(getDiagnosticString(),
5835               HasSubstr("OpenCL.std nan: "
5836                         "expected Nancode to have the same number of "
5837                         "components as Result Type"));
5838 }
5839 
TEST_F(ValidateExtInst,OpenCLStdNanFloatDiffBitWidth)5840 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
5841   const std::string body = R"(
5842 %val1 = OpExtInst %f64 %extinst nan %u32_2
5843 )";
5844 
5845   CompileSuccessfully(GenerateKernelCode(body));
5846   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5847   EXPECT_THAT(
5848       getDiagnosticString(),
5849       HasSubstr("OpenCL.std nan: "
5850                 "expected Nancode to have the same bit width as Result Type"));
5851 }
5852 
TEST_P(ValidateOpenCLStdLdexpLike,Success)5853 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
5854   const std::string ext_inst_name = GetParam();
5855   std::ostringstream ss;
5856   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5857      << " %f32_0 %u32_1\n";
5858   ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5859      << " %f32vec2_12 %u32vec2_12\n";
5860 
5861   CompileSuccessfully(GenerateKernelCode(ss.str()));
5862   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5863 }
5864 
TEST_P(ValidateOpenCLStdLdexpLike,IntResultType)5865 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
5866   const std::string ext_inst_name = GetParam();
5867   std::ostringstream ss;
5868   ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5869      << " %f32_0 %u32_1\n";
5870 
5871   CompileSuccessfully(GenerateKernelCode(ss.str()));
5872   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5873   EXPECT_THAT(
5874       getDiagnosticString(),
5875       HasSubstr("OpenCL.std " + ext_inst_name +
5876                 ": expected Result Type to be a float scalar or vector type"));
5877 }
5878 
TEST_P(ValidateOpenCLStdLdexpLike,XWrongType)5879 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
5880   const std::string ext_inst_name = GetParam();
5881   std::ostringstream ss;
5882   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5883      << " %u32_0 %u32_1\n";
5884 
5885   CompileSuccessfully(GenerateKernelCode(ss.str()));
5886   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5887   EXPECT_THAT(
5888       getDiagnosticString(),
5889       HasSubstr("OpenCL.std " + ext_inst_name +
5890                 ": expected type of operand X to be equal to Result Type"));
5891 }
5892 
TEST_P(ValidateOpenCLStdLdexpLike,ExponentNotInt)5893 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
5894   const std::string ext_inst_name = GetParam();
5895   std::ostringstream ss;
5896   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5897      << " %f32_0 %f32_1\n";
5898 
5899   CompileSuccessfully(GenerateKernelCode(ss.str()));
5900   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5901   EXPECT_THAT(
5902       getDiagnosticString(),
5903       HasSubstr("OpenCL.std " + ext_inst_name +
5904                 ": expected the exponent to be a 32-bit int scalar or vector"));
5905 }
5906 
TEST_P(ValidateOpenCLStdLdexpLike,ExponentNotInt32)5907 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
5908   const std::string ext_inst_name = GetParam();
5909   std::ostringstream ss;
5910   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5911      << " %f32_0 %u64_1\n";
5912 
5913   CompileSuccessfully(GenerateKernelCode(ss.str()));
5914   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5915   EXPECT_THAT(
5916       getDiagnosticString(),
5917       HasSubstr("OpenCL.std " + ext_inst_name +
5918                 ": expected the exponent to be a 32-bit int scalar or vector"));
5919 }
5920 
TEST_P(ValidateOpenCLStdLdexpLike,ExponentWrongSize)5921 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
5922   const std::string ext_inst_name = GetParam();
5923   std::ostringstream ss;
5924   ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5925      << " %f32_0 %u32vec2_01\n";
5926 
5927   CompileSuccessfully(GenerateKernelCode(ss.str()));
5928   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5929   EXPECT_THAT(getDiagnosticString(),
5930               HasSubstr("OpenCL.std " + ext_inst_name +
5931                         ": expected the exponent to have the same number of "
5932                         "components as Result Type"));
5933 }
5934 
5935 INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
5936                          ::testing::ValuesIn(std::vector<std::string>{
5937                              "ldexp",
5938                              "pown",
5939                              "rootn",
5940                          }));
5941 
TEST_P(ValidateOpenCLStdUpsampleLike,Success)5942 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
5943   const std::string ext_inst_name = GetParam();
5944   std::ostringstream ss;
5945   ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
5946   ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5947      << " %u16_1 %u16_2\n";
5948   ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
5949      << " %u32_1 %u32_2\n";
5950   ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
5951      << " %u32vec2_01 %u32vec2_01\n";
5952 
5953   CompileSuccessfully(GenerateKernelCode(ss.str()));
5954   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5955 }
5956 
TEST_P(ValidateOpenCLStdUpsampleLike,FloatResultType)5957 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
5958   const std::string ext_inst_name = GetParam();
5959   std::ostringstream ss;
5960   ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
5961      << " %u32_1 %u32_2\n";
5962 
5963   CompileSuccessfully(GenerateKernelCode(ss.str()));
5964   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5965   EXPECT_THAT(
5966       getDiagnosticString(),
5967       HasSubstr("OpenCL.std " + ext_inst_name +
5968                 ": expected Result Type to be an int scalar or vector type"));
5969 }
5970 
TEST_P(ValidateOpenCLStdUpsampleLike,InvalidResultTypeBitWidth)5971 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
5972   const std::string ext_inst_name = GetParam();
5973   std::ostringstream ss;
5974   ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
5975 
5976   CompileSuccessfully(GenerateKernelCode(ss.str()));
5977   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5978   EXPECT_THAT(
5979       getDiagnosticString(),
5980       HasSubstr(
5981           "OpenCL.std " + ext_inst_name +
5982           ": expected bit width of Result Type components to be 16, 32 or 64"));
5983 }
5984 
TEST_P(ValidateOpenCLStdUpsampleLike,LoHiDiffType)5985 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
5986   const std::string ext_inst_name = GetParam();
5987   std::ostringstream ss;
5988   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
5989      << " %u32_1 %u16_2\n";
5990 
5991   CompileSuccessfully(GenerateKernelCode(ss.str()));
5992   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5993   EXPECT_THAT(getDiagnosticString(),
5994               HasSubstr("OpenCL.std " + ext_inst_name +
5995                         ": expected Hi and Lo operands to have the same type"));
5996 }
5997 
TEST_P(ValidateOpenCLStdUpsampleLike,DiffNumberOfComponents)5998 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
5999   const std::string ext_inst_name = GetParam();
6000   std::ostringstream ss;
6001   ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
6002      << " %u32_1 %u32_2\n";
6003 
6004   CompileSuccessfully(GenerateKernelCode(ss.str()));
6005   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6006   EXPECT_THAT(getDiagnosticString(),
6007               HasSubstr("OpenCL.std " + ext_inst_name +
6008                         ": expected Hi and Lo operands to have the same number "
6009                         "of components as Result Type"));
6010 }
6011 
TEST_P(ValidateOpenCLStdUpsampleLike,HiLoWrongBitWidth)6012 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
6013   const std::string ext_inst_name = GetParam();
6014   std::ostringstream ss;
6015   ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
6016      << " %u16_1 %u16_2\n";
6017 
6018   CompileSuccessfully(GenerateKernelCode(ss.str()));
6019   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6020   EXPECT_THAT(
6021       getDiagnosticString(),
6022       HasSubstr("OpenCL.std " + ext_inst_name +
6023                 ": expected bit width of components of Hi and Lo operands to "
6024                 "be half of the bit width of components of Result Type"));
6025 }
6026 
6027 INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
6028                          ::testing::ValuesIn(std::vector<std::string>{
6029                              "u_upsample",
6030                              "s_upsample",
6031                          }));
6032 
TEST_F(ValidateClspvReflection,RequiresNonSemanticExtension)6033 TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) {
6034   const std::string text = R"(
6035 OpCapability Shader
6036 OpCapability Linkage
6037 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
6038 OpMemoryModel Logical GLSL450
6039 )";
6040 
6041   CompileSuccessfully(text);
6042   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6043   EXPECT_THAT(getDiagnosticString(),
6044               HasSubstr("NonSemantic extended instruction sets cannot be "
6045                         "declared without SPV_KHR_non_semantic_info"));
6046 }
6047 
TEST_F(ValidateClspvReflection,MissingVersion)6048 TEST_F(ValidateClspvReflection, MissingVersion) {
6049   const std::string text = R"(
6050 OpCapability Shader
6051 OpCapability Linkage
6052 OpExtension "SPV_KHR_non_semantic_info"
6053 %1 = OpExtInstImport "NonSemantic.ClspvReflection."
6054 OpMemoryModel Logical GLSL450
6055 %2 = OpTypeVoid
6056 %3 = OpTypeInt 32 0
6057 %4 = OpConstant %3 1
6058 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
6059 )";
6060 
6061   CompileSuccessfully(text);
6062   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6063   EXPECT_THAT(getDiagnosticString(),
6064               HasSubstr("Missing NonSemantic.ClspvReflection import version"));
6065 }
6066 
TEST_F(ValidateClspvReflection,BadVersion0)6067 TEST_F(ValidateClspvReflection, BadVersion0) {
6068   const std::string text = R"(
6069 OpCapability Shader
6070 OpCapability Linkage
6071 OpExtension "SPV_KHR_non_semantic_info"
6072 %1 = OpExtInstImport "NonSemantic.ClspvReflection.0"
6073 OpMemoryModel Logical GLSL450
6074 %2 = OpTypeVoid
6075 %3 = OpTypeInt 32 0
6076 %4 = OpConstant %3 1
6077 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
6078 )";
6079 
6080   CompileSuccessfully(text);
6081   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6082   EXPECT_THAT(getDiagnosticString(),
6083               HasSubstr("Unknown NonSemantic.ClspvReflection import version"));
6084 }
6085 
TEST_F(ValidateClspvReflection,BadVersionNotANumber)6086 TEST_F(ValidateClspvReflection, BadVersionNotANumber) {
6087   const std::string text = R"(
6088 OpCapability Shader
6089 OpCapability Linkage
6090 OpExtension "SPV_KHR_non_semantic_info"
6091 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a"
6092 OpMemoryModel Logical GLSL450
6093 %2 = OpTypeVoid
6094 %3 = OpTypeInt 32 0
6095 %4 = OpConstant %3 1
6096 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
6097 )";
6098 
6099   CompileSuccessfully(text);
6100   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6101   EXPECT_THAT(getDiagnosticString(),
6102               HasSubstr("NonSemantic.ClspvReflection import does not encode "
6103                         "the version correctly"));
6104 }
6105 
TEST_F(ValidateClspvReflection,Kernel)6106 TEST_F(ValidateClspvReflection, Kernel) {
6107   const std::string text = R"(
6108 OpCapability Shader
6109 OpExtension "SPV_KHR_non_semantic_info"
6110 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6111 OpMemoryModel Logical GLSL450
6112 OpEntryPoint GLCompute %foo "foo"
6113 OpExecutionMode %foo LocalSize 1 1 1
6114 %foo_name = OpString "foo"
6115 %void = OpTypeVoid
6116 %void_fn = OpTypeFunction %void
6117 %foo = OpFunction %void None %void_fn
6118 %entry = OpLabel
6119 OpReturn
6120 OpFunctionEnd
6121 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6122 )";
6123 
6124   CompileSuccessfully(text);
6125   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6126 }
6127 
TEST_F(ValidateClspvReflection,KernelNotAFunction)6128 TEST_F(ValidateClspvReflection, KernelNotAFunction) {
6129   const std::string text = R"(
6130 OpCapability Shader
6131 OpExtension "SPV_KHR_non_semantic_info"
6132 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6133 OpMemoryModel Logical GLSL450
6134 OpEntryPoint GLCompute %foo "foo"
6135 OpExecutionMode %foo LocalSize 1 1 1
6136 %foo_name = OpString "foo"
6137 %void = OpTypeVoid
6138 %void_fn = OpTypeFunction %void
6139 %foo = OpFunction %void None %void_fn
6140 %entry = OpLabel
6141 OpReturn
6142 OpFunctionEnd
6143 %decl = OpExtInst %void %ext Kernel %foo_name %foo_name
6144 )";
6145 
6146   CompileSuccessfully(text);
6147   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6148   EXPECT_THAT(getDiagnosticString(),
6149               HasSubstr("Kernel does not reference a function"));
6150 }
6151 
TEST_F(ValidateClspvReflection,KernelNotAnEntryPoint)6152 TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) {
6153   const std::string text = R"(
6154 OpCapability Shader
6155 OpExtension "SPV_KHR_non_semantic_info"
6156 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6157 OpMemoryModel Logical GLSL450
6158 OpEntryPoint GLCompute %foo "foo"
6159 OpExecutionMode %foo LocalSize 1 1 1
6160 %foo_name = OpString "foo"
6161 %void = OpTypeVoid
6162 %void_fn = OpTypeFunction %void
6163 %foo = OpFunction %void None %void_fn
6164 %entry = OpLabel
6165 OpReturn
6166 OpFunctionEnd
6167 %bar = OpFunction %void None %void_fn
6168 %bar_entry = OpLabel
6169 OpReturn
6170 OpFunctionEnd
6171 %decl = OpExtInst %void %ext Kernel %bar %foo_name
6172 )";
6173 
6174   CompileSuccessfully(text);
6175   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6176   EXPECT_THAT(getDiagnosticString(),
6177               HasSubstr("Kernel does not reference an entry-point"));
6178 }
6179 
TEST_F(ValidateClspvReflection,KernelNotGLCompute)6180 TEST_F(ValidateClspvReflection, KernelNotGLCompute) {
6181   const std::string text = R"(
6182 OpCapability Shader
6183 OpExtension "SPV_KHR_non_semantic_info"
6184 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6185 OpMemoryModel Logical GLSL450
6186 OpEntryPoint Fragment %foo "foo"
6187 OpExecutionMode %foo OriginUpperLeft
6188 %foo_name = OpString "foo"
6189 %void = OpTypeVoid
6190 %void_fn = OpTypeFunction %void
6191 %foo = OpFunction %void None %void_fn
6192 %entry = OpLabel
6193 OpReturn
6194 OpFunctionEnd
6195 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6196 )";
6197 
6198   CompileSuccessfully(text);
6199   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6200   EXPECT_THAT(getDiagnosticString(),
6201               HasSubstr("Kernel must refer only to GLCompute entry-points"));
6202 }
6203 
TEST_F(ValidateClspvReflection,KernelNameMismatch)6204 TEST_F(ValidateClspvReflection, KernelNameMismatch) {
6205   const std::string text = R"(
6206 OpCapability Shader
6207 OpExtension "SPV_KHR_non_semantic_info"
6208 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6209 OpMemoryModel Logical GLSL450
6210 OpEntryPoint GLCompute %foo "foo"
6211 OpExecutionMode %foo LocalSize 1 1 1
6212 %foo_name = OpString "bar"
6213 %void = OpTypeVoid
6214 %void_fn = OpTypeFunction %void
6215 %foo = OpFunction %void None %void_fn
6216 %entry = OpLabel
6217 OpReturn
6218 OpFunctionEnd
6219 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6220 )";
6221 
6222   CompileSuccessfully(text);
6223   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6224   EXPECT_THAT(getDiagnosticString(),
6225               HasSubstr("Name must match an entry-point for Kernel"));
6226 }
6227 
6228 using ArgumentBasics =
6229     spvtest::ValidateBase<std::pair<std::string, std::string>>;
6230 
6231 INSTANTIATE_TEST_SUITE_P(
6232     ValidateClspvReflectionArgumentKernel, ArgumentBasics,
6233     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
6234         std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"),
6235         std::make_pair("ArgumentUniform", "%int_0 %int_0"),
6236         std::make_pair("ArgumentPodStorageBuffer",
6237                        "%int_0 %int_0 %int_0 %int_4"),
6238         std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"),
6239         std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"),
6240         std::make_pair("ArgumentSampledImage", "%int_0 %int_0"),
6241         std::make_pair("ArgumentStorageImage", "%int_0 %int_0"),
6242         std::make_pair("ArgumentSampler", "%int_0 %int_0"),
6243         std::make_pair("ArgumentWorkgroup", "%int_0 %int_0")}));
6244 
TEST_P(ArgumentBasics,KernelNotAnExtendedInstruction)6245 TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) {
6246   const std::string ext_inst = std::get<0>(GetParam());
6247   const std::string extra = std::get<1>(GetParam());
6248   const std::string text = R"(
6249 OpCapability Shader
6250 OpExtension "SPV_KHR_non_semantic_info"
6251 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6252 OpMemoryModel Logical GLSL450
6253 OpEntryPoint GLCompute %foo "foo"
6254 OpExecutionMode %foo LocalSize 1 1 1
6255 %foo_name = OpString "foo"
6256 %void = OpTypeVoid
6257 %int = OpTypeInt 32 0
6258 %int_0 = OpConstant %int 0
6259 %int_4 = OpConstant %int 4
6260 %void_fn = OpTypeFunction %void
6261 %foo = OpFunction %void None %void_fn
6262 %entry = OpLabel
6263 OpReturn
6264 OpFunctionEnd
6265 %in = OpExtInst %void %ext )" +
6266                            ext_inst + " %int_0 %int_0 " + extra;
6267 
6268   CompileSuccessfully(text);
6269   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6270   EXPECT_THAT(getDiagnosticString(),
6271               HasSubstr("Kernel must be a Kernel extended instruction"));
6272 }
6273 
TEST_P(ArgumentBasics,KernelFromDifferentImport)6274 TEST_P(ArgumentBasics, KernelFromDifferentImport) {
6275   const std::string ext_inst = std::get<0>(GetParam());
6276   const std::string extra = std::get<1>(GetParam());
6277   const std::string text = R"(
6278 OpCapability Shader
6279 OpExtension "SPV_KHR_non_semantic_info"
6280 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6281 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
6282 OpMemoryModel Logical GLSL450
6283 OpEntryPoint GLCompute %foo "foo"
6284 OpExecutionMode %foo LocalSize 1 1 1
6285 %foo_name = OpString "foo"
6286 %void = OpTypeVoid
6287 %int = OpTypeInt 32 0
6288 %int_0 = OpConstant %int 0
6289 %int_4 = OpConstant %int 4
6290 %void_fn = OpTypeFunction %void
6291 %foo = OpFunction %void None %void_fn
6292 %entry = OpLabel
6293 OpReturn
6294 OpFunctionEnd
6295 %decl = OpExtInst %void %ext2 Kernel %foo %foo_name
6296 %in = OpExtInst %void %ext )" +
6297                            ext_inst + " %decl %int_0 " + extra;
6298 
6299   CompileSuccessfully(text);
6300   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6301   EXPECT_THAT(
6302       getDiagnosticString(),
6303       HasSubstr("Kernel must be from the same extended instruction import"));
6304 }
6305 
TEST_P(ArgumentBasics,KernelWrongExtendedInstruction)6306 TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) {
6307   const std::string ext_inst = std::get<0>(GetParam());
6308   const std::string extra = std::get<1>(GetParam());
6309   const std::string text = R"(
6310 OpCapability Shader
6311 OpExtension "SPV_KHR_non_semantic_info"
6312 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6313 OpMemoryModel Logical GLSL450
6314 OpEntryPoint GLCompute %foo "foo"
6315 OpExecutionMode %foo LocalSize 1 1 1
6316 %foo_name = OpString "foo"
6317 %void = OpTypeVoid
6318 %int = OpTypeInt 32 0
6319 %int_0 = OpConstant %int 0
6320 %int_4 = OpConstant %int 4
6321 %void_fn = OpTypeFunction %void
6322 %foo = OpFunction %void None %void_fn
6323 %entry = OpLabel
6324 OpReturn
6325 OpFunctionEnd
6326 %decl = OpExtInst %void %ext ArgumentInfo %foo_name
6327 %in = OpExtInst %void %ext )" +
6328                            ext_inst + " %decl %int_0 " + extra;
6329 
6330   CompileSuccessfully(text);
6331   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6332   EXPECT_THAT(getDiagnosticString(),
6333               HasSubstr("Kernel must be a Kernel extended instruction"));
6334 }
6335 
TEST_P(ArgumentBasics,ArgumentInfo)6336 TEST_P(ArgumentBasics, ArgumentInfo) {
6337   const std::string ext_inst = std::get<0>(GetParam());
6338   const std::string operands = std::get<1>(GetParam());
6339   const std::string text = R"(
6340 OpCapability Shader
6341 OpExtension "SPV_KHR_non_semantic_info"
6342 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6343 OpMemoryModel Logical GLSL450
6344 OpEntryPoint GLCompute %foo "foo"
6345 OpExecutionMode %foo LocalSize 1 1 1
6346 %foo_name = OpString "foo"
6347 %in_name = OpString "in"
6348 %void = OpTypeVoid
6349 %int = OpTypeInt 32 0
6350 %int_0 = OpConstant %int 0
6351 %int_4 = OpConstant %int 4
6352 %void_fn = OpTypeFunction %void
6353 %foo = OpFunction %void None %void_fn
6354 %entry = OpLabel
6355 OpReturn
6356 OpFunctionEnd
6357 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6358 %info = OpExtInst %void %ext ArgumentInfo %in_name
6359 %in = OpExtInst %void %ext )" +
6360                            ext_inst + " %decl %int_0 " + operands + " %info";
6361 
6362   CompileSuccessfully(text);
6363   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6364 }
6365 
TEST_P(ArgumentBasics,ArgumentInfoNotAnExtendedInstruction)6366 TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) {
6367   const std::string ext_inst = std::get<0>(GetParam());
6368   const std::string operands = std::get<1>(GetParam());
6369   const std::string text = R"(
6370 OpCapability Shader
6371 OpExtension "SPV_KHR_non_semantic_info"
6372 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6373 OpMemoryModel Logical GLSL450
6374 OpEntryPoint GLCompute %foo "foo"
6375 OpExecutionMode %foo LocalSize 1 1 1
6376 %foo_name = OpString "foo"
6377 %void = OpTypeVoid
6378 %int = OpTypeInt 32 0
6379 %int_0 = OpConstant %int 0
6380 %int_4 = OpConstant %int 4
6381 %void_fn = OpTypeFunction %void
6382 %foo = OpFunction %void None %void_fn
6383 %entry = OpLabel
6384 OpReturn
6385 OpFunctionEnd
6386 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6387 %in = OpExtInst %void %ext )" +
6388                            ext_inst + " %decl %int_0 " + operands + " %int_0";
6389 
6390   CompileSuccessfully(text);
6391   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6392   EXPECT_THAT(
6393       getDiagnosticString(),
6394       HasSubstr("ArgInfo must be an ArgumentInfo extended instruction"));
6395 }
6396 
TEST_P(ArgumentBasics,ArgumentInfoFromDifferentImport)6397 TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) {
6398   const std::string ext_inst = std::get<0>(GetParam());
6399   const std::string operands = std::get<1>(GetParam());
6400   const std::string text = R"(
6401 OpCapability Shader
6402 OpExtension "SPV_KHR_non_semantic_info"
6403 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6404 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
6405 OpMemoryModel Logical GLSL450
6406 OpEntryPoint GLCompute %foo "foo"
6407 OpExecutionMode %foo LocalSize 1 1 1
6408 %foo_name = OpString "foo"
6409 %in_name = OpString "in"
6410 %void = OpTypeVoid
6411 %int = OpTypeInt 32 0
6412 %int_0 = OpConstant %int 0
6413 %int_4 = OpConstant %int 4
6414 %void_fn = OpTypeFunction %void
6415 %foo = OpFunction %void None %void_fn
6416 %entry = OpLabel
6417 OpReturn
6418 OpFunctionEnd
6419 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6420 %info = OpExtInst %void %ext2 ArgumentInfo %in_name
6421 %in = OpExtInst %void %ext )" +
6422                            ext_inst + " %decl %int_0 " + operands + " %info";
6423 
6424   CompileSuccessfully(text);
6425   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6426   EXPECT_THAT(
6427       getDiagnosticString(),
6428       HasSubstr("ArgInfo must be from the same extended instruction import"));
6429 }
6430 
6431 using Uint32Constant =
6432     spvtest::ValidateBase<std::pair<std::string, std::string>>;
6433 
6434 INSTANTIATE_TEST_SUITE_P(
6435     ValidateClspvReflectionUint32Constants, Uint32Constant,
6436     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
6437         std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0",
6438                        "Ordinal"),
6439         std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0",
6440                        "Ordinal"),
6441         std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0",
6442                        "DescriptorSet"),
6443         std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0",
6444                        "DescriptorSet"),
6445         std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0",
6446                        "Binding"),
6447         std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null",
6448                        "Binding"),
6449         std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0",
6450                        "Ordinal"),
6451         std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"),
6452         std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0",
6453                        "DescriptorSet"),
6454         std::make_pair("ArgumentUniform %decl %int_0 %null %int_0",
6455                        "DescriptorSet"),
6456         std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0",
6457                        "Binding"),
6458         std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"),
6459         std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0",
6460                        "Ordinal"),
6461         std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0",
6462                        "Ordinal"),
6463         std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0",
6464                        "DescriptorSet"),
6465         std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0",
6466                        "DescriptorSet"),
6467         std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0",
6468                        "Binding"),
6469         std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null",
6470                        "Binding"),
6471         std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0",
6472                        "Ordinal"),
6473         std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0",
6474                        "Ordinal"),
6475         std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0",
6476                        "DescriptorSet"),
6477         std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0",
6478                        "DescriptorSet"),
6479         std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0",
6480                        "Binding"),
6481         std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null",
6482                        "Binding"),
6483         std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0",
6484                        "Ordinal"),
6485         std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"),
6486         std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0",
6487                        "DescriptorSet"),
6488         std::make_pair("ArgumentSampler %decl %int_0 %null %int_0",
6489                        "DescriptorSet"),
6490         std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0",
6491                        "Binding"),
6492         std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"),
6493         std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 "
6494                        "%int_0 %int_4",
6495                        "Ordinal"),
6496         std::make_pair(
6497             "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4",
6498             "Ordinal"),
6499         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 "
6500                        "%int_0 %int_4",
6501                        "DescriptorSet"),
6502         std::make_pair(
6503             "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4",
6504             "DescriptorSet"),
6505         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 "
6506                        "%int_0 %int_4",
6507                        "Binding"),
6508         std::make_pair(
6509             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4",
6510             "Binding"),
6511         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
6512                        "%float_0 %int_4",
6513                        "Offset"),
6514         std::make_pair(
6515             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4",
6516             "Offset"),
6517         std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
6518                        "%int_0 %float_0",
6519                        "Size"),
6520         std::make_pair(
6521             "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null",
6522             "Size"),
6523         std::make_pair(
6524             "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
6525             "Ordinal"),
6526         std::make_pair(
6527             "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4",
6528             "Ordinal"),
6529         std::make_pair(
6530             "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
6531             "DescriptorSet"),
6532         std::make_pair(
6533             "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4",
6534             "DescriptorSet"),
6535         std::make_pair(
6536             "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
6537             "Binding"),
6538         std::make_pair(
6539             "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4",
6540             "Binding"),
6541         std::make_pair(
6542             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
6543             "Offset"),
6544         std::make_pair(
6545             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4",
6546             "Offset"),
6547         std::make_pair(
6548             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
6549             "Size"),
6550         std::make_pair(
6551             "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
6552             "Size"),
6553         std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4",
6554                        "Ordinal"),
6555         std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4",
6556                        "Ordinal"),
6557         std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4",
6558                        "Offset"),
6559         std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4",
6560                        "Offset"),
6561         std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0",
6562                        "Size"),
6563         std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null",
6564                        "Size"),
6565         std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4",
6566                        "Ordinal"),
6567         std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4",
6568                        "Ordinal"),
6569         std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4",
6570                        "SpecId"),
6571         std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"),
6572         std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0",
6573                        "ElemSize"),
6574         std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null",
6575                        "ElemSize"),
6576         std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"),
6577         std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"),
6578         std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"),
6579         std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"),
6580         std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"),
6581         std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"),
6582         std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"),
6583         std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"),
6584         std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"),
6585         std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"),
6586         std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"),
6587         std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"),
6588         std::make_pair("SpecConstantWorkDim %float_0", "Dim"),
6589         std::make_pair("SpecConstantWorkDim %null", "Dim"),
6590         std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"),
6591         std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"),
6592         std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"),
6593         std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"),
6594         std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0",
6595                        "Offset"),
6596         std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"),
6597         std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"),
6598         std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"),
6599         std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"),
6600         std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"),
6601         std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"),
6602         std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"),
6603         std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"),
6604         std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"),
6605         std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"),
6606         std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"),
6607         std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"),
6608         std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"),
6609         std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"),
6610         std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"),
6611         std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0",
6612                        "Offset"),
6613         std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"),
6614         std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"),
6615         std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"),
6616         std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data",
6617                        "DescriptorSet"),
6618         std::make_pair("ConstantDataStorageBuffer %null %int_0 %data",
6619                        "DescriptorSet"),
6620         std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data",
6621                        "Binding"),
6622         std::make_pair("ConstantDataStorageBuffer %int_0 %null %data",
6623                        "Binding"),
6624         std::make_pair("ConstantDataUniform %float_0 %int_0 %data",
6625                        "DescriptorSet"),
6626         std::make_pair("ConstantDataUniform %null %int_0 %data",
6627                        "DescriptorSet"),
6628         std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"),
6629         std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"),
6630         std::make_pair("LiteralSampler %float_0 %int_0 %int_4",
6631                        "DescriptorSet"),
6632         std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"),
6633         std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"),
6634         std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"),
6635         std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"),
6636         std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"),
6637         std::make_pair(
6638             "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"),
6639         std::make_pair(
6640             "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"),
6641         std::make_pair(
6642             "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"),
6643         std::make_pair(
6644             "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"),
6645         std::make_pair(
6646             "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"),
6647         std::make_pair(
6648             "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z")}));
6649 
TEST_P(Uint32Constant,Invalid)6650 TEST_P(Uint32Constant, Invalid) {
6651   const std::string ext_inst = std::get<0>(GetParam());
6652   const std::string name = std::get<1>(GetParam());
6653   const std::string text = R"(
6654 OpCapability Shader
6655 OpExtension "SPV_KHR_non_semantic_info"
6656 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6657 OpMemoryModel Logical GLSL450
6658 OpEntryPoint GLCompute %foo "foo"
6659 OpExecutionMode %foo LocalSize 1 1 1
6660 %foo_name = OpString "foo"
6661 %data = OpString "1234"
6662 %void = OpTypeVoid
6663 %int = OpTypeInt 32 0
6664 %int_0 = OpConstant %int 0
6665 %int_1 = OpConstant %int 1
6666 %int_4 = OpConstant %int 4
6667 %null = OpConstantNull %int
6668 %float = OpTypeFloat 32
6669 %float_0 = OpConstant %float 0
6670 %void_fn = OpTypeFunction %void
6671 %foo = OpFunction %void None %void_fn
6672 %entry = OpLabel
6673 OpReturn
6674 OpFunctionEnd
6675 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6676 %inst = OpExtInst %void %ext )" +
6677                            ext_inst;
6678 
6679   CompileSuccessfully(text);
6680   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6681   EXPECT_THAT(
6682       getDiagnosticString(),
6683       HasSubstr(name + " must be a 32-bit unsigned integer OpConstant"));
6684 }
6685 
6686 using StringOperand =
6687     spvtest::ValidateBase<std::pair<std::string, std::string>>;
6688 
6689 INSTANTIATE_TEST_SUITE_P(
6690     ValidateClspvReflectionStringOperands, StringOperand,
6691     ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
6692         std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0",
6693                        "Data"),
6694         std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data")}));
6695 
TEST_P(StringOperand,Invalid)6696 TEST_P(StringOperand, Invalid) {
6697   const std::string ext_inst = std::get<0>(GetParam());
6698   const std::string name = std::get<1>(GetParam());
6699   const std::string text = R"(
6700 OpCapability Shader
6701 OpExtension "SPV_KHR_non_semantic_info"
6702 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
6703 OpMemoryModel Logical GLSL450
6704 OpEntryPoint GLCompute %foo "foo"
6705 OpExecutionMode %foo LocalSize 1 1 1
6706 %foo_name = OpString "foo"
6707 %data = OpString "1234"
6708 %void = OpTypeVoid
6709 %int = OpTypeInt 32 0
6710 %int_0 = OpConstant %int 0
6711 %int_1 = OpConstant %int 1
6712 %int_4 = OpConstant %int 4
6713 %null = OpConstantNull %int
6714 %float = OpTypeFloat 32
6715 %float_0 = OpConstant %float 0
6716 %void_fn = OpTypeFunction %void
6717 %foo = OpFunction %void None %void_fn
6718 %entry = OpLabel
6719 OpReturn
6720 OpFunctionEnd
6721 %decl = OpExtInst %void %ext Kernel %foo %foo_name
6722 %inst = OpExtInst %void %ext )" +
6723                            ext_inst;
6724 
6725   CompileSuccessfully(text);
6726   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6727   EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString"));
6728 }
6729 
6730 }  // namespace
6731 }  // namespace val
6732 }  // namespace spvtools
6733