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