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