1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions.
16 // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
17 // by standard SPIR-V).
18
19 #include <sstream>
20 #include <string>
21 #include <vector>
22
23 #include "gmock/gmock.h"
24 #include "test/unit_spirv.h"
25 #include "test/val/val_fixtures.h"
26
27 namespace spvtools {
28 namespace val {
29 namespace {
30
31 using ::testing::Eq;
32 using ::testing::HasSubstr;
33 using ::testing::Not;
34
35 using ValidateExtInst = spvtest::ValidateBase<bool>;
36 using ValidateOldDebugInfo = spvtest::ValidateBase<std::string>;
37 using ValidateOpenCL100DebugInfo = spvtest::ValidateBase<std::string>;
38 using ValidateLocalDebugInfoOutOfFunction = spvtest::ValidateBase<std::string>;
39 using ValidateOpenCL100DebugInfoDebugTypedef =
40 spvtest::ValidateBase<std::pair<std::string, std::string>>;
41 using ValidateOpenCL100DebugInfoDebugTypeEnum =
42 spvtest::ValidateBase<std::pair<std::string, std::string>>;
43 using ValidateOpenCL100DebugInfoDebugTypeComposite =
44 spvtest::ValidateBase<std::pair<std::string, std::string>>;
45 using ValidateOpenCL100DebugInfoDebugTypeMember =
46 spvtest::ValidateBase<std::pair<std::string, std::string>>;
47 using ValidateOpenCL100DebugInfoDebugTypeInheritance =
48 spvtest::ValidateBase<std::pair<std::string, std::string>>;
49 using ValidateOpenCL100DebugInfoDebugFunction =
50 spvtest::ValidateBase<std::pair<std::string, std::string>>;
51 using ValidateOpenCL100DebugInfoDebugFunctionDeclaration =
52 spvtest::ValidateBase<std::pair<std::string, std::string>>;
53 using ValidateOpenCL100DebugInfoDebugLexicalBlock =
54 spvtest::ValidateBase<std::pair<std::string, std::string>>;
55 using ValidateOpenCL100DebugInfoDebugLocalVariable =
56 spvtest::ValidateBase<std::pair<std::string, std::string>>;
57 using ValidateOpenCL100DebugInfoDebugGlobalVariable =
58 spvtest::ValidateBase<std::pair<std::string, std::string>>;
59 using ValidateOpenCL100DebugInfoDebugDeclare =
60 spvtest::ValidateBase<std::pair<std::string, std::string>>;
61 using ValidateOpenCL100DebugInfoDebugValue =
62 spvtest::ValidateBase<std::pair<std::string, std::string>>;
63 using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>;
64 using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>;
65 using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>;
66 using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>;
67 using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>;
68 using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>;
69 using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>;
70 using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>;
71 using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>;
72 using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>;
73 using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>;
74 using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>;
75 using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>;
76 using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>;
77 using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>;
78 using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>;
79 using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>;
80 using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>;
81 using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>;
82 using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>;
83 using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>;
84 using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>;
85 using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>;
86 using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>;
87 using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>;
88 using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>;
89 using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>;
90 using ValidateClspvReflection = spvtest::ValidateBase<bool>;
91
92 // Returns number of components in Pack/Unpack extended instructions.
93 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
94 // Number of components is assumed to be single-digit.
GetPackedNumComponents(const std::string & ext_inst_name)95 uint32_t GetPackedNumComponents(const std::string& ext_inst_name) {
96 const size_t x_index = ext_inst_name.find_last_of('x');
97 const std::string num_components_str =
98 ext_inst_name.substr(x_index - 1, x_index);
99 return uint32_t(std::stoul(num_components_str));
100 }
101
102 // Returns packed bit width in Pack/Unpack extended instructions.
103 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
GetPackedBitWidth(const std::string & ext_inst_name)104 uint32_t GetPackedBitWidth(const std::string& ext_inst_name) {
105 const size_t x_index = ext_inst_name.find_last_of('x');
106 const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1);
107 return uint32_t(std::stoul(packed_bit_width_str));
108 }
109
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")110 std::string GenerateShaderCode(
111 const std::string& body,
112 const std::string& capabilities_and_extensions = "",
113 const std::string& execution_model = "Fragment") {
114 std::ostringstream ss;
115 ss << R"(
116 OpCapability Shader
117 OpCapability Float16
118 OpCapability Float64
119 OpCapability Int16
120 OpCapability Int64
121 )";
122
123 ss << capabilities_and_extensions;
124 ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
125 ss << "OpMemoryModel Logical GLSL450\n";
126 ss << "OpEntryPoint " << execution_model << " %main \"main\""
127 << " %f32_output"
128 << " %f32vec2_output"
129 << " %u32_output"
130 << " %u32vec2_output"
131 << " %u64_output"
132 << " %f32_input"
133 << " %f32vec2_input"
134 << " %u32_input"
135 << " %u32vec2_input"
136 << " %u64_input"
137 << "\n";
138 if (execution_model == "Fragment") {
139 ss << "OpExecutionMode %main OriginUpperLeft\n";
140 }
141
142 ss << R"(
143 %void = OpTypeVoid
144 %func = OpTypeFunction %void
145 %bool = OpTypeBool
146 %f16 = OpTypeFloat 16
147 %f32 = OpTypeFloat 32
148 %f64 = OpTypeFloat 64
149 %u32 = OpTypeInt 32 0
150 %s32 = OpTypeInt 32 1
151 %u64 = OpTypeInt 64 0
152 %s64 = OpTypeInt 64 1
153 %u16 = OpTypeInt 16 0
154 %s16 = OpTypeInt 16 1
155 %f32vec2 = OpTypeVector %f32 2
156 %f32vec3 = OpTypeVector %f32 3
157 %f32vec4 = OpTypeVector %f32 4
158 %f64vec2 = OpTypeVector %f64 2
159 %f64vec3 = OpTypeVector %f64 3
160 %f64vec4 = OpTypeVector %f64 4
161 %u32vec2 = OpTypeVector %u32 2
162 %u32vec3 = OpTypeVector %u32 3
163 %s32vec2 = OpTypeVector %s32 2
164 %u32vec4 = OpTypeVector %u32 4
165 %s32vec4 = OpTypeVector %s32 4
166 %u64vec2 = OpTypeVector %u64 2
167 %s64vec2 = OpTypeVector %s64 2
168 %f64mat22 = OpTypeMatrix %f64vec2 2
169 %f32mat22 = OpTypeMatrix %f32vec2 2
170 %f32mat23 = OpTypeMatrix %f32vec2 3
171 %f32mat32 = OpTypeMatrix %f32vec3 2
172 %f32mat33 = OpTypeMatrix %f32vec3 3
173
174 %f32_0 = OpConstant %f32 0
175 %f32_1 = OpConstant %f32 1
176 %f32_2 = OpConstant %f32 2
177 %f32_3 = OpConstant %f32 3
178 %f32_4 = OpConstant %f32 4
179 %f32_h = OpConstant %f32 0.5
180 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
181 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
182 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
183 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
184 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
185 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
186
187 %f64_0 = OpConstant %f64 0
188 %f64_1 = OpConstant %f64 1
189 %f64_2 = OpConstant %f64 2
190 %f64_3 = OpConstant %f64 3
191 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
192 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
193 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
194
195 %f16_0 = OpConstant %f16 0
196 %f16_1 = OpConstant %f16 1
197 %f16_h = OpConstant %f16 0.5
198
199 %u32_0 = OpConstant %u32 0
200 %u32_1 = OpConstant %u32 1
201 %u32_2 = OpConstant %u32 2
202 %u32_3 = OpConstant %u32 3
203
204 %s32_0 = OpConstant %s32 0
205 %s32_1 = OpConstant %s32 1
206 %s32_2 = OpConstant %s32 2
207 %s32_3 = OpConstant %s32 3
208
209 %u64_0 = OpConstant %u64 0
210 %u64_1 = OpConstant %u64 1
211 %u64_2 = OpConstant %u64 2
212 %u64_3 = OpConstant %u64 3
213
214 %s64_0 = OpConstant %s64 0
215 %s64_1 = OpConstant %s64 1
216 %s64_2 = OpConstant %s64 2
217 %s64_3 = OpConstant %s64 3
218
219 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
220 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
221
222 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
223 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
224
225 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
226 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
227
228 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
229 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
230
231 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
232 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
233
234 %f32_ptr_output = OpTypePointer Output %f32
235 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
236
237 %u32_ptr_output = OpTypePointer Output %u32
238 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
239
240 %u64_ptr_output = OpTypePointer Output %u64
241
242 %f32_output = OpVariable %f32_ptr_output Output
243 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
244
245 %u32_output = OpVariable %u32_ptr_output Output
246 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
247
248 %u64_output = OpVariable %u64_ptr_output Output
249
250 %f32_ptr_input = OpTypePointer Input %f32
251 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
252
253 %u32_ptr_input = OpTypePointer Input %u32
254 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
255
256 %u64_ptr_input = OpTypePointer Input %u64
257
258 %f32_input = OpVariable %f32_ptr_input Input
259 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
260
261 %u32_input = OpVariable %u32_ptr_input Input
262 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
263
264 %u64_input = OpVariable %u64_ptr_input Input
265
266 %struct_f16_u16 = OpTypeStruct %f16 %u16
267 %struct_f32_f32 = OpTypeStruct %f32 %f32
268 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
269 %struct_f32_u32 = OpTypeStruct %f32 %u32
270 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
271 %struct_u32_f32 = OpTypeStruct %u32 %f32
272 %struct_u32_u32 = OpTypeStruct %u32 %u32
273 %struct_f32_f64 = OpTypeStruct %f32 %f64
274 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
275 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
276
277 %main = OpFunction %void None %func
278 %main_entry = OpLabel
279 )";
280
281 ss << body;
282
283 ss << R"(
284 OpReturn
285 OpFunctionEnd)";
286
287 return ss.str();
288 }
289
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & memory_model="Physical32")290 std::string GenerateKernelCode(
291 const std::string& body,
292 const std::string& capabilities_and_extensions = "",
293 const std::string& memory_model = "Physical32") {
294 std::ostringstream ss;
295 ss << R"(
296 OpCapability Addresses
297 OpCapability Kernel
298 OpCapability Linkage
299 OpCapability GenericPointer
300 OpCapability Int8
301 OpCapability Int16
302 OpCapability Int64
303 OpCapability Float16
304 OpCapability Float64
305 OpCapability Vector16
306 OpCapability Matrix
307 )";
308
309 ss << capabilities_and_extensions;
310 ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n";
311 ss << "OpMemoryModel " << memory_model << " OpenCL\n";
312
313 ss << R"(
314 %void = OpTypeVoid
315 %func = OpTypeFunction %void
316 %bool = OpTypeBool
317 %f16 = OpTypeFloat 16
318 %f32 = OpTypeFloat 32
319 %f64 = OpTypeFloat 64
320 %u32 = OpTypeInt 32 0
321 %u64 = OpTypeInt 64 0
322 %u16 = OpTypeInt 16 0
323 %u8 = OpTypeInt 8 0
324 %f32vec2 = OpTypeVector %f32 2
325 %f32vec3 = OpTypeVector %f32 3
326 %f32vec4 = OpTypeVector %f32 4
327 %f32vec8 = OpTypeVector %f32 8
328 %f16vec8 = OpTypeVector %f16 8
329 %f32vec16 = OpTypeVector %f32 16
330 %f64vec2 = OpTypeVector %f64 2
331 %f64vec3 = OpTypeVector %f64 3
332 %f64vec4 = OpTypeVector %f64 4
333 %u32vec2 = OpTypeVector %u32 2
334 %u32vec3 = OpTypeVector %u32 3
335 %u32vec4 = OpTypeVector %u32 4
336 %u32vec8 = OpTypeVector %u32 8
337 %u64vec2 = OpTypeVector %u64 2
338 %f64mat22 = OpTypeMatrix %f64vec2 2
339 %f32mat22 = OpTypeMatrix %f32vec2 2
340 %f32mat23 = OpTypeMatrix %f32vec2 3
341 %f32mat32 = OpTypeMatrix %f32vec3 2
342 %f32mat33 = OpTypeMatrix %f32vec3 3
343
344 %f32_0 = OpConstant %f32 0
345 %f32_1 = OpConstant %f32 1
346 %f32_2 = OpConstant %f32 2
347 %f32_3 = OpConstant %f32 3
348 %f32_4 = OpConstant %f32 4
349 %f32_h = OpConstant %f32 0.5
350 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
351 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
352 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
353 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
354 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
355 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
356 %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1
357
358 %f64_0 = OpConstant %f64 0
359 %f64_1 = OpConstant %f64 1
360 %f64_2 = OpConstant %f64 2
361 %f64_3 = OpConstant %f64 3
362 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
363 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
364 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
365
366 %f16_0 = OpConstant %f16 0
367 %f16_1 = OpConstant %f16 1
368
369 %u8_0 = OpConstant %u8 0
370 %u8_1 = OpConstant %u8 1
371 %u8_2 = OpConstant %u8 2
372 %u8_3 = OpConstant %u8 3
373
374 %u16_0 = OpConstant %u16 0
375 %u16_1 = OpConstant %u16 1
376 %u16_2 = OpConstant %u16 2
377 %u16_3 = OpConstant %u16 3
378
379 %u32_0 = OpConstant %u32 0
380 %u32_1 = OpConstant %u32 1
381 %u32_2 = OpConstant %u32 2
382 %u32_3 = OpConstant %u32 3
383 %u32_256 = OpConstant %u32 256
384
385 %u64_0 = OpConstant %u64 0
386 %u64_1 = OpConstant %u64 1
387 %u64_2 = OpConstant %u64 2
388 %u64_3 = OpConstant %u64 3
389 %u64_256 = OpConstant %u64 256
390
391 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
392 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
393 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
394 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
395
396 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
397
398 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
399 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
400
401 %struct_f32_f32 = OpTypeStruct %f32 %f32
402 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
403 %struct_f32_u32 = OpTypeStruct %f32 %u32
404 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
405 %struct_u32_f32 = OpTypeStruct %u32 %f32
406 %struct_u32_u32 = OpTypeStruct %u32 %u32
407 %struct_f32_f64 = OpTypeStruct %f32 %f64
408 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
409 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
410
411 %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8
412 %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup
413 %f16_ptr_workgroup = OpTypePointer Workgroup %f16
414
415 %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8
416 %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup
417 %u32_ptr_workgroup = OpTypePointer Workgroup %u32
418
419 %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8
420 %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup
421 %f32_ptr_workgroup = OpTypePointer Workgroup %f32
422
423 %u32arr = OpTypeArray %u32 %u32_256
424 %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr
425 %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup
426 %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32
427
428 %f32arr = OpTypeArray %f32 %u32_256
429 %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr
430 %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup
431 %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32
432
433 %f32vec2arr = OpTypeArray %f32vec2 %u32_256
434 %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr
435 %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup
436 %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2
437
438 %struct_arr = OpTypeArray %struct_f32_f32 %u32_256
439 %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr
440 %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup
441 %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32
442
443 %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8
444 %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant
445 %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16
446
447 %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8
448 %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant
449 %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32
450
451 %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8
452 %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant
453 %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32
454
455 %f16vec8_ptr_input = OpTypePointer Input %f16vec8
456 %f16vec8_input = OpVariable %f16vec8_ptr_input Input
457 %f16_ptr_input = OpTypePointer Input %f16
458
459 %u32vec8_ptr_input = OpTypePointer Input %u32vec8
460 %u32vec8_input = OpVariable %u32vec8_ptr_input Input
461 %u32_ptr_input = OpTypePointer Input %u32
462
463 %f32_ptr_generic = OpTypePointer Generic %f32
464 %u32_ptr_generic = OpTypePointer Generic %u32
465
466 %f32_ptr_function = OpTypePointer Function %f32
467 %f32vec2_ptr_function = OpTypePointer Function %f32vec2
468 %u32_ptr_function = OpTypePointer Function %u32
469 %u64_ptr_function = OpTypePointer Function %u64
470 %u32vec2_ptr_function = OpTypePointer Function %u32vec2
471
472 %u8arr = OpTypeArray %u8 %u32_256
473 %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr
474 %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant
475 %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8
476 %u8_ptr_generic = OpTypePointer Generic %u8
477
478 %main = OpFunction %void None %func
479 %main_entry = OpLabel
480 )";
481
482 ss << body;
483
484 ss << R"(
485 OpReturn
486 OpFunctionEnd)";
487
488 return ss.str();
489 }
490
GenerateShaderCodeForDebugInfo(const std::string & op_string_instructions,const std::string & op_const_instructions,const std::string & debug_instructions_before_main,const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")491 std::string GenerateShaderCodeForDebugInfo(
492 const std::string& op_string_instructions,
493 const std::string& op_const_instructions,
494 const std::string& debug_instructions_before_main, const std::string& body,
495 const std::string& capabilities_and_extensions = "",
496 const std::string& execution_model = "Fragment") {
497 std::ostringstream ss;
498 ss << R"(
499 OpCapability Shader
500 OpCapability Float16
501 OpCapability Float64
502 OpCapability Int16
503 OpCapability Int64
504 )";
505
506 ss << capabilities_and_extensions;
507 ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
508 ss << "OpMemoryModel Logical GLSL450\n";
509 ss << "OpEntryPoint " << execution_model << " %main \"main\""
510 << " %f32_output"
511 << " %f32vec2_output"
512 << " %u32_output"
513 << " %u32vec2_output"
514 << " %u64_output"
515 << " %f32_input"
516 << " %f32vec2_input"
517 << " %u32_input"
518 << " %u32vec2_input"
519 << " %u64_input"
520 << "\n";
521 if (execution_model == "Fragment") {
522 ss << "OpExecutionMode %main OriginUpperLeft\n";
523 }
524
525 ss << op_string_instructions;
526
527 ss << R"(
528 %void = OpTypeVoid
529 %func = OpTypeFunction %void
530 %bool = OpTypeBool
531 %f16 = OpTypeFloat 16
532 %f32 = OpTypeFloat 32
533 %f64 = OpTypeFloat 64
534 %u32 = OpTypeInt 32 0
535 %s32 = OpTypeInt 32 1
536 %u64 = OpTypeInt 64 0
537 %s64 = OpTypeInt 64 1
538 %u16 = OpTypeInt 16 0
539 %s16 = OpTypeInt 16 1
540 %f32vec2 = OpTypeVector %f32 2
541 %f32vec3 = OpTypeVector %f32 3
542 %f32vec4 = OpTypeVector %f32 4
543 %f64vec2 = OpTypeVector %f64 2
544 %f64vec3 = OpTypeVector %f64 3
545 %f64vec4 = OpTypeVector %f64 4
546 %u32vec2 = OpTypeVector %u32 2
547 %u32vec3 = OpTypeVector %u32 3
548 %s32vec2 = OpTypeVector %s32 2
549 %u32vec4 = OpTypeVector %u32 4
550 %s32vec4 = OpTypeVector %s32 4
551 %u64vec2 = OpTypeVector %u64 2
552 %s64vec2 = OpTypeVector %s64 2
553 %f64mat22 = OpTypeMatrix %f64vec2 2
554 %f32mat22 = OpTypeMatrix %f32vec2 2
555 %f32mat23 = OpTypeMatrix %f32vec2 3
556 %f32mat32 = OpTypeMatrix %f32vec3 2
557 %f32mat33 = OpTypeMatrix %f32vec3 3
558
559 %f32_0 = OpConstant %f32 0
560 %f32_1 = OpConstant %f32 1
561 %f32_2 = OpConstant %f32 2
562 %f32_3 = OpConstant %f32 3
563 %f32_4 = OpConstant %f32 4
564 %f32_h = OpConstant %f32 0.5
565 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
566 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
567 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
568 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
569 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
570 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
571
572 %f64_0 = OpConstant %f64 0
573 %f64_1 = OpConstant %f64 1
574 %f64_2 = OpConstant %f64 2
575 %f64_3 = OpConstant %f64 3
576 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
577 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
578 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
579
580 %f16_0 = OpConstant %f16 0
581 %f16_1 = OpConstant %f16 1
582 %f16_h = OpConstant %f16 0.5
583
584 %u32_0 = OpConstant %u32 0
585 %u32_1 = OpConstant %u32 1
586 %u32_2 = OpConstant %u32 2
587 %u32_3 = OpConstant %u32 3
588
589 %s32_0 = OpConstant %s32 0
590 %s32_1 = OpConstant %s32 1
591 %s32_2 = OpConstant %s32 2
592 %s32_3 = OpConstant %s32 3
593
594 %u64_0 = OpConstant %u64 0
595 %u64_1 = OpConstant %u64 1
596 %u64_2 = OpConstant %u64 2
597 %u64_3 = OpConstant %u64 3
598
599 %s64_0 = OpConstant %s64 0
600 %s64_1 = OpConstant %s64 1
601 %s64_2 = OpConstant %s64 2
602 %s64_3 = OpConstant %s64 3
603 )";
604
605 ss << op_const_instructions;
606
607 ss << R"(
608 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
609 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
610
611 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
612 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
613
614 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
615 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
616
617 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
618 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
619
620 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
621 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
622
623 %f32_ptr_output = OpTypePointer Output %f32
624 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
625
626 %u32_ptr_output = OpTypePointer Output %u32
627 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
628
629 %u64_ptr_output = OpTypePointer Output %u64
630
631 %f32_output = OpVariable %f32_ptr_output Output
632 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
633
634 %u32_output = OpVariable %u32_ptr_output Output
635 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
636
637 %u64_output = OpVariable %u64_ptr_output Output
638
639 %f32_ptr_input = OpTypePointer Input %f32
640 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
641
642 %u32_ptr_input = OpTypePointer Input %u32
643 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
644
645 %u64_ptr_input = OpTypePointer Input %u64
646
647 %f32_ptr_function = OpTypePointer Function %f32
648
649 %f32_input = OpVariable %f32_ptr_input Input
650 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
651
652 %u32_input = OpVariable %u32_ptr_input Input
653 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
654
655 %u64_input = OpVariable %u64_ptr_input Input
656
657 %u32_ptr_function = OpTypePointer Function %u32
658
659 %struct_f16_u16 = OpTypeStruct %f16 %u16
660 %struct_f32_f32 = OpTypeStruct %f32 %f32
661 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
662 %struct_f32_u32 = OpTypeStruct %f32 %u32
663 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
664 %struct_u32_f32 = OpTypeStruct %u32 %f32
665 %struct_u32_u32 = OpTypeStruct %u32 %u32
666 %struct_f32_f64 = OpTypeStruct %f32 %f64
667 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
668 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
669 )";
670
671 ss << debug_instructions_before_main;
672
673 ss << R"(
674 %main = OpFunction %void None %func
675 %main_entry = OpLabel
676 )";
677
678 ss << body;
679
680 ss << R"(
681 OpReturn
682 OpFunctionEnd)";
683
684 return ss.str();
685 }
686
TEST_F(ValidateOldDebugInfo,UseDebugInstructionOutOfFunction)687 TEST_F(ValidateOldDebugInfo, UseDebugInstructionOutOfFunction) {
688 const std::string src = R"(
689 %code = OpString "main() {}"
690 )";
691
692 const std::string dbg_inst = R"(
693 %cu = OpExtInst %void %DbgExt DebugCompilationUnit %code 1 1
694 )";
695
696 const std::string extension = R"(
697 %DbgExt = OpExtInstImport "DebugInfo"
698 )";
699
700 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
701 extension, "Vertex"));
702 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
703 }
704
TEST_F(ValidateOpenCL100DebugInfo,UseDebugInstructionOutOfFunction)705 TEST_F(ValidateOpenCL100DebugInfo, UseDebugInstructionOutOfFunction) {
706 const std::string src = R"(
707 %src = OpString "simple.hlsl"
708 %code = OpString "main() {}"
709 )";
710
711 const std::string dbg_inst = R"(
712 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
713 )";
714
715 const std::string extension = R"(
716 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
717 )";
718
719 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
720 extension, "Vertex"));
721 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
722 }
723
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceInFunction)724 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceInFunction) {
725 const std::string src = R"(
726 %src = OpString "simple.hlsl"
727 %code = OpString "main() {}"
728 )";
729
730 const std::string dbg_inst = R"(
731 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
732 )";
733
734 const std::string extension = R"(
735 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
736 )";
737
738 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", "", dbg_inst,
739 extension, "Vertex"));
740 ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
741 EXPECT_THAT(
742 getDiagnosticString(),
743 HasSubstr("Debug info extension instructions other than DebugScope, "
744 "DebugNoScope, DebugDeclare, DebugValue must appear between "
745 "section 9 (types, constants, global variables) and section 10 "
746 "(function declarations)"));
747 }
748
TEST_P(ValidateLocalDebugInfoOutOfFunction,OpenCLDebugInfo100DebugScope)749 TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) {
750 const std::string src = R"(
751 %src = OpString "simple.hlsl"
752 %code = OpString "void main() {}"
753 %void_name = OpString "void"
754 %main_name = OpString "main"
755 %main_linkage_name = OpString "v_main"
756 %int_name = OpString "int"
757 %foo_name = OpString "foo"
758 )";
759
760 const std::string dbg_inst_header = R"(
761 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
762 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
763 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 Signed
764 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
765 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
766 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %int_info %dbg_src 1 1 %main_info FlagIsLocal
767 %expr = OpExtInst %void %DbgExt DebugExpression
768 )";
769
770 const std::string body = R"(
771 %foo = OpVariable %u32_ptr_function Function
772 %foo_val = OpLoad %u32 %foo
773 )";
774
775 const std::string extension = R"(
776 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
777 )";
778
779 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
780 src, "", dbg_inst_header + GetParam(), body, extension, "Vertex"));
781 ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
782 EXPECT_THAT(getDiagnosticString(),
783 HasSubstr("DebugScope, DebugNoScope, DebugDeclare, DebugValue "
784 "of debug info extension must appear in a function "
785 "body"));
786 }
787
788 INSTANTIATE_TEST_SUITE_P(
789 AllLocalDebugInfo, ValidateLocalDebugInfoOutOfFunction,
790 ::testing::ValuesIn(std::vector<std::string>{
791 "%main_scope = OpExtInst %void %DbgExt DebugScope %main_info",
792 "%no_scope = OpExtInst %void %DbgExt DebugNoScope",
793 }));
794
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionForwardReference)795 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionForwardReference) {
796 const std::string src = R"(
797 %src = OpString "simple.hlsl"
798 %code = OpString "void main() {}"
799 %void_name = OpString "void"
800 %main_name = OpString "main"
801 %main_linkage_name = OpString "v_main"
802 )";
803
804 const std::string dbg_inst_header = R"(
805 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
806 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
807 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
808 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
809 )";
810
811 const std::string body = R"(
812 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
813 )";
814
815 const std::string extension = R"(
816 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
817 )";
818
819 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
820 src, "", dbg_inst_header, body, extension, "Vertex"));
821 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
822 }
823
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionMissingOpFunction)824 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionMissingOpFunction) {
825 const std::string src = R"(
826 %src = OpString "simple.hlsl"
827 %code = OpString "void main() {}"
828 %void_name = OpString "void"
829 %main_name = OpString "main"
830 %main_linkage_name = OpString "v_main"
831 )";
832
833 const std::string dbg_inst_header = R"(
834 %dbgNone = OpExtInst %void %DbgExt DebugInfoNone
835 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
836 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
837 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
838 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %dbgNone
839 )";
840
841 const std::string body = R"(
842 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
843 )";
844
845 const std::string extension = R"(
846 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
847 )";
848
849 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
850 src, "", dbg_inst_header, body, extension, "Vertex"));
851 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
852 }
853
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeBeforeOpVariableInFunction)854 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeBeforeOpVariableInFunction) {
855 const std::string src = R"(
856 %src = OpString "simple.hlsl"
857 %code = OpString "float4 main(float arg) {
858 float foo;
859 return float4(0, 0, 0, 0);
860 }
861 "
862 %float_name = OpString "float"
863 %main_name = OpString "main"
864 %main_linkage_name = OpString "v4f_main_f"
865 )";
866
867 const std::string size_const = R"(
868 %int_32 = OpConstant %u32 32
869 )";
870
871 const std::string dbg_inst_header = R"(
872 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
873 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
874 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
875 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
876 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
877 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
878 )";
879
880 const std::string body = R"(
881 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
882 %foo = OpVariable %f32_ptr_function Function
883 )";
884
885 const std::string extension = R"(
886 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
887 )";
888
889 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
890 src, size_const, dbg_inst_header, body, extension, "Vertex"));
891 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
892 }
893
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeSizeDebugInfoNone)894 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeSizeDebugInfoNone) {
895 const std::string src = R"(
896 %src = OpString "simple.hlsl"
897 %code = OpString "OpaqueType foo;
898 main() {}
899 "
900 %ty_name = OpString "struct VS_OUTPUT"
901 )";
902
903 const std::string dbg_inst_header = R"(
904 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
905 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
906 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
907 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
908 )";
909
910 const std::string extension = R"(
911 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
912 )";
913
914 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
915 "", extension, "Vertex"));
916 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
917 }
918
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeForwardReference)919 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeForwardReference) {
920 const std::string src = R"(
921 %src = OpString "simple.hlsl"
922 %code = OpString "struct VS_OUTPUT {
923 float4 pos : SV_POSITION;
924 float4 color : COLOR;
925 };
926 main() {}
927 "
928 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
929 %float_name = OpString "float"
930 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
931 %VS_OUTPUT_color_name = OpString "color : COLOR"
932 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
933 )";
934
935 const std::string size_const = R"(
936 %int_32 = OpConstant %u32 32
937 %int_128 = OpConstant %u32 128
938 )";
939
940 const std::string dbg_inst_header = R"(
941 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
942 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
943 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
944 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
945 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
946 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
947 %VS_OUTPUT_color_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_color_name %v4float_info %dbg_src 3 3 %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
948 )";
949
950 const std::string extension = R"(
951 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
952 )";
953
954 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
955 src, size_const, dbg_inst_header, "", extension, "Vertex"));
956 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
957 }
958
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeMissingReference)959 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeMissingReference) {
960 const std::string src = R"(
961 %src = OpString "simple.hlsl"
962 %code = OpString "struct VS_OUTPUT {
963 float4 pos : SV_POSITION;
964 float4 color : COLOR;
965 };
966 main() {}
967 "
968 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
969 %float_name = OpString "float"
970 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
971 %VS_OUTPUT_color_name = OpString "color : COLOR"
972 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
973 )";
974
975 const std::string size_const = R"(
976 %int_32 = OpConstant %u32 32
977 %int_128 = OpConstant %u32 128
978 )";
979
980 const std::string dbg_inst_header = R"(
981 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
982 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
983 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
984 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
985 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
986 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
987 )";
988
989 const std::string extension = R"(
990 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
991 )";
992
993 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
994 src, size_const, dbg_inst_header, "", extension, "Vertex"));
995 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
996 EXPECT_THAT(getDiagnosticString(),
997 HasSubstr("forward referenced IDs have not been defined"));
998 }
999
TEST_F(ValidateOpenCL100DebugInfo,DebugInstructionWrongResultType)1000 TEST_F(ValidateOpenCL100DebugInfo, DebugInstructionWrongResultType) {
1001 const std::string src = R"(
1002 %src = OpString "simple.hlsl"
1003 %code = OpString "main() {}"
1004 )";
1005
1006 const std::string dbg_inst = R"(
1007 %dbg_src = OpExtInst %bool %DbgExt DebugSource %src %code
1008 )";
1009
1010 const std::string extension = R"(
1011 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1012 )";
1013
1014 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1015 extension, "Vertex"));
1016 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1017 EXPECT_THAT(getDiagnosticString(),
1018 HasSubstr("expected result type must be a result id of "
1019 "OpTypeVoid"));
1020 }
1021
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnit)1022 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnit) {
1023 const std::string src = R"(
1024 %src = OpString "simple.hlsl"
1025 %code = OpString "main() {}"
1026 )";
1027
1028 const std::string dbg_inst = R"(
1029 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1030 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1031 )";
1032
1033 const std::string extension = R"(
1034 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1035 )";
1036
1037 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1038 extension, "Vertex"));
1039 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1040 }
1041
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnitFail)1042 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnitFail) {
1043 const std::string src = R"(
1044 %src = OpString "simple.hlsl"
1045 %code = OpString "main() {}"
1046 )";
1047
1048 const std::string dbg_inst = R"(
1049 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1050 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %src HLSL
1051 )";
1052
1053 const std::string extension = R"(
1054 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1055 )";
1056
1057 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1058 extension, "Vertex"));
1059 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1060 EXPECT_THAT(getDiagnosticString(),
1061 HasSubstr("expected operand Source must be a result id of "
1062 "DebugSource"));
1063 }
1064
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailFile)1065 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailFile) {
1066 const std::string src = R"(
1067 %code = OpString "main() {}"
1068 )";
1069
1070 const std::string dbg_inst = R"(
1071 %dbg_src = OpExtInst %void %DbgExt DebugSource %DbgExt %code
1072 )";
1073
1074 const std::string extension = R"(
1075 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1076 )";
1077
1078 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1079 extension, "Vertex"));
1080 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1081 EXPECT_THAT(getDiagnosticString(),
1082 HasSubstr("expected operand File must be a result id of "
1083 "OpString"));
1084 }
1085
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailSource)1086 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailSource) {
1087 const std::string src = R"(
1088 %src = OpString "simple.hlsl"
1089 )";
1090
1091 const std::string dbg_inst = R"(
1092 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %DbgExt
1093 )";
1094
1095 const std::string extension = R"(
1096 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1097 )";
1098
1099 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1100 extension, "Vertex"));
1101 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1102 EXPECT_THAT(getDiagnosticString(),
1103 HasSubstr("expected operand Text must be a result id of "
1104 "OpString"));
1105 }
1106
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceNoText)1107 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceNoText) {
1108 const std::string src = R"(
1109 %src = OpString "simple.hlsl"
1110 )";
1111
1112 const std::string dbg_inst = R"(
1113 %dbg_src = OpExtInst %void %DbgExt DebugSource %src
1114 )";
1115
1116 const std::string extension = R"(
1117 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1118 )";
1119
1120 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1121 extension, "Vertex"));
1122 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1123 }
1124
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailName)1125 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailName) {
1126 const std::string src = R"(
1127 %src = OpString "simple.hlsl"
1128 %code = OpString "float4 main(float arg) {
1129 float foo;
1130 return float4(0, 0, 0, 0);
1131 }
1132 "
1133 %float_name = OpString "float"
1134 )";
1135
1136 const std::string size_const = R"(
1137 %int_32 = OpConstant %u32 32
1138 )";
1139
1140 const std::string dbg_inst_header = R"(
1141 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1142 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1143 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %int_32 %int_32 Float
1144 )";
1145
1146 const std::string extension = R"(
1147 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1148 )";
1149
1150 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1151 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1152 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1153 EXPECT_THAT(getDiagnosticString(),
1154 HasSubstr("expected operand Name must be a result id of "
1155 "OpString"));
1156 }
1157
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailSize)1158 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailSize) {
1159 const std::string src = R"(
1160 %src = OpString "simple.hlsl"
1161 %code = OpString "float4 main(float arg) {
1162 float foo;
1163 return float4(0, 0, 0, 0);
1164 }
1165 "
1166 %float_name = OpString "float"
1167 )";
1168
1169 const std::string size_const = R"(
1170 %int_32 = OpConstant %u32 32
1171 )";
1172
1173 const std::string dbg_inst_header = R"(
1174 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1175 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1176 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %float_name Float
1177 )";
1178
1179 const std::string extension = R"(
1180 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1181 )";
1182
1183 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1184 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1185 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1186 EXPECT_THAT(getDiagnosticString(),
1187 HasSubstr("expected operand Size must be a result id of "
1188 "OpConstant"));
1189 }
1190
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointer)1191 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointer) {
1192 const std::string src = R"(
1193 %src = OpString "simple.hlsl"
1194 %code = OpString "float4 main(float arg) {
1195 float foo;
1196 return float4(0, 0, 0, 0);
1197 }
1198 "
1199 %float_name = OpString "float"
1200 )";
1201
1202 const std::string size_const = R"(
1203 %int_32 = OpConstant %u32 32
1204 )";
1205
1206 const std::string dbg_inst_header = R"(
1207 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1208 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1209 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1210 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %float_info Function FlagIsLocal
1211 )";
1212
1213 const std::string extension = R"(
1214 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1215 )";
1216
1217 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1218 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1219 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1220 }
1221
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointerFail)1222 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) {
1223 const std::string src = R"(
1224 %src = OpString "simple.hlsl"
1225 %code = OpString "float4 main(float arg) {
1226 float foo;
1227 return float4(0, 0, 0, 0);
1228 }
1229 "
1230 %float_name = OpString "float"
1231 )";
1232
1233 const std::string size_const = R"(
1234 %int_32 = OpConstant %u32 32
1235 )";
1236
1237 const std::string dbg_inst_header = R"(
1238 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1239 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1240 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1241 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %dbg_src Function FlagIsLocal
1242 )";
1243
1244 const std::string extension = R"(
1245 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1246 )";
1247
1248 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1249 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1250 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1251 EXPECT_THAT(getDiagnosticString(),
1252 HasSubstr("expected operand Base Type must be a result id of "
1253 "DebugTypeBasic"));
1254 }
1255
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifier)1256 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) {
1257 const std::string src = R"(
1258 %src = OpString "simple.hlsl"
1259 %code = OpString "float4 main(float arg) {
1260 float foo;
1261 return float4(0, 0, 0, 0);
1262 }
1263 "
1264 %float_name = OpString "float"
1265 )";
1266
1267 const std::string size_const = R"(
1268 %int_32 = OpConstant %u32 32
1269 )";
1270
1271 const std::string dbg_inst_header = R"(
1272 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1273 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1274 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1275 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %float_info ConstType
1276 )";
1277
1278 const std::string extension = R"(
1279 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1280 )";
1281
1282 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1283 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1284 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1285 }
1286
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifierFail)1287 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) {
1288 const std::string src = R"(
1289 %src = OpString "simple.hlsl"
1290 %code = OpString "float4 main(float arg) {
1291 float foo;
1292 return float4(0, 0, 0, 0);
1293 }
1294 "
1295 %float_name = OpString "float"
1296 )";
1297
1298 const std::string size_const = R"(
1299 %int_32 = OpConstant %u32 32
1300 )";
1301
1302 const std::string dbg_inst_header = R"(
1303 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1304 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1305 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1306 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %comp_unit ConstType
1307 )";
1308
1309 const std::string extension = R"(
1310 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1311 )";
1312
1313 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1314 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1315 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1316 EXPECT_THAT(getDiagnosticString(),
1317 HasSubstr("expected operand Base Type must be a result id of "
1318 "DebugTypeBasic"));
1319 }
1320
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArray)1321 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) {
1322 const std::string src = R"(
1323 %src = OpString "simple.hlsl"
1324 %code = OpString "main() {}"
1325 %float_name = OpString "float"
1326 )";
1327
1328 const std::string size_const = R"(
1329 %int_32 = OpConstant %u32 32
1330 )";
1331
1332 const std::string dbg_inst_header = R"(
1333 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1334 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1335 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1336 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %int_32
1337 )";
1338
1339 const std::string extension = R"(
1340 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1341 )";
1342
1343 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1344 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1345 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1346 }
1347
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayWithVariableSize)1348 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayWithVariableSize) {
1349 const std::string src = R"(
1350 %src = OpString "simple.hlsl"
1351 %code = OpString "main() {}"
1352 %float_name = OpString "float"
1353 %int_name = OpString "int"
1354 %main_name = OpString "main"
1355 %foo_name = OpString "foo"
1356 )";
1357
1358 const std::string size_const = R"(
1359 %int_32 = OpConstant %u32 32
1360 )";
1361
1362 const std::string dbg_inst_header = R"(
1363 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1364 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1365 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1366 %uint_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %int_32 Unsigned
1367 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1368 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
1369 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %uint_info %dbg_src 1 1 %main_info FlagIsLocal
1370 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info
1371 )";
1372
1373 const std::string extension = R"(
1374 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1375 )";
1376
1377 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1378 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1379 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1380 }
1381
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailBaseType)1382 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailBaseType) {
1383 const std::string src = R"(
1384 %src = OpString "simple.hlsl"
1385 %code = OpString "main() {}"
1386 %float_name = OpString "float"
1387 )";
1388
1389 const std::string size_const = R"(
1390 %int_32 = OpConstant %u32 32
1391 )";
1392
1393 const std::string dbg_inst_header = R"(
1394 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1395 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1396 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1397 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %comp_unit %int_32
1398 )";
1399
1400 const std::string extension = R"(
1401 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1402 )";
1403
1404 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1405 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1407 EXPECT_THAT(getDiagnosticString(),
1408 HasSubstr("expected operand Base Type is not a valid debug "
1409 "type"));
1410 }
1411
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCount)1412 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCount) {
1413 const std::string src = R"(
1414 %src = OpString "simple.hlsl"
1415 %code = OpString "main() {}"
1416 %float_name = OpString "float"
1417 )";
1418
1419 const std::string size_const = R"(
1420 %int_32 = OpConstant %u32 32
1421 )";
1422
1423 const std::string dbg_inst_header = R"(
1424 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1425 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1426 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1427 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %float_info
1428 )";
1429
1430 const std::string extension = R"(
1431 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1432 )";
1433
1434 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1435 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1436 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1437 EXPECT_THAT(getDiagnosticString(),
1438 HasSubstr("Component Count must be OpConstant with a 32- or "
1439 "64-bits integer scalar type or DebugGlobalVariable or "
1440 "DebugLocalVariable with a 32- or 64-bits unsigned "
1441 "integer scalar type"));
1442 }
1443
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountFloat)1444 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountFloat) {
1445 const std::string src = R"(
1446 %src = OpString "simple.hlsl"
1447 %code = OpString "main() {}"
1448 %float_name = OpString "float"
1449 )";
1450
1451 const std::string size_const = R"(
1452 %int_32 = OpConstant %u32 32
1453 )";
1454
1455 const std::string dbg_inst_header = R"(
1456 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1457 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1458 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1459 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %f32_4
1460 )";
1461
1462 const std::string extension = R"(
1463 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1464 )";
1465
1466 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1467 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1468 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1469 EXPECT_THAT(getDiagnosticString(),
1470 HasSubstr("Component Count must be OpConstant with a 32- or "
1471 "64-bits integer scalar type or DebugGlobalVariable or "
1472 "DebugLocalVariable with a 32- or 64-bits unsigned "
1473 "integer scalar type"));
1474 }
1475
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountZero)1476 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountZero) {
1477 const std::string src = R"(
1478 %src = OpString "simple.hlsl"
1479 %code = OpString "main() {}"
1480 %float_name = OpString "float"
1481 )";
1482
1483 const std::string size_const = R"(
1484 %int_32 = OpConstant %u32 32
1485 )";
1486
1487 const std::string dbg_inst_header = R"(
1488 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1489 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1490 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1491 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_0
1492 )";
1493
1494 const std::string extension = R"(
1495 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1496 )";
1497
1498 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1499 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1500 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1501 EXPECT_THAT(getDiagnosticString(),
1502 HasSubstr("Component Count must be OpConstant with a 32- or "
1503 "64-bits integer scalar type or DebugGlobalVariable or "
1504 "DebugLocalVariable with a 32- or 64-bits unsigned "
1505 "integer scalar type"));
1506 }
1507
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailVariableSizeTypeFloat)1508 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) {
1509 const std::string src = R"(
1510 %src = OpString "simple.hlsl"
1511 %code = OpString "main() {}"
1512 %float_name = OpString "float"
1513 %main_name = OpString "main"
1514 %foo_name = OpString "foo"
1515 )";
1516
1517 const std::string size_const = R"(
1518 %int_32 = OpConstant %u32 32
1519 )";
1520
1521 const std::string dbg_inst_header = R"(
1522 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1523 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1524 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1525 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1526 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
1527 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 1 %main_info FlagIsLocal
1528 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info
1529 )";
1530
1531 const std::string extension = R"(
1532 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1533 )";
1534
1535 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1536 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1537 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1538 EXPECT_THAT(getDiagnosticString(),
1539 HasSubstr("Component Count must be OpConstant with a 32- or "
1540 "64-bits integer scalar type or DebugGlobalVariable or "
1541 "DebugLocalVariable with a 32- or 64-bits unsigned "
1542 "integer scalar type"));
1543 }
1544
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVector)1545 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVector) {
1546 const std::string src = R"(
1547 %src = OpString "simple.hlsl"
1548 %code = OpString "main() {}"
1549 %float_name = OpString "float"
1550 )";
1551
1552 const std::string size_const = R"(
1553 %int_32 = OpConstant %u32 32
1554 )";
1555
1556 const std::string dbg_inst_header = R"(
1557 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1558 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1559 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1560 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1561 )";
1562
1563 const std::string extension = R"(
1564 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1565 )";
1566
1567 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1568 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1569 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1570 }
1571
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFail)1572 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFail) {
1573 const std::string src = R"(
1574 %src = OpString "simple.hlsl"
1575 %code = OpString "main() {}"
1576 %float_name = OpString "float"
1577 )";
1578
1579 const std::string size_const = R"(
1580 %int_32 = OpConstant %u32 32
1581 )";
1582
1583 const std::string dbg_inst_header = R"(
1584 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1585 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1586 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1587 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 4
1588 )";
1589
1590 const std::string extension = R"(
1591 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1592 )";
1593
1594 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1595 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1596 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1597 EXPECT_THAT(getDiagnosticString(),
1598 HasSubstr("expected operand Base Type must be a result id of "
1599 "DebugTypeBasic"));
1600 }
1601
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentZero)1602 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentZero) {
1603 const std::string src = R"(
1604 %src = OpString "simple.hlsl"
1605 %code = OpString "main() {}"
1606 %float_name = OpString "float"
1607 )";
1608
1609 const std::string size_const = R"(
1610 %int_32 = OpConstant %u32 32
1611 )";
1612
1613 const std::string dbg_inst_header = R"(
1614 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1615 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1616 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1617 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 0
1618 )";
1619
1620 const std::string extension = R"(
1621 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1622 )";
1623
1624 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1625 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1627 EXPECT_THAT(getDiagnosticString(),
1628 HasSubstr("expected operand Base Type must be a result id of "
1629 "DebugTypeBasic"));
1630 }
1631
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentFive)1632 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentFive) {
1633 const std::string src = R"(
1634 %src = OpString "simple.hlsl"
1635 %code = OpString "main() {}"
1636 %float_name = OpString "float"
1637 )";
1638
1639 const std::string size_const = R"(
1640 %int_32 = OpConstant %u32 32
1641 )";
1642
1643 const std::string dbg_inst_header = R"(
1644 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1645 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1646 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1647 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 5
1648 )";
1649
1650 const std::string extension = R"(
1651 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1652 )";
1653
1654 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1655 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1656 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1657 EXPECT_THAT(getDiagnosticString(),
1658 HasSubstr("expected operand Base Type must be a result id of "
1659 "DebugTypeBasic"));
1660 }
1661
TEST_F(ValidateOpenCL100DebugInfo,DebugTypedef)1662 TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) {
1663 const std::string src = R"(
1664 %src = OpString "simple.hlsl"
1665 %code = OpString "main() {}"
1666 %float_name = OpString "float"
1667 %foo_name = OpString "foo"
1668 )";
1669
1670 const std::string size_const = R"(
1671 %int_32 = OpConstant %u32 32
1672 )";
1673
1674 const std::string dbg_inst_header = R"(
1675 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1676 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1677 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1678 %foo_info = OpExtInst %void %DbgExt DebugTypedef %foo_name %float_info %dbg_src 1 1 %comp_unit
1679 )";
1680
1681 const std::string extension = R"(
1682 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1683 )";
1684
1685 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1686 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1688 }
1689
TEST_P(ValidateOpenCL100DebugInfoDebugTypedef,Fail)1690 TEST_P(ValidateOpenCL100DebugInfoDebugTypedef, Fail) {
1691 const std::string src = R"(
1692 %src = OpString "simple.hlsl"
1693 %code = OpString "main() {}"
1694 %float_name = OpString "float"
1695 %foo_name = OpString "foo"
1696 )";
1697
1698 const std::string size_const = R"(
1699 %int_32 = OpConstant %u32 32
1700 )";
1701
1702 const auto& param = GetParam();
1703
1704 std::ostringstream ss;
1705 ss << R"(
1706 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1707 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1708 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1709 %foo_info = OpExtInst %void %DbgExt DebugTypedef )";
1710 ss << param.first;
1711
1712 const std::string extension = R"(
1713 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1714 )";
1715
1716 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1717 "", extension, "Vertex"));
1718 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1719 EXPECT_THAT(getDiagnosticString(),
1720 HasSubstr("expected operand " + param.second +
1721 " must be a result id of "));
1722 }
1723
1724 INSTANTIATE_TEST_SUITE_P(
1725 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypedef,
1726 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1727 std::make_pair(R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit)",
1728 "Name"),
1729 std::make_pair(R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit)",
1730 "Base Type"),
1731 std::make_pair(R"(%foo_name %float_info %comp_unit 1 1 %comp_unit)",
1732 "Source"),
1733 std::make_pair(R"(%foo_name %float_info %dbg_src 1 1 %dbg_src)",
1734 "Parent"),
1735 }));
1736
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunction)1737 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunction) {
1738 const std::string src = R"(
1739 %src = OpString "simple.hlsl"
1740 %code = OpString "main() {}"
1741 %main_name = OpString "main"
1742 %main_linkage_name = OpString "v_main"
1743 %float_name = OpString "float"
1744 )";
1745
1746 const std::string size_const = R"(
1747 %int_32 = OpConstant %u32 32
1748 )";
1749
1750 const std::string dbg_inst_header = R"(
1751 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1752 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1753 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1754 %main_type_info1 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1755 %main_type_info2 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info
1756 %main_type_info3 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %float_info
1757 %main_type_info4 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void %float_info %float_info
1758 )";
1759
1760 const std::string extension = R"(
1761 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1762 )";
1763
1764 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1765 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1766 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1767 }
1768
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailReturn)1769 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailReturn) {
1770 const std::string src = R"(
1771 %src = OpString "simple.hlsl"
1772 %code = OpString "main() {}"
1773 %main_name = OpString "main"
1774 %main_linkage_name = OpString "v_main"
1775 %float_name = OpString "float"
1776 )";
1777
1778 const std::string size_const = R"(
1779 %int_32 = OpConstant %u32 32
1780 )";
1781
1782 const std::string dbg_inst_header = R"(
1783 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1784 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1785 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1786 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %dbg_src %float_info
1787 )";
1788
1789 const std::string extension = R"(
1790 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1791 )";
1792
1793 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1794 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1795 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1796 EXPECT_THAT(
1797 getDiagnosticString(),
1798 HasSubstr("expected operand Return Type is not a valid debug type"));
1799 }
1800
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailParam)1801 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailParam) {
1802 const std::string src = R"(
1803 %src = OpString "simple.hlsl"
1804 %code = OpString "main() {}"
1805 %main_name = OpString "main"
1806 %main_linkage_name = OpString "v_main"
1807 %float_name = OpString "float"
1808 )";
1809
1810 const std::string size_const = R"(
1811 %int_32 = OpConstant %u32 32
1812 )";
1813
1814 const std::string dbg_inst_header = R"(
1815 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1816 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1817 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1818 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %void
1819 )";
1820
1821 const std::string extension = R"(
1822 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1823 )";
1824
1825 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1826 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1827 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1828 EXPECT_THAT(
1829 getDiagnosticString(),
1830 HasSubstr("expected operand Parameter Types is not a valid debug type"));
1831 }
1832
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeEnum)1833 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeEnum) {
1834 const std::string src = R"(
1835 %src = OpString "simple.hlsl"
1836 %code = OpString "main() {}"
1837 %float_name = OpString "float"
1838 %foo_name = OpString "foo"
1839 )";
1840
1841 const std::string size_const = R"(
1842 %int_32 = OpConstant %u32 32
1843 )";
1844
1845 const std::string dbg_inst_header = R"(
1846 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1847 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1848 %none = OpExtInst %void %DbgExt DebugInfoNone
1849 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1850 %foo_info1 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1851 %foo_info2 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1852 %foo_info3 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic
1853 )";
1854
1855 const std::string extension = R"(
1856 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1857 )";
1858
1859 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1860 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1861 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1862 }
1863
TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum,Fail)1864 TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum, Fail) {
1865 const std::string src = R"(
1866 %src = OpString "simple.hlsl"
1867 %code = OpString "main() {}"
1868 %float_name = OpString "float"
1869 %foo_name = OpString "foo"
1870 )";
1871
1872 const std::string size_const = R"(
1873 %int_32 = OpConstant %u32 32
1874 )";
1875
1876 const auto& param = GetParam();
1877
1878 std::ostringstream ss;
1879 ss << R"(
1880 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1881 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1882 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1883 %foo_info = OpExtInst %void %DbgExt DebugTypeEnum )";
1884 ss << param.first;
1885
1886 const std::string extension = R"(
1887 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1888 )";
1889
1890 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1891 "", extension, "Vertex"));
1892 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1893 EXPECT_THAT(getDiagnosticString(),
1894 HasSubstr("expected operand " + param.second));
1895 }
1896
1897 INSTANTIATE_TEST_SUITE_P(
1898 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeEnum,
1899 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1900 std::make_pair(
1901 R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1902 "Name"),
1903 std::make_pair(
1904 R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1905 "Underlying Types"),
1906 std::make_pair(
1907 R"(%foo_name %float_info %comp_unit 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1908 "Source"),
1909 std::make_pair(
1910 R"(%foo_name %float_info %dbg_src 1 1 %dbg_src %int_32 FlagIsPublic %u32_0 %foo_name)",
1911 "Parent"),
1912 std::make_pair(
1913 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %void FlagIsPublic %u32_0 %foo_name)",
1914 "Size"),
1915 std::make_pair(
1916 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %u32_0 FlagIsPublic %u32_0 %foo_name)",
1917 "Size"),
1918 std::make_pair(
1919 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %foo_name %foo_name)",
1920 "Value"),
1921 std::make_pair(
1922 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %u32_1)",
1923 "Name"),
1924 }));
1925
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeFunctionAndInheritance)1926 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeFunctionAndInheritance) {
1927 const std::string src = R"(
1928 %src = OpString "simple.hlsl"
1929 %code = OpString "struct VS_OUTPUT {
1930 float4 pos : SV_POSITION;
1931 };
1932 struct foo : VS_OUTPUT {
1933 };
1934 main() {}
1935 "
1936 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1937 %float_name = OpString "float"
1938 %foo_name = OpString "foo"
1939 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1940 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1941 %main_name = OpString "main"
1942 %main_linkage_name = OpString "v4f_main_f"
1943 )";
1944
1945 const std::string size_const = R"(
1946 %int_32 = OpConstant %u32 32
1947 %int_128 = OpConstant %u32 128
1948 )";
1949
1950 const std::string dbg_inst_header = R"(
1951 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1952 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1953 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child
1954 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1955 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1956 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
1957 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
1958 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
1959 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
1960 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
1961 )";
1962
1963 const std::string extension = R"(
1964 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1965 )";
1966
1967 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1968 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1969 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1970 }
1971
TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite,Fail)1972 TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite, Fail) {
1973 const std::string src = R"(
1974 %src = OpString "simple.hlsl"
1975 %code = OpString "struct VS_OUTPUT {
1976 float4 pos : SV_POSITION;
1977 };
1978 struct foo : VS_OUTPUT {
1979 };
1980 main() {}
1981 "
1982 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1983 %float_name = OpString "float"
1984 %foo_name = OpString "foo"
1985 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1986 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1987 %main_name = OpString "main"
1988 %main_linkage_name = OpString "v4f_main_f"
1989 )";
1990
1991 const std::string size_const = R"(
1992 %int_32 = OpConstant %u32 32
1993 %int_128 = OpConstant %u32 128
1994 )";
1995
1996 const auto& param = GetParam();
1997
1998 std::ostringstream ss;
1999 ss << R"(
2000 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2001 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2002 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite )";
2003 ss << param.first;
2004 ss << R"(
2005 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2006 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
2007 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
2008 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
2009 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
2010 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2011 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
2012 )";
2013
2014 const std::string extension = R"(
2015 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2016 )";
2017
2018 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2019 "", extension, "Vertex"));
2020 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2021 EXPECT_THAT(getDiagnosticString(),
2022 HasSubstr("expected operand " + param.second + " must be "));
2023 }
2024
2025 INSTANTIATE_TEST_SUITE_P(
2026 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeComposite,
2027 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2028 std::make_pair(
2029 R"(%dbg_src Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2030 "Name"),
2031 std::make_pair(
2032 R"(%VS_OUTPUT_name Structure %comp_unit 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2033 "Source"),
2034 std::make_pair(
2035 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %dbg_src %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2036 "Parent"),
2037 std::make_pair(
2038 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %int_128 %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2039 "Linkage Name"),
2040 std::make_pair(
2041 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %dbg_src FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2042 "Size"),
2043 std::make_pair(
2044 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %dbg_src %main_info %child)",
2045 "Members"),
2046 std::make_pair(
2047 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %dbg_src %child)",
2048 "Members"),
2049 std::make_pair(
2050 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %dbg_src)",
2051 "Members"),
2052 }));
2053
TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember,Fail)2054 TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember, Fail) {
2055 const std::string src = R"(
2056 %src = OpString "simple.hlsl"
2057 %code = OpString "struct VS_OUTPUT {
2058 float pos : SV_POSITION;
2059 };
2060 main() {}
2061 "
2062 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
2063 %float_name = OpString "float"
2064 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
2065 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
2066 )";
2067
2068 const std::string size_const = R"(
2069 %int_32 = OpConstant %u32 32
2070 )";
2071
2072 const auto& param = GetParam();
2073
2074 std::ostringstream ss;
2075 ss << R"(
2076 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2077 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2078 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_32 FlagIsPublic %VS_OUTPUT_pos_info
2079 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2080 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember )";
2081 ss << param.first;
2082
2083 const std::string extension = R"(
2084 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2085 )";
2086
2087 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2088 "", extension, "Vertex"));
2089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2090 if (!param.second.empty()) {
2091 EXPECT_THAT(getDiagnosticString(),
2092 HasSubstr("expected operand " + param.second +
2093 " must be a result id of "));
2094 }
2095 }
2096
2097 INSTANTIATE_TEST_SUITE_P(
2098 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeMember,
2099 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2100 std::make_pair(
2101 R"(%dbg_src %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2102 "Name"),
2103 std::make_pair(
2104 R"(%VS_OUTPUT_pos_name %dbg_src %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2105 ""),
2106 std::make_pair(
2107 R"(%VS_OUTPUT_pos_name %float_info %float_info 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2108 "Source"),
2109 std::make_pair(
2110 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %float_info %u32_0 %int_32 FlagIsPublic)",
2111 "Parent"),
2112 std::make_pair(
2113 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %void %int_32 FlagIsPublic)",
2114 "Offset"),
2115 std::make_pair(
2116 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2117 "Size"),
2118 }));
2119
TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance,Fail)2120 TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance, Fail) {
2121 const std::string src = R"(
2122 %src = OpString "simple.hlsl"
2123 %code = OpString "struct VS_OUTPUT {};
2124 struct foo : VS_OUTPUT {};
2125 "
2126 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
2127 %foo_name = OpString "foo"
2128 )";
2129
2130 const auto& param = GetParam();
2131
2132 std::ostringstream ss;
2133 ss << R"(
2134 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2135 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2136 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_name %u32_0 FlagIsPublic %child
2137 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2138 %bar_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Union %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2139 %child = OpExtInst %void %DbgExt DebugTypeInheritance )"
2140 << param.first;
2141
2142 const std::string extension = R"(
2143 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2144 )";
2145
2146 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2147 extension, "Vertex"));
2148 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2149 EXPECT_THAT(getDiagnosticString(),
2150 HasSubstr("expected operand " + param.second));
2151 }
2152
2153 INSTANTIATE_TEST_SUITE_P(
2154 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeInheritance,
2155 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2156 std::make_pair(R"(%dbg_src %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2157 "Child must be a result id of"),
2158 std::make_pair(R"(%foo_info %dbg_src %u32_0 %u32_0 FlagIsPublic)",
2159 "Parent must be a result id of"),
2160 std::make_pair(
2161 R"(%bar_info %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2162 "Child must be class or struct debug type"),
2163 std::make_pair(R"(%foo_info %bar_info %u32_0 %u32_0 FlagIsPublic)",
2164 "Parent must be class or struct debug type"),
2165 std::make_pair(R"(%foo_info %VS_OUTPUT_info %void %u32_0 FlagIsPublic)",
2166 "Offset"),
2167 std::make_pair(R"(%foo_info %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2168 "Size"),
2169 }));
TEST_P(ValidateGlslStd450SqrtLike,Success)2170 TEST_P(ValidateGlslStd450SqrtLike, Success) {
2171 const std::string ext_inst_name = GetParam();
2172 std::ostringstream ss;
2173 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
2174 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
2175 << " %f32vec2_01\n";
2176 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
2177 CompileSuccessfully(GenerateShaderCode(ss.str()));
2178 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2179 }
2180
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionDeclaration)2181 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionDeclaration) {
2182 const std::string src = R"(
2183 %src = OpString "simple.hlsl"
2184 %code = OpString "struct VS_OUTPUT {
2185 float4 pos : SV_POSITION;
2186 };
2187 main() {}
2188 "
2189 %main_name = OpString "main"
2190 %main_linkage_name = OpString "v4f_main_f"
2191 )";
2192
2193 const std::string dbg_inst_header = R"(
2194 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2195 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2196 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2197 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2198 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)";
2199
2200 const std::string extension = R"(
2201 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2202 )";
2203
2204 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2205 "", extension, "Vertex"));
2206 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2207 }
2208
TEST_P(ValidateOpenCL100DebugInfoDebugFunction,Fail)2209 TEST_P(ValidateOpenCL100DebugInfoDebugFunction, Fail) {
2210 const std::string src = R"(
2211 %src = OpString "simple.hlsl"
2212 %code = OpString "struct VS_OUTPUT {
2213 float4 pos : SV_POSITION;
2214 };
2215 main() {}
2216 "
2217 %main_name = OpString "main"
2218 %main_linkage_name = OpString "v4f_main_f"
2219 )";
2220
2221 const auto& param = GetParam();
2222
2223 std::ostringstream ss;
2224 ss << R"(
2225 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2226 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2227 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2228 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2229 %main_info = OpExtInst %void %DbgExt DebugFunction )"
2230 << param.first;
2231
2232 const std::string extension = R"(
2233 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2234 )";
2235
2236 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2237 extension, "Vertex"));
2238 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2239 EXPECT_THAT(getDiagnosticString(),
2240 HasSubstr("expected operand " + param.second));
2241 }
2242
2243 INSTANTIATE_TEST_SUITE_P(
2244 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugFunction,
2245 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2246 std::make_pair(
2247 R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2248 "Name"),
2249 std::make_pair(
2250 R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2251 "Type"),
2252 std::make_pair(
2253 R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2254 "Source"),
2255 std::make_pair(
2256 R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic 13 %main)",
2257 "Parent"),
2258 std::make_pair(
2259 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic 13 %main)",
2260 "Linkage Name"),
2261 std::make_pair(
2262 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %void)",
2263 "Function"),
2264 std::make_pair(
2265 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main %dbg_src)",
2266 "Declaration"),
2267 }));
2268
TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration,Fail)2269 TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration, Fail) {
2270 const std::string src = R"(
2271 %src = OpString "simple.hlsl"
2272 %code = OpString "struct VS_OUTPUT {
2273 float4 pos : SV_POSITION;
2274 };
2275 main() {}
2276 "
2277 %main_name = OpString "main"
2278 %main_linkage_name = OpString "v4f_main_f"
2279 )";
2280
2281 const auto& param = GetParam();
2282
2283 std::ostringstream ss;
2284 ss << R"(
2285 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2286 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2287 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2288 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration )"
2289 << param.first;
2290
2291 const std::string extension = R"(
2292 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2293 )";
2294
2295 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2296 extension, "Vertex"));
2297 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2298 EXPECT_THAT(getDiagnosticString(),
2299 HasSubstr("expected operand " + param.second));
2300 }
2301
2302 INSTANTIATE_TEST_SUITE_P(
2303 AllOpenCL100DebugInfoFail,
2304 ValidateOpenCL100DebugInfoDebugFunctionDeclaration,
2305 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2306 std::make_pair(
2307 R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2308 "Name"),
2309 std::make_pair(
2310 R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2311 "Type"),
2312 std::make_pair(
2313 R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2314 "Source"),
2315 std::make_pair(
2316 R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic)",
2317 "Parent"),
2318 std::make_pair(
2319 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic)",
2320 "Linkage Name"),
2321 }));
2322
TEST_F(ValidateOpenCL100DebugInfo,DebugLexicalBlock)2323 TEST_F(ValidateOpenCL100DebugInfo, DebugLexicalBlock) {
2324 const std::string src = R"(
2325 %src = OpString "simple.hlsl"
2326 %code = OpString "main() {}"
2327 %main_name = OpString "main"
2328 )";
2329
2330 const std::string dbg_inst_header = R"(
2331 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2332 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2333 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock %dbg_src 1 1 %comp_unit %main_name)";
2334
2335 const std::string extension = R"(
2336 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2337 )";
2338
2339 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2340 "", extension, "Vertex"));
2341 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2342 }
2343
TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock,Fail)2344 TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock, Fail) {
2345 const std::string src = R"(
2346 %src = OpString "simple.hlsl"
2347 %code = OpString "main() {}"
2348 %main_name = OpString "main"
2349 )";
2350
2351 const auto& param = GetParam();
2352
2353 std::ostringstream ss;
2354 ss << R"(
2355 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2356 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2357 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock )"
2358 << param.first;
2359
2360 const std::string extension = R"(
2361 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2362 )";
2363
2364 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2365 extension, "Vertex"));
2366 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2367 EXPECT_THAT(getDiagnosticString(),
2368 HasSubstr("expected operand " + param.second));
2369 }
2370
2371 INSTANTIATE_TEST_SUITE_P(
2372 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLexicalBlock,
2373 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2374 std::make_pair(R"(%comp_unit 1 1 %comp_unit %main_name)", "Source"),
2375 std::make_pair(R"(%dbg_src 1 1 %dbg_src %main_name)", "Parent"),
2376 std::make_pair(R"(%dbg_src 1 1 %comp_unit %void)", "Name"),
2377 }));
2378
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailScope)2379 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailScope) {
2380 const std::string src = R"(
2381 %src = OpString "simple.hlsl"
2382 %code = OpString "void main() {}"
2383 )";
2384
2385 const std::string dbg_inst_header = R"(
2386 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2387 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2388 )";
2389
2390 const std::string body = R"(
2391 %main_scope = OpExtInst %void %DbgExt DebugScope %dbg_src
2392 )";
2393
2394 const std::string extension = R"(
2395 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2396 )";
2397
2398 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2399 src, "", dbg_inst_header, body, extension, "Vertex"));
2400 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2401 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope"));
2402 }
2403
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailInlinedAt)2404 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailInlinedAt) {
2405 const std::string src = R"(
2406 %src = OpString "simple.hlsl"
2407 %code = OpString "void main() {}"
2408 )";
2409
2410 const std::string dbg_inst_header = R"(
2411 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2412 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2413 )";
2414
2415 const std::string body = R"(
2416 %main_scope = OpExtInst %void %DbgExt DebugScope %comp_unit %dbg_src
2417 )";
2418
2419 const std::string extension = R"(
2420 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2421 )";
2422
2423 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2424 src, "", dbg_inst_header, body, extension, "Vertex"));
2425 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2426 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined At"));
2427 }
2428
TEST_F(ValidateOpenCL100DebugInfo,DebugLocalVariable)2429 TEST_F(ValidateOpenCL100DebugInfo, DebugLocalVariable) {
2430 const std::string src = R"(
2431 %src = OpString "simple.hlsl"
2432 %code = OpString "void main() { float foo; }"
2433 %float_name = OpString "float"
2434 %foo_name = OpString "foo"
2435 )";
2436
2437 const std::string size_const = R"(
2438 %int_32 = OpConstant %u32 32
2439 )";
2440
2441 const std::string dbg_inst_header = R"(
2442 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2443 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2444 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2445 %foo = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2446 )";
2447
2448 const std::string extension = R"(
2449 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2450 )";
2451
2452 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2453 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2454 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2455 }
2456
TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable,Fail)2457 TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable, Fail) {
2458 const std::string src = R"(
2459 %src = OpString "simple.hlsl"
2460 %code = OpString "void main() { float foo; }"
2461 %float_name = OpString "float"
2462 %foo_name = OpString "foo"
2463 )";
2464
2465 const std::string size_const = R"(
2466 %int_32 = OpConstant %u32 32
2467 )";
2468
2469 const auto& param = GetParam();
2470
2471 std::ostringstream ss;
2472 ss << R"(
2473 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2474 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2475 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2476 %foo = OpExtInst %void %DbgExt DebugLocalVariable )"
2477 << param.first;
2478
2479 const std::string extension = R"(
2480 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2481 )";
2482
2483 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2484 "", extension, "Vertex"));
2485 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2486 EXPECT_THAT(getDiagnosticString(),
2487 HasSubstr("expected operand " + param.second));
2488 }
2489
2490 INSTANTIATE_TEST_SUITE_P(
2491 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLocalVariable,
2492 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2493 std::make_pair(
2494 R"(%void %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2495 "Name"),
2496 std::make_pair(
2497 R"(%foo_name %dbg_src %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2498 "Type"),
2499 std::make_pair(
2500 R"(%foo_name %float_info %comp_unit 1 10 %comp_unit FlagIsLocal 0)",
2501 "Source"),
2502 std::make_pair(
2503 R"(%foo_name %float_info %dbg_src 1 10 %dbg_src FlagIsLocal 0)",
2504 "Parent"),
2505 }));
2506
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclare)2507 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclare) {
2508 const std::string src = R"(
2509 %src = OpString "simple.hlsl"
2510 %code = OpString "void main() { float foo; }"
2511 %float_name = OpString "float"
2512 %foo_name = OpString "foo"
2513 )";
2514
2515 const std::string size_const = R"(
2516 %int_32 = OpConstant %u32 32
2517 )";
2518
2519 const std::string dbg_inst_header = R"(
2520 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2521 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2522 %null_expr = OpExtInst %void %DbgExt DebugExpression
2523 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2524 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2525 )";
2526
2527 const std::string body = R"(
2528 %foo = OpVariable %f32_ptr_function Function
2529 %decl = OpExtInst %void %DbgExt DebugDeclare %foo_info %foo %null_expr
2530 )";
2531
2532 const std::string extension = R"(
2533 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2534 )";
2535
2536 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2537 src, size_const, dbg_inst_header, body, extension, "Vertex"));
2538 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2539 }
2540
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclareParam)2541 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclareParam) {
2542 CompileSuccessfully(R"(
2543 OpCapability Shader
2544 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
2545 OpMemoryModel Logical GLSL450
2546 OpEntryPoint Vertex %main "main" %in_var_COLOR
2547 %4 = OpString "test.hlsl"
2548 OpSource HLSL 620 %4 "#line 1 \"test.hlsl\"
2549 void main(float foo:COLOR) {}
2550 "
2551 %11 = OpString "#line 1 \"test.hlsl\"
2552 void main(float foo:COLOR) {}
2553 "
2554 %14 = OpString "float"
2555 %17 = OpString "src.main"
2556 %20 = OpString "foo"
2557 OpName %in_var_COLOR "in.var.COLOR"
2558 OpName %main "main"
2559 OpName %param_var_foo "param.var.foo"
2560 OpName %src_main "src.main"
2561 OpName %foo "foo"
2562 OpName %bb_entry "bb.entry"
2563 OpDecorate %in_var_COLOR Location 0
2564 %uint = OpTypeInt 32 0
2565 %uint_32 = OpConstant %uint 32
2566 %float = OpTypeFloat 32
2567 %_ptr_Input_float = OpTypePointer Input %float
2568 %void = OpTypeVoid
2569 %23 = OpTypeFunction %void
2570 %_ptr_Function_float = OpTypePointer Function %float
2571 %29 = OpTypeFunction %void %_ptr_Function_float
2572 OpLine %4 1 21
2573 %in_var_COLOR = OpVariable %_ptr_Input_float Input
2574 %10 = OpExtInst %void %1 DebugExpression
2575 %12 = OpExtInst %void %1 DebugSource %4 %11
2576 %13 = OpExtInst %void %1 DebugCompilationUnit 1 4 %12 HLSL
2577 %15 = OpExtInst %void %1 DebugTypeBasic %14 %uint_32 Float
2578 %16 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %void %15
2579 %18 = OpExtInst %void %1 DebugFunction %17 %16 %12 1 1 %13 %17 FlagIsProtected|FlagIsPrivate 1 %src_main
2580 %21 = OpExtInst %void %1 DebugLocalVariable %20 %15 %12 1 17 %18 FlagIsLocal 0
2581 %22 = OpExtInst %void %1 DebugLexicalBlock %12 1 28 %18
2582 OpLine %4 1 1
2583 %main = OpFunction %void None %23
2584 %24 = OpLabel
2585 OpLine %4 1 17
2586 %param_var_foo = OpVariable %_ptr_Function_float Function
2587 %27 = OpLoad %float %in_var_COLOR
2588 OpLine %4 1 1
2589 %28 = OpFunctionCall %void %src_main %param_var_foo
2590 OpReturn
2591 OpFunctionEnd
2592 %src_main = OpFunction %void None %29
2593 OpLine %4 1 17
2594 %foo = OpFunctionParameter %_ptr_Function_float
2595 %31 = OpExtInst %void %1 DebugDeclare %21 %foo %10
2596 %bb_entry = OpLabel
2597 OpLine %4 1 29
2598 OpReturn
2599 OpFunctionEnd
2600 )");
2601 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2602 }
2603
2604 TEST_P(ValidateOpenCL100DebugInfoDebugDeclare, Fail) {
2605 const std::string src = R"(
2606 %src = OpString "simple.hlsl"
2607 %code = OpString "void main() { float foo; }"
2608 %float_name = OpString "float"
2609 %foo_name = OpString "foo"
2610 )";
2611
2612 const std::string size_const = R"(
2613 %int_32 = OpConstant %u32 32
2614 )";
2615
2616 const std::string dbg_inst_header = R"(
2617 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2618 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2619 %null_expr = OpExtInst %void %DbgExt DebugExpression
2620 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2621 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2622 )";
2623
2624 const auto& param = GetParam();
2625
2626 std::ostringstream ss;
2627 ss << R"(
2628 %foo = OpVariable %f32_ptr_function Function
2629 %decl = OpExtInst %void %DbgExt DebugDeclare )"
2630 << param.first;
2631
2632 const std::string extension = R"(
2633 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2634 )";
2635
2636 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2637 src, size_const, dbg_inst_header, ss.str(), extension, "Vertex"));
2638 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2639 EXPECT_THAT(getDiagnosticString(),
2640 HasSubstr("expected operand " + param.second));
2641 }
2642
2643 INSTANTIATE_TEST_SUITE_P(
2644 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugDeclare,
2645 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2646 std::make_pair(R"(%dbg_src %foo %null_expr)", "Local Variable"),
2647 std::make_pair(R"(%foo_info %void %null_expr)", "Variable"),
2648 std::make_pair(R"(%foo_info %foo %dbg_src)", "Expression"),
2649 }));
2650
2651 TEST_F(ValidateOpenCL100DebugInfo, DebugExpression) {
2652 const std::string dbg_inst_header = R"(
2653 %op0 = OpExtInst %void %DbgExt DebugOperation Deref
2654 %op1 = OpExtInst %void %DbgExt DebugOperation Plus
2655 %null_expr = OpExtInst %void %DbgExt DebugExpression %op0 %op1
2656 )";
2657
2658 const std::string extension = R"(
2659 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2660 )";
2661
2662 CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2663 "", extension, "Vertex"));
2664 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2665 }
2666
2667 TEST_F(ValidateOpenCL100DebugInfo, DebugExpressionFail) {
2668 const std::string dbg_inst_header = R"(
2669 %op = OpExtInst %void %DbgExt DebugOperation Deref
2670 %null_expr = OpExtInst %void %DbgExt DebugExpression %op %void
2671 )";
2672
2673 const std::string extension = R"(
2674 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2675 )";
2676
2677 CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2678 "", extension, "Vertex"));
2679 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2680 EXPECT_THAT(
2681 getDiagnosticString(),
2682 HasSubstr(
2683 "expected operand Operation must be a result id of DebugOperation"));
2684 }
2685
2686 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplate) {
2687 const std::string src = R"(
2688 %src = OpString "simple.hlsl"
2689 %code = OpString "OpaqueType foo;
2690 main() {}
2691 "
2692 %float_name = OpString "float"
2693 %ty_name = OpString "Texture"
2694 %t_name = OpString "T"
2695 )";
2696
2697 const std::string size_const = R"(
2698 %int_32 = OpConstant %u32 32
2699 %int_128 = OpConstant %u32 128
2700 )";
2701
2702 const std::string dbg_inst_header = R"(
2703 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2704 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2705 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2706 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2707 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
2708 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2709 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param
2710 )";
2711
2712 const std::string extension = R"(
2713 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2714 )";
2715
2716 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2717 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2718 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2719 }
2720
2721 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateUsedForVariableType) {
2722 const std::string src = R"(
2723 %src = OpString "simple.hlsl"
2724 %code = OpString "OpaqueType foo;
2725 main() {}
2726 "
2727 %float_name = OpString "float"
2728 %ty_name = OpString "Texture"
2729 %t_name = OpString "T"
2730 %foo_name = OpString "foo"
2731 )";
2732
2733 const std::string size_const = R"(
2734 %int_32 = OpConstant %u32 32
2735 %int_128 = OpConstant %u32 128
2736 )";
2737
2738 const std::string dbg_inst_header = R"(
2739 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2740 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2741 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2742 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2743 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
2744 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2745 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param
2746 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %temp %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate
2747 )";
2748
2749 const std::string extension = R"(
2750 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2751 )";
2752
2753 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2754 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2755 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2756 }
2757
2758 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFunction) {
2759 const std::string src = R"(
2760 %src = OpString "simple.hlsl"
2761 %code = OpString "OpaqueType foo;
2762 main() {}
2763 "
2764 %float_name = OpString "float"
2765 %ty_name = OpString "Texture"
2766 %t_name = OpString "T"
2767 %main_name = OpString "main"
2768 )";
2769
2770 const std::string size_const = R"(
2771 %int_32 = OpConstant %u32 32
2772 %int_128 = OpConstant %u32 128
2773 )";
2774
2775 const std::string dbg_inst_header = R"(
2776 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2777 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2778 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2779 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2780 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2781 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param
2782 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
2783 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %param
2784 )";
2785
2786 const std::string extension = R"(
2787 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2788 )";
2789
2790 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2791 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2792 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2793 }
2794
2795 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFailTarget) {
2796 const std::string src = R"(
2797 %src = OpString "simple.hlsl"
2798 %code = OpString "OpaqueType foo;
2799 main() {}
2800 "
2801 %float_name = OpString "float"
2802 %ty_name = OpString "Texture"
2803 %t_name = OpString "T"
2804 %main_name = OpString "main"
2805 )";
2806
2807 const std::string size_const = R"(
2808 %int_32 = OpConstant %u32 32
2809 %int_128 = OpConstant %u32 128
2810 )";
2811
2812 const std::string dbg_inst_header = R"(
2813 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2814 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2815 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2816 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2817 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2818 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %float_info %param
2819 )";
2820
2821 const std::string extension = R"(
2822 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2823 )";
2824
2825 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2826 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2827 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2828 EXPECT_THAT(getDiagnosticString(),
2829 HasSubstr("expected operand Target must be DebugTypeComposite or "
2830 "DebugFunction"));
2831 }
2832
2833 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFailParam) {
2834 const std::string src = R"(
2835 %src = OpString "simple.hlsl"
2836 %code = OpString "OpaqueType foo;
2837 main() {}
2838 "
2839 %float_name = OpString "float"
2840 %ty_name = OpString "Texture"
2841 %t_name = OpString "T"
2842 %main_name = OpString "main"
2843 )";
2844
2845 const std::string size_const = R"(
2846 %int_32 = OpConstant %u32 32
2847 %int_128 = OpConstant %u32 128
2848 )";
2849
2850 const std::string dbg_inst_header = R"(
2851 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2852 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2853 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2854 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2855 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2856 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param
2857 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
2858 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %float_info
2859 )";
2860
2861 const std::string extension = R"(
2862 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2863 )";
2864
2865 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2866 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2868 EXPECT_THAT(
2869 getDiagnosticString(),
2870 HasSubstr(
2871 "expected operand Parameters must be DebugTypeTemplateParameter or "
2872 "DebugTypeTemplateTemplateParameter"));
2873 }
2874
2875 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariable) {
2876 const std::string src = R"(
2877 %src = OpString "simple.hlsl"
2878 %code = OpString "float foo; void main() {}"
2879 %float_name = OpString "float"
2880 %foo_name = OpString "foo"
2881 )";
2882
2883 const std::string size_const = R"(
2884 %int_32 = OpConstant %u32 32
2885 )";
2886
2887 const std::string dbg_inst_header = R"(
2888 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2889 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2890 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2891 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate
2892 )";
2893
2894 const std::string extension = R"(
2895 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2896 )";
2897
2898 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2899 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2900 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2901 }
2902
2903 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableStaticMember) {
2904 const std::string src = R"(
2905 %src = OpString "simple.hlsl"
2906 %code = OpString "float foo; void main() {}"
2907 %float_name = OpString "float"
2908 %foo_name = OpString "foo"
2909 )";
2910
2911 const std::string size_const = R"(
2912 %int_32 = OpConstant %u32 32
2913 )";
2914
2915 const std::string dbg_inst_header = R"(
2916 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2917 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2918 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2919 %t = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Class %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsPublic %a
2920 %a = OpExtInst %void %DbgExt DebugTypeMember %foo_name %float_info %dbg_src 0 0 %t %u32_0 %int_32 FlagIsPublic
2921 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate %a
2922 )";
2923
2924 const std::string extension = R"(
2925 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2926 )";
2927
2928 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2929 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2930 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2931 }
2932
2933 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableDebugInfoNone) {
2934 const std::string src = R"(
2935 %src = OpString "simple.hlsl"
2936 %code = OpString "float foo; void main() {}"
2937 %float_name = OpString "float"
2938 %foo_name = OpString "foo"
2939 )";
2940
2941 const std::string size_const = R"(
2942 %int_32 = OpConstant %u32 32
2943 )";
2944
2945 const std::string dbg_inst_header = R"(
2946 %dbgNone = OpExtInst %void %DbgExt DebugInfoNone
2947 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2948 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2949 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2950 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %dbgNone FlagIsProtected|FlagIsPrivate
2951 )";
2952
2953 const std::string extension = R"(
2954 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2955 )";
2956
2957 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2958 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2959 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2960 }
2961
2962 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableConst) {
2963 const std::string src = R"(
2964 %src = OpString "simple.hlsl"
2965 %code = OpString "float foo; void main() {}"
2966 %float_name = OpString "float"
2967 %foo_name = OpString "foo"
2968 )";
2969
2970 const std::string size_const = R"(
2971 %int_32 = OpConstant %u32 32
2972 )";
2973
2974 const std::string dbg_inst_header = R"(
2975 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2976 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2977 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2978 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsProtected|FlagIsPrivate
2979 )";
2980
2981 const std::string extension = R"(
2982 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2983 )";
2984
2985 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2986 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2987 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2988 }
2989
2990 TEST_P(ValidateOpenCL100DebugInfoDebugGlobalVariable, Fail) {
2991 const std::string src = R"(
2992 %src = OpString "simple.hlsl"
2993 %code = OpString "float foo; void main() {}"
2994 %float_name = OpString "float"
2995 %foo_name = OpString "foo"
2996 )";
2997
2998 const std::string size_const = R"(
2999 %int_32 = OpConstant %u32 32
3000 )";
3001
3002 const auto& param = GetParam();
3003
3004 std::ostringstream ss;
3005 ss << R"(
3006 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3007 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3008 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3009 %foo = OpExtInst %void %DbgExt DebugGlobalVariable )"
3010 << param.first;
3011
3012 const std::string extension = R"(
3013 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3014 )";
3015
3016 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
3017 "", extension, "Vertex"));
3018 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3019 EXPECT_THAT(getDiagnosticString(),
3020 HasSubstr("expected operand " + param.second));
3021 }
3022
3023 INSTANTIATE_TEST_SUITE_P(
3024 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugGlobalVariable,
3025 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
3026 std::make_pair(
3027 R"(%void %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3028 "Name"),
3029 std::make_pair(
3030 R"(%foo_name %dbg_src %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3031 "Type"),
3032 std::make_pair(
3033 R"(%foo_name %float_info %comp_unit 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3034 "Source"),
3035 std::make_pair(
3036 R"(%foo_name %float_info %dbg_src 0 0 %dbg_src %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3037 "Scope"),
3038 std::make_pair(
3039 R"(%foo_name %float_info %dbg_src 0 0 %comp_unit %void %f32_input FlagIsProtected|FlagIsPrivate)",
3040 "Linkage Name"),
3041 std::make_pair(
3042 R"(%foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %void FlagIsProtected|FlagIsPrivate)",
3043 "Variable"),
3044 }));
3045
3046 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAt) {
3047 const std::string src = R"(
3048 %src = OpString "simple.hlsl"
3049 %code = OpString "void main() {}"
3050 %void_name = OpString "void"
3051 %main_name = OpString "main"
3052 %main_linkage_name = OpString "v_main"
3053 )";
3054
3055 const std::string dbg_inst_header = R"(
3056 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3057 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3058 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3059 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3060 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3061 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at
3062 )";
3063
3064 const std::string body = R"(
3065 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3066 )";
3067
3068 const std::string extension = R"(
3069 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3070 )";
3071
3072 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3073 src, "", dbg_inst_header, body, extension, "Vertex"));
3074 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3075 }
3076
3077 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail) {
3078 const std::string src = R"(
3079 %src = OpString "simple.hlsl"
3080 %code = OpString "void main() {}"
3081 %void_name = OpString "void"
3082 %main_name = OpString "main"
3083 %main_linkage_name = OpString "v_main"
3084 )";
3085
3086 const std::string dbg_inst_header = R"(
3087 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3088 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3089 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3090 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3091 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3092 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %inlined_at
3093 )";
3094
3095 const std::string body = R"(
3096 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3097 )";
3098
3099 const std::string extension = R"(
3100 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3101 )";
3102
3103 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3104 src, "", dbg_inst_header, body, extension, "Vertex"));
3105 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3106 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope"));
3107 }
3108
3109 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail2) {
3110 const std::string src = R"(
3111 %src = OpString "simple.hlsl"
3112 %code = OpString "void main() {}"
3113 %void_name = OpString "void"
3114 %main_name = OpString "main"
3115 %main_linkage_name = OpString "v_main"
3116 )";
3117
3118 const std::string dbg_inst_header = R"(
3119 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3120 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3121 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3122 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3123 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3124 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %main_info
3125 )";
3126
3127 const std::string body = R"(
3128 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3129 )";
3130
3131 const std::string extension = R"(
3132 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3133 )";
3134
3135 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3136 src, "", dbg_inst_header, body, extension, "Vertex"));
3137 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3138 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined"));
3139 }
3140
3141 TEST_F(ValidateOpenCL100DebugInfo, DebugValue) {
3142 const std::string src = R"(
3143 %src = OpString "simple.hlsl"
3144 %code = OpString "void main() { float foo; }"
3145 %float_name = OpString "float"
3146 %foo_name = OpString "foo"
3147 )";
3148
3149 const std::string size_const = R"(
3150 %int_3 = OpConstant %u32 3
3151 %int_32 = OpConstant %u32 32
3152 )";
3153
3154 const std::string dbg_inst_header = R"(
3155 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3156 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3157 %null_expr = OpExtInst %void %DbgExt DebugExpression
3158 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3159 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
3160 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
3161 )";
3162
3163 const std::string body = R"(
3164 %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %int_3
3165 )";
3166
3167 const std::string extension = R"(
3168 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3169 )";
3170
3171 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3172 src, size_const, dbg_inst_header, body, extension, "Vertex"));
3173 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3174 }
3175
3176 TEST_F(ValidateOpenCL100DebugInfo, DebugValueWithVariableIndex) {
3177 const std::string src = R"(
3178 %src = OpString "simple.hlsl"
3179 %code = OpString "void main() { float foo; }"
3180 %float_name = OpString "float"
3181 %int_name = OpString "int"
3182 %foo_name = OpString "foo"
3183 %len_name = OpString "length"
3184 )";
3185
3186 const std::string size_const = R"(
3187 %int_3 = OpConstant %u32 3
3188 %int_32 = OpConstant %u32 32
3189 )";
3190
3191 const std::string dbg_inst_header = R"(
3192 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3193 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3194 %null_expr = OpExtInst %void %DbgExt DebugExpression
3195 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3196 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %int_32 Signed
3197 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
3198 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src 1 10 %comp_unit FlagIsLocal
3199 %len_info = OpExtInst %void %DbgExt DebugLocalVariable %len_name %int_info %dbg_src 0 0 %comp_unit FlagIsLocal
3200 )";
3201
3202 const std::string body = R"(
3203 %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %len_info
3204 )";
3205
3206 const std::string extension = R"(
3207 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3208 )";
3209
3210 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3211 src, size_const, dbg_inst_header, body, extension, "Vertex"));
3212 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3213 }
3214
3215 TEST_P(ValidateOpenCL100DebugInfoDebugValue, Fail) {
3216 const std::string src = R"(
3217 %src = OpString "simple.hlsl"
3218 %code = OpString "void main() { float foo; }"
3219 %float_name = OpString "float"
3220 %foo_name = OpString "foo"
3221 )";
3222
3223 const std::string size_const = R"(
3224 %int_32 = OpConstant %u32 32
3225 )";
3226
3227 const std::string dbg_inst_header = R"(
3228 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3229 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3230 %null_expr = OpExtInst %void %DbgExt DebugExpression
3231 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3232 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
3233 )";
3234
3235 const auto& param = GetParam();
3236
3237 std::ostringstream ss;
3238 ss << R"(
3239 %decl = OpExtInst %void %DbgExt DebugValue )"
3240 << param.first;
3241
3242 const std::string extension = R"(
3243 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3244 )";
3245
3246 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3247 src, size_const, dbg_inst_header, ss.str(), extension, "Vertex"));
3248 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3249 EXPECT_THAT(getDiagnosticString(),
3250 HasSubstr("expected operand " + param.second));
3251 }
3252
3253 INSTANTIATE_TEST_SUITE_P(
3254 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugValue,
3255 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
3256 std::make_pair(R"(%dbg_src %int_32 %null_expr)", "Local Variable"),
3257 std::make_pair(R"(%foo_info %int_32 %dbg_src)", "Expression"),
3258 std::make_pair(R"(%foo_info %int_32 %null_expr %dbg_src)", "Indexes"),
3259 }));
3260
3261 TEST_P(ValidateGlslStd450SqrtLike, IntResultType) {
3262 const std::string ext_inst_name = GetParam();
3263 const std::string body =
3264 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
3265
3266 CompileSuccessfully(GenerateShaderCode(body));
3267 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3268 EXPECT_THAT(getDiagnosticString(),
3269 HasSubstr("GLSL.std.450 " + ext_inst_name +
3270 ": expected Result Type to be a float scalar "
3271 "or vector type"));
3272 }
3273
3274 TEST_P(ValidateGlslStd450SqrtLike, IntOperand) {
3275 const std::string ext_inst_name = GetParam();
3276 const std::string body =
3277 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3278
3279 CompileSuccessfully(GenerateShaderCode(body));
3280 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3281 EXPECT_THAT(getDiagnosticString(),
3282 HasSubstr("GLSL.std.450 " + ext_inst_name +
3283 ": expected types of all operands to be equal to "
3284 "Result Type"));
3285 }
3286
3287 INSTANTIATE_TEST_SUITE_P(AllSqrtLike, ValidateGlslStd450SqrtLike,
3288 ::testing::ValuesIn(std::vector<std::string>{
3289 "Round",
3290 "RoundEven",
3291 "FAbs",
3292 "Trunc",
3293 "FSign",
3294 "Floor",
3295 "Ceil",
3296 "Fract",
3297 "Sqrt",
3298 "InverseSqrt",
3299 "Normalize",
3300 }));
3301
3302 TEST_P(ValidateGlslStd450FMinLike, Success) {
3303 const std::string ext_inst_name = GetParam();
3304 std::ostringstream ss;
3305 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3306 << " %f32_0 %f32_1\n";
3307 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3308 << " %f32vec2_01 %f32vec2_12\n";
3309 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
3310 << " %f64_0 %f64_0\n";
3311 CompileSuccessfully(GenerateShaderCode(ss.str()));
3312 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3313 }
3314
3315 TEST_P(ValidateGlslStd450FMinLike, IntResultType) {
3316 const std::string ext_inst_name = GetParam();
3317 const std::string body =
3318 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
3319
3320 CompileSuccessfully(GenerateShaderCode(body));
3321 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3322 EXPECT_THAT(getDiagnosticString(),
3323 HasSubstr("GLSL.std.450 " + ext_inst_name +
3324 ": expected Result Type to be a float scalar "
3325 "or vector type"));
3326 }
3327
3328 TEST_P(ValidateGlslStd450FMinLike, IntOperand1) {
3329 const std::string ext_inst_name = GetParam();
3330 const std::string body =
3331 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
3332
3333 CompileSuccessfully(GenerateShaderCode(body));
3334 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3335 EXPECT_THAT(getDiagnosticString(),
3336 HasSubstr("GLSL.std.450 " + ext_inst_name +
3337 ": expected types of all operands to be equal to "
3338 "Result Type"));
3339 }
3340
3341 TEST_P(ValidateGlslStd450FMinLike, IntOperand2) {
3342 const std::string ext_inst_name = GetParam();
3343 const std::string body =
3344 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
3345
3346 CompileSuccessfully(GenerateShaderCode(body));
3347 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3348 EXPECT_THAT(getDiagnosticString(),
3349 HasSubstr("GLSL.std.450 " + ext_inst_name +
3350 ": expected types of all operands to be equal to "
3351 "Result Type"));
3352 }
3353
3354 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateGlslStd450FMinLike,
3355 ::testing::ValuesIn(std::vector<std::string>{
3356 "FMin",
3357 "FMax",
3358 "Step",
3359 "Reflect",
3360 "NMin",
3361 "NMax",
3362 }));
3363
3364 TEST_P(ValidateGlslStd450FClampLike, Success) {
3365 const std::string ext_inst_name = GetParam();
3366 std::ostringstream ss;
3367 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3368 << " %f32_0 %f32_1 %f32_2\n";
3369 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3370 << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
3371 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
3372 << " %f64_0 %f64_0 %f64_1\n";
3373 CompileSuccessfully(GenerateShaderCode(ss.str()));
3374 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3375 }
3376
3377 TEST_P(ValidateGlslStd450FClampLike, IntResultType) {
3378 const std::string ext_inst_name = GetParam();
3379 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
3380 " %f32_0 %f32_1 %f32_2\n";
3381
3382 CompileSuccessfully(GenerateShaderCode(body));
3383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384 EXPECT_THAT(getDiagnosticString(),
3385 HasSubstr("GLSL.std.450 " + ext_inst_name +
3386 ": expected Result Type to be a float scalar "
3387 "or vector type"));
3388 }
3389
3390 TEST_P(ValidateGlslStd450FClampLike, IntOperand1) {
3391 const std::string ext_inst_name = GetParam();
3392 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3393 " %u32_0 %f32_0 %f32_1\n";
3394
3395 CompileSuccessfully(GenerateShaderCode(body));
3396 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3397 EXPECT_THAT(getDiagnosticString(),
3398 HasSubstr("GLSL.std.450 " + ext_inst_name +
3399 ": expected types of all operands to be equal to "
3400 "Result Type"));
3401 }
3402
3403 TEST_P(ValidateGlslStd450FClampLike, IntOperand2) {
3404 const std::string ext_inst_name = GetParam();
3405 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3406 " %f32_0 %u32_0 %f32_1\n";
3407
3408 CompileSuccessfully(GenerateShaderCode(body));
3409 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3410 EXPECT_THAT(getDiagnosticString(),
3411 HasSubstr("GLSL.std.450 " + ext_inst_name +
3412 ": expected types of all operands to be equal to "
3413 "Result Type"));
3414 }
3415
3416 TEST_P(ValidateGlslStd450FClampLike, IntOperand3) {
3417 const std::string ext_inst_name = GetParam();
3418 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3419 " %f32_1 %f32_0 %u32_2\n";
3420
3421 CompileSuccessfully(GenerateShaderCode(body));
3422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3423 EXPECT_THAT(getDiagnosticString(),
3424 HasSubstr("GLSL.std.450 " + ext_inst_name +
3425 ": expected types of all operands to be equal to "
3426 "Result Type"));
3427 }
3428
3429 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateGlslStd450FClampLike,
3430 ::testing::ValuesIn(std::vector<std::string>{
3431 "FClamp",
3432 "FMix",
3433 "SmoothStep",
3434 "Fma",
3435 "FaceForward",
3436 "NClamp",
3437 }));
3438
3439 TEST_P(ValidateGlslStd450SAbsLike, Success) {
3440 const std::string ext_inst_name = GetParam();
3441 std::ostringstream ss;
3442 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n";
3443 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n";
3444 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
3445 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n";
3446 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3447 << " %s32vec2_01\n";
3448 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3449 << " %u32vec2_01\n";
3450 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3451 << " %s32vec2_01\n";
3452 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3453 << " %u32vec2_01\n";
3454 CompileSuccessfully(GenerateShaderCode(ss.str()));
3455 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3456 }
3457
3458 TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) {
3459 const std::string ext_inst_name = GetParam();
3460 const std::string body =
3461 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3462
3463 CompileSuccessfully(GenerateShaderCode(body));
3464 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3465 EXPECT_THAT(getDiagnosticString(),
3466 HasSubstr("GLSL.std.450 " + ext_inst_name +
3467 ": expected Result Type to be an int scalar "
3468 "or vector type"));
3469 }
3470
3471 TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) {
3472 const std::string ext_inst_name = GetParam();
3473 const std::string body =
3474 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n";
3475
3476 CompileSuccessfully(GenerateShaderCode(body));
3477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3478 EXPECT_THAT(getDiagnosticString(),
3479 HasSubstr("GLSL.std.450 " + ext_inst_name +
3480 ": expected all operands to be int scalars or "
3481 "vectors"));
3482 }
3483
3484 TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) {
3485 const std::string ext_inst_name = GetParam();
3486 const std::string body =
3487 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n";
3488
3489 CompileSuccessfully(GenerateShaderCode(body));
3490 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3491 EXPECT_THAT(getDiagnosticString(),
3492 HasSubstr("GLSL.std.450 " + ext_inst_name +
3493 ": expected all operands to have the same dimension as "
3494 "Result Type"));
3495 }
3496
3497 TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) {
3498 const std::string ext_inst_name = GetParam();
3499 const std::string body =
3500 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n";
3501
3502 CompileSuccessfully(GenerateShaderCode(body));
3503 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3504 EXPECT_THAT(getDiagnosticString(),
3505 HasSubstr("GLSL.std.450 " + ext_inst_name +
3506 ": expected all operands to have the same bit width as "
3507 "Result Type"));
3508 }
3509
3510 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateGlslStd450SAbsLike,
3511 ::testing::ValuesIn(std::vector<std::string>{
3512 "SAbs",
3513 "SSign",
3514 "FindILsb",
3515 "FindUMsb",
3516 "FindSMsb",
3517 }));
3518
3519 TEST_F(ValidateExtInst, FindUMsbNot32Bit) {
3520 const std::string body = R"(
3521 %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1
3522 )";
3523
3524 CompileSuccessfully(GenerateShaderCode(body));
3525 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3526 EXPECT_THAT(getDiagnosticString(),
3527 HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently "
3528 "limited to 32-bit width components"));
3529 }
3530
3531 TEST_F(ValidateExtInst, FindSMsbNot32Bit) {
3532 const std::string body = R"(
3533 %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1
3534 )";
3535
3536 CompileSuccessfully(GenerateShaderCode(body));
3537 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3538 EXPECT_THAT(getDiagnosticString(),
3539 HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently "
3540 "limited to 32-bit width components"));
3541 }
3542
3543 TEST_P(ValidateGlslStd450UMinLike, Success) {
3544 const std::string ext_inst_name = GetParam();
3545 std::ostringstream ss;
3546 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
3547 << " %u32_1 %s32_2\n";
3548 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
3549 << " %s32_1 %u32_2\n";
3550 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
3551 << " %u32_1 %s32_2\n";
3552 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
3553 << " %s32_1 %u32_2\n";
3554 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3555 << " %s32vec2_01 %u32vec2_01\n";
3556 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3557 << " %u32vec2_01 %s32vec2_01\n";
3558 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3559 << " %s32vec2_01 %u32vec2_01\n";
3560 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3561 << " %u32vec2_01 %s32vec2_01\n";
3562 ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
3563 << " %u64_1 %s64_0\n";
3564 CompileSuccessfully(GenerateShaderCode(ss.str()));
3565 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3566 }
3567
3568 TEST_P(ValidateGlslStd450UMinLike, FloatResultType) {
3569 const std::string ext_inst_name = GetParam();
3570 const std::string body =
3571 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
3572
3573 CompileSuccessfully(GenerateShaderCode(body));
3574 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3575 EXPECT_THAT(getDiagnosticString(),
3576 HasSubstr("GLSL.std.450 " + ext_inst_name +
3577 ": expected Result Type to be an int scalar "
3578 "or vector type"));
3579 }
3580
3581 TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) {
3582 const std::string ext_inst_name = GetParam();
3583 const std::string body =
3584 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
3585
3586 CompileSuccessfully(GenerateShaderCode(body));
3587 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3588 EXPECT_THAT(getDiagnosticString(),
3589 HasSubstr("GLSL.std.450 " + ext_inst_name +
3590 ": expected all operands to be int scalars or "
3591 "vectors"));
3592 }
3593
3594 TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) {
3595 const std::string ext_inst_name = GetParam();
3596 const std::string body =
3597 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
3598
3599 CompileSuccessfully(GenerateShaderCode(body));
3600 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3601 EXPECT_THAT(getDiagnosticString(),
3602 HasSubstr("GLSL.std.450 " + ext_inst_name +
3603 ": expected all operands to be int scalars or "
3604 "vectors"));
3605 }
3606
3607 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) {
3608 const std::string ext_inst_name = GetParam();
3609 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3610 " %s32vec2_01 %s32_0\n";
3611
3612 CompileSuccessfully(GenerateShaderCode(body));
3613 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3614 EXPECT_THAT(getDiagnosticString(),
3615 HasSubstr("GLSL.std.450 " + ext_inst_name +
3616 ": expected all operands to have the same dimension as "
3617 "Result Type"));
3618 }
3619
3620 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) {
3621 const std::string ext_inst_name = GetParam();
3622 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3623 " %s32_0 %s32vec2_01\n";
3624
3625 CompileSuccessfully(GenerateShaderCode(body));
3626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3627 EXPECT_THAT(getDiagnosticString(),
3628 HasSubstr("GLSL.std.450 " + ext_inst_name +
3629 ": expected all operands to have the same dimension as "
3630 "Result Type"));
3631 }
3632
3633 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) {
3634 const std::string ext_inst_name = GetParam();
3635 const std::string body =
3636 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n";
3637
3638 CompileSuccessfully(GenerateShaderCode(body));
3639 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3640 EXPECT_THAT(getDiagnosticString(),
3641 HasSubstr("GLSL.std.450 " + ext_inst_name +
3642 ": expected all operands to have the same bit width as "
3643 "Result Type"));
3644 }
3645
3646 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) {
3647 const std::string ext_inst_name = GetParam();
3648 const std::string body =
3649 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n";
3650
3651 CompileSuccessfully(GenerateShaderCode(body));
3652 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3653 EXPECT_THAT(getDiagnosticString(),
3654 HasSubstr("GLSL.std.450 " + ext_inst_name +
3655 ": expected all operands to have the same bit width as "
3656 "Result Type"));
3657 }
3658
3659 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateGlslStd450UMinLike,
3660 ::testing::ValuesIn(std::vector<std::string>{
3661 "UMin",
3662 "SMin",
3663 "UMax",
3664 "SMax",
3665 }));
3666
3667 TEST_P(ValidateGlslStd450UClampLike, Success) {
3668 const std::string ext_inst_name = GetParam();
3669 std::ostringstream ss;
3670 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
3671 << " %s32_0 %u32_1 %s32_2\n";
3672 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
3673 << " %u32_0 %s32_1 %u32_2\n";
3674 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
3675 << " %s32_0 %u32_1 %s32_2\n";
3676 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
3677 << " %u32_0 %s32_1 %u32_2\n";
3678 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3679 << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
3680 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3681 << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3682 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3683 << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
3684 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3685 << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3686 ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
3687 << " %u64_1 %s64_0 %s64_1\n";
3688 CompileSuccessfully(GenerateShaderCode(ss.str()));
3689 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3690 }
3691
3692 TEST_P(ValidateGlslStd450UClampLike, FloatResultType) {
3693 const std::string ext_inst_name = GetParam();
3694 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3695 " %u32_0 %u32_0 %u32_1\n";
3696
3697 CompileSuccessfully(GenerateShaderCode(body));
3698 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3699 EXPECT_THAT(getDiagnosticString(),
3700 HasSubstr("GLSL.std.450 " + ext_inst_name +
3701 ": expected Result Type to be an int scalar "
3702 "or vector type"));
3703 }
3704
3705 TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) {
3706 const std::string ext_inst_name = GetParam();
3707 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3708 " %f32_0 %u32_0 %u32_1\n";
3709
3710 CompileSuccessfully(GenerateShaderCode(body));
3711 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3712 EXPECT_THAT(getDiagnosticString(),
3713 HasSubstr("GLSL.std.450 " + ext_inst_name +
3714 ": expected all operands to be int scalars or "
3715 "vectors"));
3716 }
3717
3718 TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) {
3719 const std::string ext_inst_name = GetParam();
3720 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3721 " %u32_0 %f32_0 %u32_1\n";
3722
3723 CompileSuccessfully(GenerateShaderCode(body));
3724 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3725 EXPECT_THAT(getDiagnosticString(),
3726 HasSubstr("GLSL.std.450 " + ext_inst_name +
3727 ": expected all operands to be int scalars or "
3728 "vectors"));
3729 }
3730
3731 TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) {
3732 const std::string ext_inst_name = GetParam();
3733 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3734 " %u32_0 %u32_0 %f32_1\n";
3735
3736 CompileSuccessfully(GenerateShaderCode(body));
3737 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3738 EXPECT_THAT(getDiagnosticString(),
3739 HasSubstr("GLSL.std.450 " + ext_inst_name +
3740 ": expected all operands to be int scalars or "
3741 "vectors"));
3742 }
3743
3744 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) {
3745 const std::string ext_inst_name = GetParam();
3746 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3747 " %s32vec2_01 %s32_0 %u32_1\n";
3748
3749 CompileSuccessfully(GenerateShaderCode(body));
3750 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3751 EXPECT_THAT(getDiagnosticString(),
3752 HasSubstr("GLSL.std.450 " + ext_inst_name +
3753 ": expected all operands to have the same dimension as "
3754 "Result Type"));
3755 }
3756
3757 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) {
3758 const std::string ext_inst_name = GetParam();
3759 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3760 " %s32_0 %s32vec2_01 %u32_1\n";
3761
3762 CompileSuccessfully(GenerateShaderCode(body));
3763 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3764 EXPECT_THAT(getDiagnosticString(),
3765 HasSubstr("GLSL.std.450 " + ext_inst_name +
3766 ": expected all operands to have the same dimension as "
3767 "Result Type"));
3768 }
3769
3770 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) {
3771 const std::string ext_inst_name = GetParam();
3772 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3773 " %s32_0 %u32_1 %s32vec2_01\n";
3774
3775 CompileSuccessfully(GenerateShaderCode(body));
3776 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3777 EXPECT_THAT(getDiagnosticString(),
3778 HasSubstr("GLSL.std.450 " + ext_inst_name +
3779 ": expected all operands to have the same dimension as "
3780 "Result Type"));
3781 }
3782
3783 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) {
3784 const std::string ext_inst_name = GetParam();
3785 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3786 " %s32_0 %s64_0 %s64_1\n";
3787
3788 CompileSuccessfully(GenerateShaderCode(body));
3789 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3790 EXPECT_THAT(getDiagnosticString(),
3791 HasSubstr("GLSL.std.450 " + ext_inst_name +
3792 ": expected all operands to have the same bit width as "
3793 "Result Type"));
3794 }
3795
3796 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) {
3797 const std::string ext_inst_name = GetParam();
3798 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3799 " %s64_0 %s32_0 %s64_1\n";
3800
3801 CompileSuccessfully(GenerateShaderCode(body));
3802 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3803 EXPECT_THAT(getDiagnosticString(),
3804 HasSubstr("GLSL.std.450 " + ext_inst_name +
3805 ": expected all operands to have the same bit width as "
3806 "Result Type"));
3807 }
3808
3809 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) {
3810 const std::string ext_inst_name = GetParam();
3811 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3812 " %s64_0 %s64_0 %s32_1\n";
3813
3814 CompileSuccessfully(GenerateShaderCode(body));
3815 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3816 EXPECT_THAT(getDiagnosticString(),
3817 HasSubstr("GLSL.std.450 " + ext_inst_name +
3818 ": expected all operands to have the same bit width as "
3819 "Result Type"));
3820 }
3821
3822 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateGlslStd450UClampLike,
3823 ::testing::ValuesIn(std::vector<std::string>{
3824 "UClamp",
3825 "SClamp",
3826 }));
3827
3828 TEST_P(ValidateGlslStd450SinLike, Success) {
3829 const std::string ext_inst_name = GetParam();
3830 std::ostringstream ss;
3831 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
3832 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3833 << " %f32vec2_01\n";
3834 CompileSuccessfully(GenerateShaderCode(ss.str()));
3835 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3836 }
3837
3838 TEST_P(ValidateGlslStd450SinLike, IntResultType) {
3839 const std::string ext_inst_name = GetParam();
3840 const std::string body =
3841 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
3842
3843 CompileSuccessfully(GenerateShaderCode(body));
3844 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3845 EXPECT_THAT(getDiagnosticString(),
3846 HasSubstr("GLSL.std.450 " + ext_inst_name +
3847 ": expected Result Type to be a 16 or 32-bit scalar "
3848 "or vector float type"));
3849 }
3850
3851 TEST_P(ValidateGlslStd450SinLike, F64ResultType) {
3852 const std::string ext_inst_name = GetParam();
3853 const std::string body =
3854 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n";
3855
3856 CompileSuccessfully(GenerateShaderCode(body));
3857 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3858 EXPECT_THAT(getDiagnosticString(),
3859 HasSubstr("GLSL.std.450 " + ext_inst_name +
3860 ": expected Result Type to be a 16 or 32-bit scalar "
3861 "or vector float type"));
3862 }
3863
3864 TEST_P(ValidateGlslStd450SinLike, IntOperand) {
3865 const std::string ext_inst_name = GetParam();
3866 const std::string body =
3867 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3868
3869 CompileSuccessfully(GenerateShaderCode(body));
3870 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3871 EXPECT_THAT(getDiagnosticString(),
3872 HasSubstr("GLSL.std.450 " + ext_inst_name +
3873 ": expected types of all operands to be equal to "
3874 "Result Type"));
3875 }
3876
3877 INSTANTIATE_TEST_SUITE_P(AllSinLike, ValidateGlslStd450SinLike,
3878 ::testing::ValuesIn(std::vector<std::string>{
3879 "Radians",
3880 "Degrees",
3881 "Sin",
3882 "Cos",
3883 "Tan",
3884 "Asin",
3885 "Acos",
3886 "Atan",
3887 "Sinh",
3888 "Cosh",
3889 "Tanh",
3890 "Asinh",
3891 "Acosh",
3892 "Atanh",
3893 "Exp",
3894 "Exp2",
3895 "Log",
3896 "Log2",
3897 }));
3898
3899 TEST_P(ValidateGlslStd450PowLike, Success) {
3900 const std::string ext_inst_name = GetParam();
3901 std::ostringstream ss;
3902 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3903 << " %f32_1 %f32_1\n";
3904 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3905 << " %f32vec2_01 %f32vec2_12\n";
3906 CompileSuccessfully(GenerateShaderCode(ss.str()));
3907 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3908 }
3909
3910 TEST_P(ValidateGlslStd450PowLike, IntResultType) {
3911 const std::string ext_inst_name = GetParam();
3912 const std::string body =
3913 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3914
3915 CompileSuccessfully(GenerateShaderCode(body));
3916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3917 EXPECT_THAT(getDiagnosticString(),
3918 HasSubstr("GLSL.std.450 " + ext_inst_name +
3919 ": expected Result Type to be a 16 or 32-bit scalar "
3920 "or vector float type"));
3921 }
3922
3923 TEST_P(ValidateGlslStd450PowLike, F64ResultType) {
3924 const std::string ext_inst_name = GetParam();
3925 const std::string body =
3926 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3927
3928 CompileSuccessfully(GenerateShaderCode(body));
3929 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3930 EXPECT_THAT(getDiagnosticString(),
3931 HasSubstr("GLSL.std.450 " + ext_inst_name +
3932 ": expected Result Type to be a 16 or 32-bit scalar "
3933 "or vector float type"));
3934 }
3935
3936 TEST_P(ValidateGlslStd450PowLike, IntOperand1) {
3937 const std::string ext_inst_name = GetParam();
3938 const std::string body =
3939 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
3940
3941 CompileSuccessfully(GenerateShaderCode(body));
3942 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3943 EXPECT_THAT(getDiagnosticString(),
3944 HasSubstr("GLSL.std.450 " + ext_inst_name +
3945 ": expected types of all operands to be equal to "
3946 "Result Type"));
3947 }
3948
3949 TEST_P(ValidateGlslStd450PowLike, IntOperand2) {
3950 const std::string ext_inst_name = GetParam();
3951 const std::string body =
3952 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
3953
3954 CompileSuccessfully(GenerateShaderCode(body));
3955 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3956 EXPECT_THAT(getDiagnosticString(),
3957 HasSubstr("GLSL.std.450 " + ext_inst_name +
3958 ": expected types of all operands to be equal to "
3959 "Result Type"));
3960 }
3961
3962 INSTANTIATE_TEST_SUITE_P(AllPowLike, ValidateGlslStd450PowLike,
3963 ::testing::ValuesIn(std::vector<std::string>{
3964 "Atan2",
3965 "Pow",
3966 }));
3967
3968 TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) {
3969 const std::string body = R"(
3970 %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212
3971 )";
3972
3973 CompileSuccessfully(GenerateShaderCode(body));
3974 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3975 }
3976
3977 TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) {
3978 const std::string body = R"(
3979 %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212
3980 )";
3981
3982 CompileSuccessfully(GenerateShaderCode(body));
3983 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3984 EXPECT_THAT(getDiagnosticString(),
3985 HasSubstr("GLSL.std.450 Determinant: "
3986 "expected operand X component type to be equal to "
3987 "Result Type"));
3988 }
3989
3990 TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) {
3991 const std::string body = R"(
3992 %val1 = OpExtInst %f32 %extinst Determinant %f32_1
3993 )";
3994
3995 CompileSuccessfully(GenerateShaderCode(body));
3996 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3997 EXPECT_THAT(getDiagnosticString(),
3998 HasSubstr("GLSL.std.450 Determinant: "
3999 "expected operand X to be a square matrix"));
4000 }
4001
4002 TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) {
4003 const std::string body = R"(
4004 %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212
4005 )";
4006
4007 CompileSuccessfully(GenerateShaderCode(body));
4008 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4009 EXPECT_THAT(getDiagnosticString(),
4010 HasSubstr("GLSL.std.450 Determinant: "
4011 "expected operand X to be a square matrix"));
4012 }
4013
4014 TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) {
4015 const std::string body = R"(
4016 %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212
4017 )";
4018
4019 CompileSuccessfully(GenerateShaderCode(body));
4020 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4021 }
4022
4023 TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) {
4024 const std::string body = R"(
4025 %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212
4026 )";
4027
4028 CompileSuccessfully(GenerateShaderCode(body));
4029 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4030 EXPECT_THAT(getDiagnosticString(),
4031 HasSubstr("GLSL.std.450 MatrixInverse: "
4032 "expected operand X type to be equal to "
4033 "Result Type"));
4034 }
4035
4036 TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) {
4037 const std::string body = R"(
4038 %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212
4039 )";
4040
4041 CompileSuccessfully(GenerateShaderCode(body));
4042 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4043 EXPECT_THAT(getDiagnosticString(),
4044 HasSubstr("GLSL.std.450 MatrixInverse: "
4045 "expected Result Type to be a square matrix"));
4046 }
4047
4048 TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) {
4049 const std::string body = R"(
4050 %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212
4051 )";
4052
4053 CompileSuccessfully(GenerateShaderCode(body));
4054 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4055 EXPECT_THAT(getDiagnosticString(),
4056 HasSubstr("GLSL.std.450 MatrixInverse: "
4057 "expected Result Type to be a square matrix"));
4058 }
4059
4060 TEST_F(ValidateExtInst, GlslStd450ModfSuccess) {
4061 const std::string body = R"(
4062 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output
4063 %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output
4064 )";
4065
4066 CompileSuccessfully(GenerateShaderCode(body));
4067 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4068 }
4069
4070 TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) {
4071 const std::string body = R"(
4072 %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output
4073 )";
4074
4075 CompileSuccessfully(GenerateShaderCode(body));
4076 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4077 EXPECT_THAT(getDiagnosticString(),
4078 HasSubstr("GLSL.std.450 Modf: "
4079 "expected Result Type to be a scalar or vector "
4080 "float type"));
4081 }
4082
4083 TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) {
4084 const std::string body = R"(
4085 %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output
4086 )";
4087
4088 CompileSuccessfully(GenerateShaderCode(body));
4089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4090 EXPECT_THAT(getDiagnosticString(),
4091 HasSubstr("GLSL.std.450 Modf: "
4092 "expected operand X type to be equal to Result Type"));
4093 }
4094
4095 TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) {
4096 const std::string body = R"(
4097 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1
4098 )";
4099
4100 CompileSuccessfully(GenerateShaderCode(body));
4101 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4102 EXPECT_THAT(getDiagnosticString(),
4103 HasSubstr("GLSL.std.450 Modf: "
4104 "expected operand I to be a pointer"));
4105 }
4106
4107 TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) {
4108 const std::string body = R"(
4109 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output
4110 )";
4111
4112 CompileSuccessfully(GenerateShaderCode(body));
4113 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4114 EXPECT_THAT(getDiagnosticString(),
4115 HasSubstr("GLSL.std.450 Modf: "
4116 "expected operand I data type to be equal to "
4117 "Result Type"));
4118 }
4119
4120 TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) {
4121 const std::string body = R"(
4122 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h
4123 %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01
4124 )";
4125
4126 CompileSuccessfully(GenerateShaderCode(body));
4127 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4128 }
4129
4130 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) {
4131 const std::string body = R"(
4132 %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h
4133 )";
4134
4135 CompileSuccessfully(GenerateShaderCode(body));
4136 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4137 EXPECT_THAT(getDiagnosticString(),
4138 HasSubstr("GLSL.std.450 ModfStruct: "
4139 "expected Result Type to be a struct with two "
4140 "identical scalar or vector float type members"));
4141 }
4142
4143 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) {
4144 const std::string body = R"(
4145 %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h
4146 )";
4147
4148 CompileSuccessfully(GenerateShaderCode(body));
4149 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4150 EXPECT_THAT(getDiagnosticString(),
4151 HasSubstr("GLSL.std.450 ModfStruct: "
4152 "expected Result Type to be a struct with two "
4153 "identical scalar or vector float type members"));
4154 }
4155
4156 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) {
4157 const std::string body = R"(
4158 %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h
4159 )";
4160
4161 CompileSuccessfully(GenerateShaderCode(body));
4162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4163 EXPECT_THAT(getDiagnosticString(),
4164 HasSubstr("GLSL.std.450 ModfStruct: "
4165 "expected Result Type to be a struct with two "
4166 "identical scalar or vector float type members"));
4167 }
4168
4169 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) {
4170 const std::string body = R"(
4171 %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h
4172 )";
4173
4174 CompileSuccessfully(GenerateShaderCode(body));
4175 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4176 EXPECT_THAT(getDiagnosticString(),
4177 HasSubstr("GLSL.std.450 ModfStruct: "
4178 "expected Result Type to be a struct with two "
4179 "identical scalar or vector float type members"));
4180 }
4181
4182 TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) {
4183 const std::string body = R"(
4184 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0
4185 )";
4186
4187 CompileSuccessfully(GenerateShaderCode(body));
4188 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4189 EXPECT_THAT(getDiagnosticString(),
4190 HasSubstr("GLSL.std.450 ModfStruct: "
4191 "expected operand X type to be equal to members of "
4192 "Result Type struct"));
4193 }
4194
4195 TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) {
4196 const std::string body = R"(
4197 %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output
4198 %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output
4199 )";
4200
4201 CompileSuccessfully(GenerateShaderCode(body));
4202 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4203 }
4204
4205 TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) {
4206 const std::string body = R"(
4207 %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output
4208 )";
4209
4210 CompileSuccessfully(GenerateShaderCode(body));
4211 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4212 EXPECT_THAT(getDiagnosticString(),
4213 HasSubstr("GLSL.std.450 Frexp: "
4214 "expected Result Type to be a scalar or vector "
4215 "float type"));
4216 }
4217
4218 TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) {
4219 const std::string body = R"(
4220 %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output
4221 )";
4222
4223 CompileSuccessfully(GenerateShaderCode(body));
4224 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4225 EXPECT_THAT(getDiagnosticString(),
4226 HasSubstr("GLSL.std.450 Frexp: "
4227 "expected operand X type to be equal to Result Type"));
4228 }
4229
4230 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) {
4231 const std::string body = R"(
4232 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1
4233 )";
4234
4235 CompileSuccessfully(GenerateShaderCode(body));
4236 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4237 EXPECT_THAT(getDiagnosticString(),
4238 HasSubstr("GLSL.std.450 Frexp: "
4239 "expected operand Exp to be a pointer"));
4240 }
4241
4242 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) {
4243 const std::string body = R"(
4244 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output
4245 )";
4246
4247 CompileSuccessfully(GenerateShaderCode(body));
4248 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4249 EXPECT_THAT(getDiagnosticString(),
4250 HasSubstr("GLSL.std.450 Frexp: "
4251 "expected operand Exp data type to be a 32-bit int "
4252 "scalar or vector type"));
4253 }
4254
4255 TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) {
4256 const std::string body = R"(
4257 %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output
4258 )";
4259
4260 CompileSuccessfully(GenerateShaderCode(body));
4261 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4262 EXPECT_THAT(getDiagnosticString(),
4263 HasSubstr("GLSL.std.450 Frexp: "
4264 "expected operand Exp data type to have the same "
4265 "component number as Result Type"));
4266 }
4267
4268 TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) {
4269 const std::string body = R"(
4270 %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2
4271 %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12
4272 %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1
4273 )";
4274
4275 CompileSuccessfully(GenerateShaderCode(body));
4276 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4277 }
4278
4279 TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) {
4280 const std::string body = R"(
4281 %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2
4282 )";
4283
4284 CompileSuccessfully(GenerateShaderCode(body));
4285 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4286 EXPECT_THAT(getDiagnosticString(),
4287 HasSubstr("GLSL.std.450 Ldexp: "
4288 "expected Result Type to be a scalar or vector "
4289 "float type"));
4290 }
4291
4292 TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) {
4293 const std::string body = R"(
4294 %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2
4295 )";
4296
4297 CompileSuccessfully(GenerateShaderCode(body));
4298 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4299 EXPECT_THAT(getDiagnosticString(),
4300 HasSubstr("GLSL.std.450 Ldexp: "
4301 "expected operand X type to be equal to Result Type"));
4302 }
4303
4304 TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) {
4305 const std::string body = R"(
4306 %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2
4307 )";
4308
4309 CompileSuccessfully(GenerateShaderCode(body));
4310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4311 EXPECT_THAT(getDiagnosticString(),
4312 HasSubstr("GLSL.std.450 Ldexp: "
4313 "expected operand Exp to be a 32-bit int scalar "
4314 "or vector type"));
4315 }
4316
4317 TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) {
4318 const std::string body = R"(
4319 %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2
4320 )";
4321
4322 CompileSuccessfully(GenerateShaderCode(body));
4323 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4324 EXPECT_THAT(getDiagnosticString(),
4325 HasSubstr("GLSL.std.450 Ldexp: "
4326 "expected operand Exp to have the same component "
4327 "number as Result Type"));
4328 }
4329
4330 TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) {
4331 const std::string body = R"(
4332 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h
4333 %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01
4334 )";
4335
4336 CompileSuccessfully(GenerateShaderCode(body));
4337 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4338 }
4339
4340 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) {
4341 const std::string body = R"(
4342 %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h
4343 )";
4344
4345 CompileSuccessfully(GenerateShaderCode(body));
4346 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4347 EXPECT_THAT(getDiagnosticString(),
4348 HasSubstr("GLSL.std.450 FrexpStruct: "
4349 "expected Result Type to be a struct with two members, "
4350 "first member a float scalar or vector, second member "
4351 "a 32-bit int scalar or vector with the same number of "
4352 "components as the first member"));
4353 }
4354
4355 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) {
4356 const std::string body = R"(
4357 %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h
4358 )";
4359
4360 CompileSuccessfully(GenerateShaderCode(body));
4361 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4362 EXPECT_THAT(getDiagnosticString(),
4363 HasSubstr("GLSL.std.450 FrexpStruct: "
4364 "expected Result Type to be a struct with two members, "
4365 "first member a float scalar or vector, second member "
4366 "a 32-bit int scalar or vector with the same number of "
4367 "components as the first member"));
4368 }
4369
4370 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) {
4371 const std::string body = R"(
4372 %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h
4373 )";
4374
4375 CompileSuccessfully(GenerateShaderCode(body));
4376 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4377 EXPECT_THAT(getDiagnosticString(),
4378 HasSubstr("GLSL.std.450 FrexpStruct: "
4379 "expected Result Type to be a struct with two members, "
4380 "first member a float scalar or vector, second member "
4381 "a 32-bit int scalar or vector with the same number of "
4382 "components as the first member"));
4383 }
4384
4385 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) {
4386 const std::string body = R"(
4387 %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h
4388 )";
4389
4390 CompileSuccessfully(GenerateShaderCode(body));
4391 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4392 EXPECT_THAT(getDiagnosticString(),
4393 HasSubstr("GLSL.std.450 FrexpStruct: "
4394 "expected Result Type to be a struct with two members, "
4395 "first member a float scalar or vector, second member "
4396 "a 32-bit int scalar or vector with the same number of "
4397 "components as the first member"));
4398 }
4399
4400 TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) {
4401 const std::string body = R"(
4402 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0
4403 )";
4404
4405 CompileSuccessfully(GenerateShaderCode(body));
4406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4407 EXPECT_THAT(getDiagnosticString(),
4408 HasSubstr("GLSL.std.450 FrexpStruct: "
4409 "expected operand X type to be equal to the first "
4410 "member of Result Type struct"));
4411 }
4412
4413 TEST_F(ValidateExtInst,
4414 GlslStd450FrexpStructResultTypeStructRightInt16Member2) {
4415 const std::string body = R"(
4416 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
4417 )";
4418
4419 const std::string extension = R"(
4420 OpExtension "SPV_AMD_gpu_shader_int16"
4421 )";
4422
4423 CompileSuccessfully(GenerateShaderCode(body, extension));
4424 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4425 }
4426
4427 TEST_F(ValidateExtInst,
4428 GlslStd450FrexpStructResultTypeStructWrongInt16Member2) {
4429 const std::string body = R"(
4430 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
4431 )";
4432
4433 CompileSuccessfully(GenerateShaderCode(body));
4434 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4435 EXPECT_THAT(getDiagnosticString(),
4436 HasSubstr("GLSL.std.450 FrexpStruct: "
4437 "expected Result Type to be a struct with two members, "
4438 "first member a float scalar or vector, second member "
4439 "a 32-bit int scalar or vector with the same number of "
4440 "components as the first member"));
4441 }
4442
4443 TEST_P(ValidateGlslStd450Pack, Success) {
4444 const std::string ext_inst_name = GetParam();
4445 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4446 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4447 const uint32_t total_bit_width = num_components * packed_bit_width;
4448 const std::string vec_str =
4449 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4450
4451 std::ostringstream body;
4452 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4453 << ext_inst_name << vec_str;
4454 body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst "
4455 << ext_inst_name << vec_str;
4456 CompileSuccessfully(GenerateShaderCode(body.str()));
4457 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4458 }
4459
4460 TEST_P(ValidateGlslStd450Pack, Float32ResultType) {
4461 const std::string ext_inst_name = GetParam();
4462 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4463 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4464 const uint32_t total_bit_width = num_components * packed_bit_width;
4465 const std::string vec_str =
4466 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4467
4468 std::ostringstream body;
4469 body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst "
4470 << ext_inst_name << vec_str;
4471
4472 std::ostringstream expected;
4473 expected << "GLSL.std.450 " << ext_inst_name
4474 << ": expected Result Type to be " << total_bit_width
4475 << "-bit int scalar type";
4476
4477 CompileSuccessfully(GenerateShaderCode(body.str()));
4478 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4479 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4480 }
4481
4482 TEST_P(ValidateGlslStd450Pack, Int16ResultType) {
4483 const std::string ext_inst_name = GetParam();
4484 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4485 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4486 const uint32_t total_bit_width = num_components * packed_bit_width;
4487 const std::string vec_str =
4488 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4489
4490 std::ostringstream body;
4491 body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str;
4492
4493 std::ostringstream expected;
4494 expected << "GLSL.std.450 " << ext_inst_name
4495 << ": expected Result Type to be " << total_bit_width
4496 << "-bit int scalar type";
4497
4498 CompileSuccessfully(GenerateShaderCode(body.str()));
4499 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4500 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4501 }
4502
4503 TEST_P(ValidateGlslStd450Pack, VNotVector) {
4504 const std::string ext_inst_name = GetParam();
4505 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4506 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4507 const uint32_t total_bit_width = num_components * packed_bit_width;
4508
4509 std::ostringstream body;
4510 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4511 << ext_inst_name << " %f32_1\n";
4512
4513 std::ostringstream expected;
4514 expected << "GLSL.std.450 " << ext_inst_name
4515 << ": expected operand V to be a 32-bit float vector of size "
4516 << num_components;
4517
4518 CompileSuccessfully(GenerateShaderCode(body.str()));
4519 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4520 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4521 }
4522
4523 TEST_P(ValidateGlslStd450Pack, VNotFloatVector) {
4524 const std::string ext_inst_name = GetParam();
4525 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4526 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4527 const uint32_t total_bit_width = num_components * packed_bit_width;
4528 const std::string vec_str =
4529 num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n";
4530
4531 std::ostringstream body;
4532 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4533 << ext_inst_name << vec_str;
4534
4535 std::ostringstream expected;
4536 expected << "GLSL.std.450 " << ext_inst_name
4537 << ": expected operand V to be a 32-bit float vector of size "
4538 << num_components;
4539
4540 CompileSuccessfully(GenerateShaderCode(body.str()));
4541 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4542 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4543 }
4544
4545 TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) {
4546 const std::string ext_inst_name = GetParam();
4547 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4548 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4549 const uint32_t total_bit_width = num_components * packed_bit_width;
4550 const std::string vec_str =
4551 num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n";
4552
4553 std::ostringstream body;
4554 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4555 << ext_inst_name << vec_str;
4556
4557 std::ostringstream expected;
4558 expected << "GLSL.std.450 " << ext_inst_name
4559 << ": expected operand V to be a 32-bit float vector of size "
4560 << num_components;
4561
4562 CompileSuccessfully(GenerateShaderCode(body.str()));
4563 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4564 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4565 }
4566
4567 TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) {
4568 const std::string ext_inst_name = GetParam();
4569 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4570 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4571 const uint32_t total_bit_width = num_components * packed_bit_width;
4572 const std::string vec_str =
4573 num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4574
4575 std::ostringstream body;
4576 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4577 << ext_inst_name << vec_str;
4578
4579 std::ostringstream expected;
4580 expected << "GLSL.std.450 " << ext_inst_name
4581 << ": expected operand V to be a 32-bit float vector of size "
4582 << num_components;
4583
4584 CompileSuccessfully(GenerateShaderCode(body.str()));
4585 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4586 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4587 }
4588
4589 INSTANTIATE_TEST_SUITE_P(AllPack, ValidateGlslStd450Pack,
4590 ::testing::ValuesIn(std::vector<std::string>{
4591 "PackSnorm4x8",
4592 "PackUnorm4x8",
4593 "PackSnorm2x16",
4594 "PackUnorm2x16",
4595 "PackHalf2x16",
4596 }));
4597
4598 TEST_F(ValidateExtInst, PackDouble2x32Success) {
4599 const std::string body = R"(
4600 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01
4601 )";
4602
4603 CompileSuccessfully(GenerateShaderCode(body));
4604 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4605 }
4606
4607 TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) {
4608 const std::string body = R"(
4609 %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01
4610 )";
4611
4612 CompileSuccessfully(GenerateShaderCode(body));
4613 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4614 EXPECT_THAT(getDiagnosticString(),
4615 HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
4616 "be 64-bit float scalar type"));
4617 }
4618
4619 TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) {
4620 const std::string body = R"(
4621 %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01
4622 )";
4623
4624 CompileSuccessfully(GenerateShaderCode(body));
4625 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4626 EXPECT_THAT(getDiagnosticString(),
4627 HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
4628 "be 64-bit float scalar type"));
4629 }
4630
4631 TEST_F(ValidateExtInst, PackDouble2x32VNotVector) {
4632 const std::string body = R"(
4633 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1
4634 )";
4635
4636 CompileSuccessfully(GenerateShaderCode(body));
4637 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4638 EXPECT_THAT(getDiagnosticString(),
4639 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4640 "a 32-bit int vector of size 2"));
4641 }
4642
4643 TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) {
4644 const std::string body = R"(
4645 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01
4646 )";
4647
4648 CompileSuccessfully(GenerateShaderCode(body));
4649 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4650 EXPECT_THAT(getDiagnosticString(),
4651 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4652 "a 32-bit int vector of size 2"));
4653 }
4654
4655 TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) {
4656 const std::string body = R"(
4657 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01
4658 )";
4659
4660 CompileSuccessfully(GenerateShaderCode(body));
4661 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4662 EXPECT_THAT(getDiagnosticString(),
4663 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4664 "a 32-bit int vector of size 2"));
4665 }
4666
4667 TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) {
4668 const std::string body = R"(
4669 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123
4670 )";
4671
4672 CompileSuccessfully(GenerateShaderCode(body));
4673 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4674 EXPECT_THAT(getDiagnosticString(),
4675 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4676 "a 32-bit int vector of size 2"));
4677 }
4678
4679 TEST_P(ValidateGlslStd450Unpack, Success) {
4680 const std::string ext_inst_name = GetParam();
4681 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4682 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4683 const uint32_t total_bit_width = num_components * packed_bit_width;
4684 const std::string result_type_str =
4685 num_components == 2 ? "%f32vec2" : " %f32vec4";
4686
4687 std::ostringstream body;
4688 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4689 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4690 body << "%val2 = OpExtInst " << result_type_str << " %extinst "
4691 << ext_inst_name << " %s" << total_bit_width << "_1\n";
4692 CompileSuccessfully(GenerateShaderCode(body.str()));
4693 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4694 }
4695
4696 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) {
4697 const std::string ext_inst_name = GetParam();
4698 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4699 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4700 const uint32_t total_bit_width = num_components * packed_bit_width;
4701 const std::string result_type_str = "%f32";
4702
4703 std::ostringstream body;
4704 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4705 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4706
4707 std::ostringstream expected;
4708 expected << "GLSL.std.450 " << ext_inst_name
4709 << ": expected Result Type to be a 32-bit float vector of size "
4710 << num_components;
4711
4712 CompileSuccessfully(GenerateShaderCode(body.str()));
4713 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4714 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4715 }
4716
4717 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) {
4718 const std::string ext_inst_name = GetParam();
4719 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4720 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4721 const uint32_t total_bit_width = num_components * packed_bit_width;
4722 const std::string result_type_str =
4723 num_components == 2 ? "%u32vec2" : " %u32vec4";
4724
4725 std::ostringstream body;
4726 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4727 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4728
4729 std::ostringstream expected;
4730 expected << "GLSL.std.450 " << ext_inst_name
4731 << ": expected Result Type to be a 32-bit float vector of size "
4732 << num_components;
4733
4734 CompileSuccessfully(GenerateShaderCode(body.str()));
4735 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4736 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4737 }
4738
4739 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) {
4740 const std::string ext_inst_name = GetParam();
4741 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4742 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4743 const uint32_t total_bit_width = num_components * packed_bit_width;
4744 const std::string result_type_str =
4745 num_components == 2 ? "%f64vec2" : " %f64vec4";
4746
4747 std::ostringstream body;
4748 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4749 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4750
4751 std::ostringstream expected;
4752 expected << "GLSL.std.450 " << ext_inst_name
4753 << ": expected Result Type to be a 32-bit float vector of size "
4754 << num_components;
4755
4756 CompileSuccessfully(GenerateShaderCode(body.str()));
4757 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4758 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4759 }
4760
4761 TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) {
4762 const std::string ext_inst_name = GetParam();
4763 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4764 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4765 const uint32_t total_bit_width = num_components * packed_bit_width;
4766 const std::string result_type_str =
4767 num_components == 4 ? "%f32vec2" : " %f32vec4";
4768
4769 std::ostringstream body;
4770 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4771 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4772
4773 std::ostringstream expected;
4774 expected << "GLSL.std.450 " << ext_inst_name
4775 << ": expected Result Type to be a 32-bit float vector of size "
4776 << num_components;
4777
4778 CompileSuccessfully(GenerateShaderCode(body.str()));
4779 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4780 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4781 }
4782
4783 TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) {
4784 const std::string ext_inst_name = GetParam();
4785 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4786 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4787 const uint32_t total_bit_width = num_components * packed_bit_width;
4788 const std::string result_type_str =
4789 num_components == 2 ? "%f32vec2" : " %f32vec4";
4790
4791 std::ostringstream body;
4792 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4793 << ext_inst_name << " %f" << total_bit_width << "_1\n";
4794
4795 std::ostringstream expected;
4796 expected << "GLSL.std.450 " << ext_inst_name
4797 << ": expected operand P to be a " << total_bit_width
4798 << "-bit int scalar";
4799
4800 CompileSuccessfully(GenerateShaderCode(body.str()));
4801 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4802 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4803 }
4804
4805 TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) {
4806 const std::string ext_inst_name = GetParam();
4807 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4808 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4809 const uint32_t total_bit_width = num_components * packed_bit_width;
4810 const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32;
4811 const std::string result_type_str =
4812 num_components == 2 ? "%f32vec2" : " %f32vec4";
4813
4814 std::ostringstream body;
4815 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4816 << ext_inst_name << " %u" << wrong_bit_width << "_1\n";
4817
4818 std::ostringstream expected;
4819 expected << "GLSL.std.450 " << ext_inst_name
4820 << ": expected operand P to be a " << total_bit_width
4821 << "-bit int scalar";
4822
4823 CompileSuccessfully(GenerateShaderCode(body.str()));
4824 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4825 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4826 }
4827
4828 INSTANTIATE_TEST_SUITE_P(AllUnpack, ValidateGlslStd450Unpack,
4829 ::testing::ValuesIn(std::vector<std::string>{
4830 "UnpackSnorm4x8",
4831 "UnpackUnorm4x8",
4832 "UnpackSnorm2x16",
4833 "UnpackUnorm2x16",
4834 "UnpackHalf2x16",
4835 }));
4836
4837 TEST_F(ValidateExtInst, UnpackDouble2x32Success) {
4838 const std::string body = R"(
4839 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1
4840 )";
4841
4842 CompileSuccessfully(GenerateShaderCode(body));
4843 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4844 }
4845
4846 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) {
4847 const std::string body = R"(
4848 %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1
4849 )";
4850
4851 CompileSuccessfully(GenerateShaderCode(body));
4852 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4853 EXPECT_THAT(getDiagnosticString(),
4854 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4855 "to be a 32-bit int vector of size 2"));
4856 }
4857
4858 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) {
4859 const std::string body = R"(
4860 %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1
4861 )";
4862
4863 CompileSuccessfully(GenerateShaderCode(body));
4864 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4865 EXPECT_THAT(getDiagnosticString(),
4866 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4867 "to be a 32-bit int vector of size 2"));
4868 }
4869
4870 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) {
4871 const std::string body = R"(
4872 %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1
4873 )";
4874
4875 CompileSuccessfully(GenerateShaderCode(body));
4876 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4877 EXPECT_THAT(getDiagnosticString(),
4878 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4879 "to be a 32-bit int vector of size 2"));
4880 }
4881
4882 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) {
4883 const std::string body = R"(
4884 %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1
4885 )";
4886
4887 CompileSuccessfully(GenerateShaderCode(body));
4888 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4889 EXPECT_THAT(getDiagnosticString(),
4890 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4891 "to be a 32-bit int vector of size 2"));
4892 }
4893
4894 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) {
4895 const std::string body = R"(
4896 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1
4897 )";
4898
4899 CompileSuccessfully(GenerateShaderCode(body));
4900 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4901 EXPECT_THAT(getDiagnosticString(),
4902 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4903 "be a 64-bit float scalar"));
4904 }
4905
4906 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) {
4907 const std::string body = R"(
4908 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1
4909 )";
4910
4911 CompileSuccessfully(GenerateShaderCode(body));
4912 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4913 EXPECT_THAT(getDiagnosticString(),
4914 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4915 "be a 64-bit float scalar"));
4916 }
4917
4918 TEST_F(ValidateExtInst, GlslStd450LengthSuccess) {
4919 const std::string body = R"(
4920 %val1 = OpExtInst %f32 %extinst Length %f32_1
4921 %val2 = OpExtInst %f32 %extinst Length %f32vec2_01
4922 %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123
4923 )";
4924
4925 CompileSuccessfully(GenerateShaderCode(body));
4926 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4927 }
4928
4929 TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) {
4930 const std::string body = R"(
4931 %val1 = OpExtInst %u32 %extinst Length %f32vec2_01
4932 )";
4933
4934 CompileSuccessfully(GenerateShaderCode(body));
4935 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4936 EXPECT_THAT(getDiagnosticString(),
4937 HasSubstr("GLSL.std.450 Length: "
4938 "expected Result Type to be a float scalar type"));
4939 }
4940
4941 TEST_F(ValidateExtInst, GlslStd450LengthIntX) {
4942 const std::string body = R"(
4943 %val1 = OpExtInst %f32 %extinst Length %u32vec2_01
4944 )";
4945
4946 CompileSuccessfully(GenerateShaderCode(body));
4947 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4948 EXPECT_THAT(getDiagnosticString(),
4949 HasSubstr("GLSL.std.450 Length: "
4950 "expected operand X to be of float scalar or "
4951 "vector type"));
4952 }
4953
4954 TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) {
4955 const std::string body = R"(
4956 %val1 = OpExtInst %f64 %extinst Length %f32vec2_01
4957 )";
4958
4959 CompileSuccessfully(GenerateShaderCode(body));
4960 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4961 EXPECT_THAT(getDiagnosticString(),
4962 HasSubstr("GLSL.std.450 Length: "
4963 "expected operand X component type to be equal to "
4964 "Result Type"));
4965 }
4966
4967 TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) {
4968 const std::string body = R"(
4969 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1
4970 %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12
4971 %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234
4972 )";
4973
4974 CompileSuccessfully(GenerateShaderCode(body));
4975 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4976 }
4977
4978 TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) {
4979 const std::string body = R"(
4980 %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12
4981 )";
4982
4983 CompileSuccessfully(GenerateShaderCode(body));
4984 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4985 EXPECT_THAT(getDiagnosticString(),
4986 HasSubstr("GLSL.std.450 Distance: "
4987 "expected Result Type to be a float scalar type"));
4988 }
4989
4990 TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) {
4991 const std::string body = R"(
4992 %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1
4993 )";
4994
4995 CompileSuccessfully(GenerateShaderCode(body));
4996 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4997 EXPECT_THAT(getDiagnosticString(),
4998 HasSubstr("GLSL.std.450 Distance: "
4999 "expected operand P0 to be of float scalar or "
5000 "vector type"));
5001 }
5002
5003 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) {
5004 const std::string body = R"(
5005 %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12
5006 )";
5007
5008 CompileSuccessfully(GenerateShaderCode(body));
5009 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5010 EXPECT_THAT(getDiagnosticString(),
5011 HasSubstr("GLSL.std.450 Distance: "
5012 "expected operand P0 component type to be equal to "
5013 "Result Type"));
5014 }
5015
5016 TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) {
5017 const std::string body = R"(
5018 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1
5019 )";
5020
5021 CompileSuccessfully(GenerateShaderCode(body));
5022 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5023 EXPECT_THAT(getDiagnosticString(),
5024 HasSubstr("GLSL.std.450 Distance: "
5025 "expected operand P1 to be of float scalar or "
5026 "vector type"));
5027 }
5028
5029 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) {
5030 const std::string body = R"(
5031 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01
5032 )";
5033
5034 CompileSuccessfully(GenerateShaderCode(body));
5035 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5036 EXPECT_THAT(getDiagnosticString(),
5037 HasSubstr("GLSL.std.450 Distance: "
5038 "expected operand P1 component type to be equal to "
5039 "Result Type"));
5040 }
5041
5042 TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) {
5043 const std::string body = R"(
5044 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123
5045 )";
5046
5047 CompileSuccessfully(GenerateShaderCode(body));
5048 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5049 EXPECT_THAT(getDiagnosticString(),
5050 HasSubstr("GLSL.std.450 Distance: "
5051 "expected operands P0 and P1 to have the same number "
5052 "of components"));
5053 }
5054
5055 TEST_F(ValidateExtInst, GlslStd450CrossSuccess) {
5056 const std::string body = R"(
5057 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
5058 )";
5059
5060 CompileSuccessfully(GenerateShaderCode(body));
5061 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5062 }
5063
5064 TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) {
5065 const std::string body = R"(
5066 %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
5067 )";
5068
5069 CompileSuccessfully(GenerateShaderCode(body));
5070 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5071 EXPECT_THAT(getDiagnosticString(),
5072 HasSubstr("GLSL.std.450 Cross: "
5073 "expected Result Type to be a float vector type"));
5074 }
5075
5076 TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) {
5077 const std::string body = R"(
5078 %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123
5079 )";
5080
5081 CompileSuccessfully(GenerateShaderCode(body));
5082 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5083 EXPECT_THAT(getDiagnosticString(),
5084 HasSubstr("GLSL.std.450 Cross: "
5085 "expected Result Type to have 3 components"));
5086 }
5087
5088 TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) {
5089 const std::string body = R"(
5090 %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123
5091 )";
5092
5093 CompileSuccessfully(GenerateShaderCode(body));
5094 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5095 EXPECT_THAT(getDiagnosticString(),
5096 HasSubstr("GLSL.std.450 Cross: "
5097 "expected operand X type to be equal to Result Type"));
5098 }
5099
5100 TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) {
5101 const std::string body = R"(
5102 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012
5103 )";
5104
5105 CompileSuccessfully(GenerateShaderCode(body));
5106 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5107 EXPECT_THAT(getDiagnosticString(),
5108 HasSubstr("GLSL.std.450 Cross: "
5109 "expected operand Y type to be equal to Result Type"));
5110 }
5111
5112 TEST_F(ValidateExtInst, GlslStd450RefractSuccess) {
5113 const std::string body = R"(
5114 %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1
5115 %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1
5116 )";
5117
5118 CompileSuccessfully(GenerateShaderCode(body));
5119 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5120 }
5121
5122 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) {
5123 const std::string body = R"(
5124 %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1
5125 )";
5126
5127 CompileSuccessfully(GenerateShaderCode(body));
5128 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5129 EXPECT_THAT(getDiagnosticString(),
5130 HasSubstr("GLSL.std.450 Refract: "
5131 "expected Result Type to be a float scalar or "
5132 "vector type"));
5133 }
5134
5135 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) {
5136 const std::string body = R"(
5137 %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1
5138 )";
5139
5140 CompileSuccessfully(GenerateShaderCode(body));
5141 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5142 EXPECT_THAT(getDiagnosticString(),
5143 HasSubstr("GLSL.std.450 Refract: "
5144 "expected operand I to be of type equal to "
5145 "Result Type"));
5146 }
5147
5148 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) {
5149 const std::string body = R"(
5150 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1
5151 )";
5152
5153 CompileSuccessfully(GenerateShaderCode(body));
5154 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5155 EXPECT_THAT(getDiagnosticString(),
5156 HasSubstr("GLSL.std.450 Refract: "
5157 "expected operand N to be of type equal to "
5158 "Result Type"));
5159 }
5160
5161 TEST_F(ValidateExtInst, GlslStd450RefractIntEta) {
5162 const std::string body = R"(
5163 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1
5164 )";
5165
5166 CompileSuccessfully(GenerateShaderCode(body));
5167 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5168 EXPECT_THAT(getDiagnosticString(),
5169 HasSubstr("GLSL.std.450 Refract: "
5170 "expected operand Eta to be a float scalar"));
5171 }
5172
5173 TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) {
5174 // SPIR-V issue 337: Eta can be 64-bit float scalar.
5175 const std::string body = R"(
5176 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1
5177 )";
5178
5179 CompileSuccessfully(GenerateShaderCode(body));
5180 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5181 EXPECT_THAT(getDiagnosticString(), Eq(""));
5182 }
5183
5184 TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) {
5185 const std::string body = R"(
5186 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01
5187 )";
5188
5189 CompileSuccessfully(GenerateShaderCode(body));
5190 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5191 EXPECT_THAT(getDiagnosticString(),
5192 HasSubstr("GLSL.std.450 Refract: "
5193 "expected operand Eta to be a float scalar"));
5194 }
5195
5196 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) {
5197 const std::string body = R"(
5198 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5199 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input
5200 )";
5201
5202 CompileSuccessfully(
5203 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5204 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5205 }
5206
5207 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
5208 const std::string body = R"(
5209 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5210 )";
5211
5212 CompileSuccessfully(GenerateShaderCode(body));
5213 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5214 EXPECT_THAT(getDiagnosticString(),
5215 HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5216 "capability InterpolationFunction"));
5217 }
5218
5219 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
5220 const std::string body = R"(
5221 %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
5222 )";
5223
5224 CompileSuccessfully(
5225 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5226 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5227 EXPECT_THAT(getDiagnosticString(),
5228 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5229 "expected Result Type to be a 32-bit float scalar "
5230 "or vector type"));
5231 }
5232
5233 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
5234 const std::string body = R"(
5235 %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
5236 )";
5237
5238 CompileSuccessfully(
5239 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5240 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5241 EXPECT_THAT(getDiagnosticString(),
5242 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5243 "expected Result Type to be a 32-bit float scalar "
5244 "or vector type"));
5245 }
5246
5247 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
5248 const std::string body = R"(
5249 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
5250 )";
5251
5252 CompileSuccessfully(
5253 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5254 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5255 EXPECT_THAT(getDiagnosticString(),
5256 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5257 "expected Interpolant to be a pointer"));
5258 }
5259
5260 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
5261 const std::string body = R"(
5262 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
5263 )";
5264
5265 CompileSuccessfully(
5266 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5267 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5268 EXPECT_THAT(getDiagnosticString(),
5269 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5270 "expected Interpolant data type to be equal to "
5271 "Result Type"));
5272 }
5273
5274 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
5275 const std::string body = R"(
5276 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
5277 )";
5278
5279 CompileSuccessfully(
5280 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5281 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5282 EXPECT_THAT(getDiagnosticString(),
5283 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5284 "expected Interpolant storage class to be Input"));
5285 }
5286
5287 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
5288 const std::string body = R"(
5289 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5290 )";
5291
5292 CompileSuccessfully(GenerateShaderCode(
5293 body, "OpCapability InterpolationFunction\n", "Vertex"));
5294 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5295 EXPECT_THAT(getDiagnosticString(),
5296 HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5297 "Fragment execution model"));
5298 }
5299
5300 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
5301 const std::string body = R"(
5302 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5303 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
5304 )";
5305
5306 CompileSuccessfully(
5307 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5308 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5309 }
5310
5311 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
5312 const std::string body = R"(
5313 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5314 )";
5315
5316 CompileSuccessfully(GenerateShaderCode(body));
5317 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5318 EXPECT_THAT(getDiagnosticString(),
5319 HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5320 "capability InterpolationFunction"));
5321 }
5322
5323 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
5324 const std::string body = R"(
5325 %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
5326 )";
5327
5328 CompileSuccessfully(
5329 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5330 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5331 EXPECT_THAT(getDiagnosticString(),
5332 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5333 "expected Result Type to be a 32-bit float scalar "
5334 "or vector type"));
5335 }
5336
5337 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
5338 const std::string body = R"(
5339 %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
5340 )";
5341
5342 CompileSuccessfully(
5343 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5344 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5345 EXPECT_THAT(getDiagnosticString(),
5346 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5347 "expected Result Type to be a 32-bit float scalar "
5348 "or vector type"));
5349 }
5350
5351 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
5352 const std::string body = R"(
5353 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
5354 )";
5355
5356 CompileSuccessfully(
5357 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5358 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5359 EXPECT_THAT(getDiagnosticString(),
5360 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5361 "expected Interpolant to be a pointer"));
5362 }
5363
5364 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
5365 const std::string body = R"(
5366 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
5367 )";
5368
5369 CompileSuccessfully(
5370 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5371 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5372 EXPECT_THAT(getDiagnosticString(),
5373 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5374 "expected Interpolant data type to be equal to "
5375 "Result Type"));
5376 }
5377
5378 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
5379 const std::string body = R"(
5380 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
5381 )";
5382
5383 CompileSuccessfully(
5384 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5385 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5386 EXPECT_THAT(getDiagnosticString(),
5387 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5388 "expected Interpolant storage class to be Input"));
5389 }
5390
5391 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
5392 const std::string body = R"(
5393 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
5394 )";
5395
5396 CompileSuccessfully(
5397 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5398 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5399 EXPECT_THAT(getDiagnosticString(),
5400 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5401 "expected Sample to be 32-bit integer"));
5402 }
5403
5404 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
5405 const std::string body = R"(
5406 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
5407 )";
5408
5409 CompileSuccessfully(
5410 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5411 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5412 EXPECT_THAT(getDiagnosticString(),
5413 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5414 "expected Sample to be 32-bit integer"));
5415 }
5416
5417 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
5418 const std::string body = R"(
5419 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5420 )";
5421
5422 CompileSuccessfully(GenerateShaderCode(
5423 body, "OpCapability InterpolationFunction\n", "Vertex"));
5424 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5425 EXPECT_THAT(getDiagnosticString(),
5426 HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5427 "Fragment execution model"));
5428 }
5429
5430 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
5431 const std::string body = R"(
5432 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5433 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5434 )";
5435
5436 CompileSuccessfully(
5437 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5438 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5439 }
5440
5441 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
5442 const std::string body = R"(
5443 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5444 )";
5445
5446 CompileSuccessfully(GenerateShaderCode(body));
5447 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5448 EXPECT_THAT(getDiagnosticString(),
5449 HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5450 "capability InterpolationFunction"));
5451 }
5452
5453 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
5454 const std::string body = R"(
5455 %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5456 )";
5457
5458 CompileSuccessfully(
5459 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5460 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5461 EXPECT_THAT(getDiagnosticString(),
5462 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5463 "expected Result Type to be a 32-bit float scalar "
5464 "or vector type"));
5465 }
5466
5467 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
5468 const std::string body = R"(
5469 %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5470 )";
5471
5472 CompileSuccessfully(
5473 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5474 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5475 EXPECT_THAT(getDiagnosticString(),
5476 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5477 "expected Result Type to be a 32-bit float scalar "
5478 "or vector type"));
5479 }
5480
5481 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
5482 const std::string body = R"(
5483 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
5484 )";
5485
5486 CompileSuccessfully(
5487 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5488 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5489 EXPECT_THAT(getDiagnosticString(),
5490 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5491 "expected Interpolant to be a pointer"));
5492 }
5493
5494 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
5495 const std::string body = R"(
5496 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5497 )";
5498
5499 CompileSuccessfully(
5500 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5501 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5502 EXPECT_THAT(getDiagnosticString(),
5503 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5504 "expected Interpolant data type to be equal to "
5505 "Result Type"));
5506 }
5507
5508 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
5509 const std::string body = R"(
5510 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
5511 )";
5512
5513 CompileSuccessfully(
5514 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5515 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5516 EXPECT_THAT(getDiagnosticString(),
5517 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5518 "expected Interpolant storage class to be Input"));
5519 }
5520
5521 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
5522 const std::string body = R"(
5523 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
5524 )";
5525
5526 CompileSuccessfully(
5527 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5528 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5529 EXPECT_THAT(getDiagnosticString(),
5530 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5531 "expected Offset to be a vector of 2 32-bit floats"));
5532 }
5533
5534 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
5535 const std::string body = R"(
5536 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
5537 )";
5538
5539 CompileSuccessfully(
5540 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5541 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5542 EXPECT_THAT(getDiagnosticString(),
5543 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5544 "expected Offset to be a vector of 2 32-bit floats"));
5545 }
5546
5547 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
5548 const std::string body = R"(
5549 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
5550 )";
5551
5552 CompileSuccessfully(
5553 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5554 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5555 EXPECT_THAT(getDiagnosticString(),
5556 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5557 "expected Offset to be a vector of 2 32-bit floats"));
5558 }
5559
5560 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
5561 const std::string body = R"(
5562 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
5563 )";
5564
5565 CompileSuccessfully(
5566 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5567 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5568 EXPECT_THAT(getDiagnosticString(),
5569 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5570 "expected Offset to be a vector of 2 32-bit floats"));
5571 }
5572
5573 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
5574 const std::string body = R"(
5575 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5576 )";
5577
5578 CompileSuccessfully(GenerateShaderCode(
5579 body, "OpCapability InterpolationFunction\n", "Vertex"));
5580 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5581 EXPECT_THAT(getDiagnosticString(),
5582 HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5583 "Fragment execution model"));
5584 }
5585
5586 TEST_P(ValidateOpenCLStdSqrtLike, Success) {
5587 const std::string ext_inst_name = GetParam();
5588 std::ostringstream ss;
5589 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
5590 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5591 << " %f32vec2_01\n";
5592 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
5593 << " %f32vec4_0123\n";
5594 ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
5595 CompileSuccessfully(GenerateKernelCode(ss.str()));
5596 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5597 }
5598
5599 TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
5600 const std::string ext_inst_name = GetParam();
5601 const std::string body =
5602 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5603
5604 CompileSuccessfully(GenerateKernelCode(body));
5605 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5606 EXPECT_THAT(getDiagnosticString(),
5607 HasSubstr("OpenCL.std " + ext_inst_name +
5608 ": expected Result Type to be a float scalar "
5609 "or vector type"));
5610 }
5611
5612 TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
5613 const std::string ext_inst_name = GetParam();
5614 const std::string body =
5615 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5616
5617 CompileSuccessfully(GenerateKernelCode(body));
5618 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5619 EXPECT_THAT(getDiagnosticString(),
5620 HasSubstr("OpenCL.std " + ext_inst_name +
5621 ": expected types of all operands to be equal to "
5622 "Result Type"));
5623 }
5624
5625 INSTANTIATE_TEST_SUITE_P(
5626 AllSqrtLike, ValidateOpenCLStdSqrtLike,
5627 ::testing::ValuesIn(std::vector<std::string>{
5628 "acos", "acosh", "acospi", "asin",
5629 "asinh", "asinpi", "atan", "atanh",
5630 "atanpi", "cbrt", "ceil", "cos",
5631 "cosh", "cospi", "erfc", "erf",
5632 "exp", "exp2", "exp10", "expm1",
5633 "fabs", "floor", "log", "log2",
5634 "log10", "log1p", "logb", "rint",
5635 "round", "rsqrt", "sin", "sinh",
5636 "sinpi", "sqrt", "tan", "tanh",
5637 "tanpi", "tgamma", "trunc", "half_cos",
5638 "half_exp", "half_exp2", "half_exp10", "half_log",
5639 "half_log2", "half_log10", "half_recip", "half_rsqrt",
5640 "half_sin", "half_sqrt", "half_tan", "lgamma",
5641 "native_cos", "native_exp", "native_exp2", "native_exp10",
5642 "native_log", "native_log2", "native_log10", "native_recip",
5643 "native_rsqrt", "native_sin", "native_sqrt", "native_tan",
5644 "degrees", "radians", "sign",
5645 }));
5646
5647 TEST_P(ValidateOpenCLStdFMinLike, Success) {
5648 const std::string ext_inst_name = GetParam();
5649 std::ostringstream ss;
5650 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5651 << " %f32_0 %f32_1\n";
5652 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5653 << " %f32vec2_01 %f32vec2_12\n";
5654 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5655 << " %f64_0 %f64_0\n";
5656 CompileSuccessfully(GenerateKernelCode(ss.str()));
5657 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5658 }
5659
5660 TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
5661 const std::string ext_inst_name = GetParam();
5662 const std::string body =
5663 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
5664
5665 CompileSuccessfully(GenerateKernelCode(body));
5666 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5667 EXPECT_THAT(getDiagnosticString(),
5668 HasSubstr("OpenCL.std " + ext_inst_name +
5669 ": expected Result Type to be a float scalar "
5670 "or vector type"));
5671 }
5672
5673 TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
5674 const std::string ext_inst_name = GetParam();
5675 const std::string body =
5676 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
5677
5678 CompileSuccessfully(GenerateKernelCode(body));
5679 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5680 EXPECT_THAT(getDiagnosticString(),
5681 HasSubstr("OpenCL.std " + ext_inst_name +
5682 ": expected types of all operands to be equal to "
5683 "Result Type"));
5684 }
5685
5686 TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
5687 const std::string ext_inst_name = GetParam();
5688 const std::string body =
5689 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
5690
5691 CompileSuccessfully(GenerateKernelCode(body));
5692 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5693 EXPECT_THAT(getDiagnosticString(),
5694 HasSubstr("OpenCL.std " + ext_inst_name +
5695 ": expected types of all operands to be equal to "
5696 "Result Type"));
5697 }
5698
5699 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
5700 ::testing::ValuesIn(std::vector<std::string>{
5701 "atan2", "atan2pi", "copysign",
5702 "fdim", "fmax", "fmin",
5703 "fmod", "maxmag", "minmag",
5704 "hypot", "nextafter", "pow",
5705 "powr", "remainder", "half_divide",
5706 "half_powr", "native_divide", "native_powr",
5707 "step", "fmax_common", "fmin_common",
5708 }));
5709
5710 TEST_P(ValidateOpenCLStdFClampLike, Success) {
5711 const std::string ext_inst_name = GetParam();
5712 std::ostringstream ss;
5713 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5714 << " %f32_0 %f32_1 %f32_2\n";
5715 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5716 << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
5717 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5718 << " %f64_0 %f64_0 %f64_1\n";
5719 CompileSuccessfully(GenerateKernelCode(ss.str()));
5720 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5721 }
5722
5723 TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
5724 const std::string ext_inst_name = GetParam();
5725 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5726 " %f32_0 %f32_1 %f32_2\n";
5727
5728 CompileSuccessfully(GenerateKernelCode(body));
5729 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5730 EXPECT_THAT(getDiagnosticString(),
5731 HasSubstr("OpenCL.std " + ext_inst_name +
5732 ": expected Result Type to be a float scalar "
5733 "or vector type"));
5734 }
5735
5736 TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
5737 const std::string ext_inst_name = GetParam();
5738 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5739 " %u32_0 %f32_0 %f32_1\n";
5740
5741 CompileSuccessfully(GenerateKernelCode(body));
5742 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5743 EXPECT_THAT(getDiagnosticString(),
5744 HasSubstr("OpenCL.std " + ext_inst_name +
5745 ": expected types of all operands to be equal to "
5746 "Result Type"));
5747 }
5748
5749 TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
5750 const std::string ext_inst_name = GetParam();
5751 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5752 " %f32_0 %u32_0 %f32_1\n";
5753
5754 CompileSuccessfully(GenerateKernelCode(body));
5755 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5756 EXPECT_THAT(getDiagnosticString(),
5757 HasSubstr("OpenCL.std " + ext_inst_name +
5758 ": expected types of all operands to be equal to "
5759 "Result Type"));
5760 }
5761
5762 TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
5763 const std::string ext_inst_name = GetParam();
5764 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5765 " %f32_1 %f32_0 %u32_2\n";
5766
5767 CompileSuccessfully(GenerateKernelCode(body));
5768 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5769 EXPECT_THAT(getDiagnosticString(),
5770 HasSubstr("OpenCL.std " + ext_inst_name +
5771 ": expected types of all operands to be equal to "
5772 "Result Type"));
5773 }
5774
5775 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
5776 ::testing::ValuesIn(std::vector<std::string>{
5777 "fma",
5778 "mad",
5779 "fclamp",
5780 "mix",
5781 "smoothstep",
5782 }));
5783
5784 TEST_P(ValidateOpenCLStdSAbsLike, Success) {
5785 const std::string ext_inst_name = GetParam();
5786 std::ostringstream ss;
5787 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5788 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5789 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5790 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5791 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5792 << " %u32vec2_01\n";
5793 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5794 << " %u32vec2_01\n";
5795 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5796 << " %u32vec2_01\n";
5797 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5798 << " %u32vec2_01\n";
5799 CompileSuccessfully(GenerateKernelCode(ss.str()));
5800 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5801 }
5802
5803 TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
5804 const std::string ext_inst_name = GetParam();
5805 const std::string body =
5806 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5807
5808 CompileSuccessfully(GenerateKernelCode(body));
5809 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5810 EXPECT_THAT(getDiagnosticString(),
5811 HasSubstr("OpenCL.std " + ext_inst_name +
5812 ": expected Result Type to be an int scalar "
5813 "or vector type"));
5814 }
5815
5816 TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
5817 const std::string ext_inst_name = GetParam();
5818 const std::string body =
5819 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5820
5821 CompileSuccessfully(GenerateKernelCode(body));
5822 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5823 EXPECT_THAT(
5824 getDiagnosticString(),
5825 HasSubstr("OpenCL.std " + ext_inst_name +
5826 ": expected types of all operands to be equal to Result Type"));
5827 }
5828
5829 TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
5830 const std::string ext_inst_name = GetParam();
5831 const std::string body =
5832 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
5833
5834 CompileSuccessfully(GenerateKernelCode(body));
5835 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5836 EXPECT_THAT(
5837 getDiagnosticString(),
5838 HasSubstr("OpenCL.std " + ext_inst_name +
5839 ": expected types of all operands to be equal to Result Type"));
5840 }
5841
5842 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
5843 ::testing::ValuesIn(std::vector<std::string>{
5844 "s_abs",
5845 "clz",
5846 "ctz",
5847 "popcount",
5848 "u_abs",
5849 }));
5850
5851 TEST_P(ValidateOpenCLStdUMinLike, Success) {
5852 const std::string ext_inst_name = GetParam();
5853 std::ostringstream ss;
5854 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5855 << " %u32_1 %u32_2\n";
5856 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5857 << " %u32_1 %u32_2\n";
5858 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5859 << " %u32_1 %u32_2\n";
5860 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5861 << " %u32_1 %u32_2\n";
5862 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5863 << " %u32vec2_01 %u32vec2_01\n";
5864 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5865 << " %u32vec2_01 %u32vec2_01\n";
5866 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5867 << " %u32vec2_01 %u32vec2_01\n";
5868 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5869 << " %u32vec2_01 %u32vec2_01\n";
5870 ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5871 << " %u64_1 %u64_0\n";
5872 CompileSuccessfully(GenerateKernelCode(ss.str()));
5873 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5874 }
5875
5876 TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
5877 const std::string ext_inst_name = GetParam();
5878 const std::string body =
5879 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
5880
5881 CompileSuccessfully(GenerateKernelCode(body));
5882 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5883 EXPECT_THAT(getDiagnosticString(),
5884 HasSubstr("OpenCL.std " + ext_inst_name +
5885 ": expected Result Type to be an int scalar "
5886 "or vector type"));
5887 }
5888
5889 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
5890 const std::string ext_inst_name = GetParam();
5891 const std::string body =
5892 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
5893
5894 CompileSuccessfully(GenerateKernelCode(body));
5895 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5896 EXPECT_THAT(
5897 getDiagnosticString(),
5898 HasSubstr("OpenCL.std " + ext_inst_name +
5899 ": expected types of all operands to be equal to Result Type"));
5900 }
5901
5902 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
5903 const std::string ext_inst_name = GetParam();
5904 const std::string body =
5905 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
5906
5907 CompileSuccessfully(GenerateKernelCode(body));
5908 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5909 EXPECT_THAT(
5910 getDiagnosticString(),
5911 HasSubstr("OpenCL.std " + ext_inst_name +
5912 ": expected types of all operands to be equal to Result Type"));
5913 }
5914
5915 TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
5916 const std::string ext_inst_name = GetParam();
5917 const std::string body =
5918 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
5919
5920 CompileSuccessfully(GenerateKernelCode(body));
5921 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5922 EXPECT_THAT(
5923 getDiagnosticString(),
5924 HasSubstr("OpenCL.std " + ext_inst_name +
5925 ": expected types of all operands to be equal to Result Type"));
5926 }
5927
5928 TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
5929 const std::string ext_inst_name = GetParam();
5930 const std::string body =
5931 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
5932
5933 CompileSuccessfully(GenerateKernelCode(body));
5934 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5935 EXPECT_THAT(
5936 getDiagnosticString(),
5937 HasSubstr("OpenCL.std " + ext_inst_name +
5938 ": expected types of all operands to be equal to Result Type"));
5939 }
5940
5941 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
5942 ::testing::ValuesIn(std::vector<std::string>{
5943 "s_max",
5944 "u_max",
5945 "s_min",
5946 "u_min",
5947 "s_abs_diff",
5948 "s_add_sat",
5949 "u_add_sat",
5950 "s_mul_hi",
5951 "rotate",
5952 "s_sub_sat",
5953 "u_sub_sat",
5954 "s_hadd",
5955 "u_hadd",
5956 "s_rhadd",
5957 "u_rhadd",
5958 "u_abs_diff",
5959 "u_mul_hi",
5960 }));
5961
5962 TEST_P(ValidateOpenCLStdUClampLike, Success) {
5963 const std::string ext_inst_name = GetParam();
5964 std::ostringstream ss;
5965 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5966 << " %u32_0 %u32_1 %u32_2\n";
5967 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5968 << " %u32_0 %u32_1 %u32_2\n";
5969 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5970 << " %u32_0 %u32_1 %u32_2\n";
5971 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5972 << " %u32_0 %u32_1 %u32_2\n";
5973 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5974 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5975 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5976 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5977 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5978 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5979 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5980 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
5981 ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5982 << " %u64_1 %u64_0 %u64_1\n";
5983 CompileSuccessfully(GenerateKernelCode(ss.str()));
5984 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5985 }
5986
5987 TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
5988 const std::string ext_inst_name = GetParam();
5989 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5990 " %u32_0 %u32_0 %u32_1\n";
5991
5992 CompileSuccessfully(GenerateKernelCode(body));
5993 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5994 EXPECT_THAT(getDiagnosticString(),
5995 HasSubstr("OpenCL.std " + ext_inst_name +
5996 ": expected Result Type to be an int scalar "
5997 "or vector type"));
5998 }
5999
6000 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
6001 const std::string ext_inst_name = GetParam();
6002 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6003 " %f32_0 %u32_0 %u32_1\n";
6004
6005 CompileSuccessfully(GenerateKernelCode(body));
6006 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6007 EXPECT_THAT(
6008 getDiagnosticString(),
6009 HasSubstr("OpenCL.std " + ext_inst_name +
6010 ": expected types of all operands to be equal to Result Type"));
6011 }
6012
6013 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
6014 const std::string ext_inst_name = GetParam();
6015 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6016 " %u32_0 %f32_0 %u32_1\n";
6017
6018 CompileSuccessfully(GenerateKernelCode(body));
6019 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6020 EXPECT_THAT(
6021 getDiagnosticString(),
6022 HasSubstr("OpenCL.std " + ext_inst_name +
6023 ": expected types of all operands to be equal to Result Type"));
6024 }
6025
6026 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
6027 const std::string ext_inst_name = GetParam();
6028 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6029 " %u32_0 %u32_0 %f32_1\n";
6030
6031 CompileSuccessfully(GenerateKernelCode(body));
6032 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6033 EXPECT_THAT(
6034 getDiagnosticString(),
6035 HasSubstr("OpenCL.std " + ext_inst_name +
6036 ": expected types of all operands to be equal to Result Type"));
6037 }
6038
6039 TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
6040 const std::string ext_inst_name = GetParam();
6041 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6042 " %f32_0 %u32_0 %u64_1\n";
6043
6044 CompileSuccessfully(GenerateKernelCode(body));
6045 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6046 EXPECT_THAT(
6047 getDiagnosticString(),
6048 HasSubstr("OpenCL.std " + ext_inst_name +
6049 ": expected types of all operands to be equal to Result Type"));
6050 }
6051
6052 TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
6053 const std::string ext_inst_name = GetParam();
6054 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6055 " %u32_0 %f32_0 %u64_1\n";
6056
6057 CompileSuccessfully(GenerateKernelCode(body));
6058 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6059 EXPECT_THAT(
6060 getDiagnosticString(),
6061 HasSubstr("OpenCL.std " + ext_inst_name +
6062 ": expected types of all operands to be equal to Result Type"));
6063 }
6064
6065 TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
6066 const std::string ext_inst_name = GetParam();
6067 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6068 " %u32_0 %u32_0 %u64_1\n";
6069
6070 CompileSuccessfully(GenerateKernelCode(body));
6071 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6072 EXPECT_THAT(
6073 getDiagnosticString(),
6074 HasSubstr("OpenCL.std " + ext_inst_name +
6075 ": expected types of all operands to be equal to Result Type"));
6076 }
6077
6078 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
6079 ::testing::ValuesIn(std::vector<std::string>{
6080 "s_clamp",
6081 "u_clamp",
6082 "s_mad_hi",
6083 "u_mad_sat",
6084 "s_mad_sat",
6085 "u_mad_hi",
6086 }));
6087
6088 // -------------------------------------------------------------
6089 TEST_P(ValidateOpenCLStdUMul24Like, Success) {
6090 const std::string ext_inst_name = GetParam();
6091 std::ostringstream ss;
6092 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6093 << " %u32_1 %u32_2\n";
6094 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6095 << " %u32_1 %u32_2\n";
6096 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6097 << " %u32_1 %u32_2\n";
6098 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6099 << " %u32_1 %u32_2\n";
6100 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6101 << " %u32vec2_01 %u32vec2_01\n";
6102 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6103 << " %u32vec2_01 %u32vec2_01\n";
6104 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6105 << " %u32vec2_01 %u32vec2_01\n";
6106 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6107 << " %u32vec2_01 %u32vec2_01\n";
6108 CompileSuccessfully(GenerateKernelCode(ss.str()));
6109 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6110 }
6111
6112 TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
6113 const std::string ext_inst_name = GetParam();
6114 const std::string body =
6115 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
6116
6117 CompileSuccessfully(GenerateKernelCode(body));
6118 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6119 EXPECT_THAT(
6120 getDiagnosticString(),
6121 HasSubstr(
6122 "OpenCL.std " + ext_inst_name +
6123 ": expected Result Type to be a 32-bit int scalar or vector type"));
6124 }
6125
6126 TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
6127 const std::string ext_inst_name = GetParam();
6128 const std::string body =
6129 "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
6130
6131 CompileSuccessfully(GenerateKernelCode(body));
6132 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6133 EXPECT_THAT(
6134 getDiagnosticString(),
6135 HasSubstr(
6136 "OpenCL.std " + ext_inst_name +
6137 ": expected Result Type to be a 32-bit int scalar or vector type"));
6138 }
6139
6140 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
6141 const std::string ext_inst_name = GetParam();
6142 const std::string body =
6143 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
6144
6145 CompileSuccessfully(GenerateKernelCode(body));
6146 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6147 EXPECT_THAT(
6148 getDiagnosticString(),
6149 HasSubstr("OpenCL.std " + ext_inst_name +
6150 ": expected types of all operands to be equal to Result Type"));
6151 }
6152
6153 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
6154 const std::string ext_inst_name = GetParam();
6155 const std::string body =
6156 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
6157
6158 CompileSuccessfully(GenerateKernelCode(body));
6159 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6160 EXPECT_THAT(
6161 getDiagnosticString(),
6162 HasSubstr("OpenCL.std " + ext_inst_name +
6163 ": expected types of all operands to be equal to Result Type"));
6164 }
6165
6166 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
6167 const std::string ext_inst_name = GetParam();
6168 const std::string body =
6169 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
6170
6171 CompileSuccessfully(GenerateKernelCode(body));
6172 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6173 EXPECT_THAT(
6174 getDiagnosticString(),
6175 HasSubstr("OpenCL.std " + ext_inst_name +
6176 ": expected types of all operands to be equal to Result Type"));
6177 }
6178
6179 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
6180 const std::string ext_inst_name = GetParam();
6181 const std::string body =
6182 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
6183
6184 CompileSuccessfully(GenerateKernelCode(body));
6185 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6186 EXPECT_THAT(
6187 getDiagnosticString(),
6188 HasSubstr("OpenCL.std " + ext_inst_name +
6189 ": expected types of all operands to be equal to Result Type"));
6190 }
6191
6192 INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
6193 ::testing::ValuesIn(std::vector<std::string>{
6194 "s_mul24",
6195 "u_mul24",
6196 }));
6197
6198 TEST_P(ValidateOpenCLStdUMad24Like, Success) {
6199 const std::string ext_inst_name = GetParam();
6200 std::ostringstream ss;
6201 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6202 << " %u32_0 %u32_1 %u32_2\n";
6203 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6204 << " %u32_0 %u32_1 %u32_2\n";
6205 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6206 << " %u32_0 %u32_1 %u32_2\n";
6207 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6208 << " %u32_0 %u32_1 %u32_2\n";
6209 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6210 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6211 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6212 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6213 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6214 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6215 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6216 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6217 CompileSuccessfully(GenerateKernelCode(ss.str()));
6218 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6219 }
6220
6221 TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
6222 const std::string ext_inst_name = GetParam();
6223 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6224 " %u32_0 %u32_0 %u32_1\n";
6225
6226 CompileSuccessfully(GenerateKernelCode(body));
6227 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6228 EXPECT_THAT(
6229 getDiagnosticString(),
6230 HasSubstr(
6231 "OpenCL.std " + ext_inst_name +
6232 ": expected Result Type to be a 32-bit int scalar or vector type"));
6233 }
6234
6235 TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
6236 const std::string ext_inst_name = GetParam();
6237 const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
6238 " %u64_0 %u64_0 %u64_1\n";
6239
6240 CompileSuccessfully(GenerateKernelCode(body));
6241 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6242 EXPECT_THAT(
6243 getDiagnosticString(),
6244 HasSubstr(
6245 "OpenCL.std " + ext_inst_name +
6246 ": expected Result Type to be a 32-bit int scalar or vector type"));
6247 }
6248
6249 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
6250 const std::string ext_inst_name = GetParam();
6251 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6252 " %f32_0 %u32_0 %u32_1\n";
6253
6254 CompileSuccessfully(GenerateKernelCode(body));
6255 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6256 EXPECT_THAT(
6257 getDiagnosticString(),
6258 HasSubstr("OpenCL.std " + ext_inst_name +
6259 ": expected types of all operands to be equal to Result Type"));
6260 }
6261
6262 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
6263 const std::string ext_inst_name = GetParam();
6264 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6265 " %u32_0 %f32_0 %u32_1\n";
6266
6267 CompileSuccessfully(GenerateKernelCode(body));
6268 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6269 EXPECT_THAT(
6270 getDiagnosticString(),
6271 HasSubstr("OpenCL.std " + ext_inst_name +
6272 ": expected types of all operands to be equal to Result Type"));
6273 }
6274
6275 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
6276 const std::string ext_inst_name = GetParam();
6277 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6278 " %u32_0 %u32_0 %f32_1\n";
6279
6280 CompileSuccessfully(GenerateKernelCode(body));
6281 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6282 EXPECT_THAT(
6283 getDiagnosticString(),
6284 HasSubstr("OpenCL.std " + ext_inst_name +
6285 ": expected types of all operands to be equal to Result Type"));
6286 }
6287
6288 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
6289 const std::string ext_inst_name = GetParam();
6290 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6291 " %f32_0 %u32_0 %u64_1\n";
6292
6293 CompileSuccessfully(GenerateKernelCode(body));
6294 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6295 EXPECT_THAT(
6296 getDiagnosticString(),
6297 HasSubstr("OpenCL.std " + ext_inst_name +
6298 ": expected types of all operands to be equal to Result Type"));
6299 }
6300
6301 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
6302 const std::string ext_inst_name = GetParam();
6303 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6304 " %u32_0 %f32_0 %u64_1\n";
6305
6306 CompileSuccessfully(GenerateKernelCode(body));
6307 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6308 EXPECT_THAT(
6309 getDiagnosticString(),
6310 HasSubstr("OpenCL.std " + ext_inst_name +
6311 ": expected types of all operands to be equal to Result Type"));
6312 }
6313
6314 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
6315 const std::string ext_inst_name = GetParam();
6316 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6317 " %u32_0 %u32_0 %u64_1\n";
6318
6319 CompileSuccessfully(GenerateKernelCode(body));
6320 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6321 EXPECT_THAT(
6322 getDiagnosticString(),
6323 HasSubstr("OpenCL.std " + ext_inst_name +
6324 ": expected types of all operands to be equal to Result Type"));
6325 }
6326
6327 INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
6328 ::testing::ValuesIn(std::vector<std::string>{
6329 "s_mad24",
6330 "u_mad24",
6331 }));
6332
6333 TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
6334 const std::string body = R"(
6335 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6336 %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
6337 )";
6338
6339 CompileSuccessfully(GenerateKernelCode(body));
6340 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6341 }
6342
6343 TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
6344 const std::string body = R"(
6345 %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6346 )";
6347
6348 CompileSuccessfully(GenerateKernelCode(body));
6349 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6350 EXPECT_THAT(getDiagnosticString(),
6351 HasSubstr("OpenCL.std cross: "
6352 "expected Result Type to be a float vector type"));
6353 }
6354
6355 TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
6356 const std::string body = R"(
6357 %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
6358 )";
6359
6360 CompileSuccessfully(GenerateKernelCode(body));
6361 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6362 EXPECT_THAT(getDiagnosticString(),
6363 HasSubstr("OpenCL.std cross: "
6364 "expected Result Type to have 3 or 4 components"));
6365 }
6366
6367 TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
6368 const std::string body = R"(
6369 %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
6370 )";
6371
6372 CompileSuccessfully(GenerateKernelCode(body));
6373 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6374 EXPECT_THAT(getDiagnosticString(),
6375 HasSubstr("OpenCL.std cross: "
6376 "expected operand X type to be equal to Result Type"));
6377 }
6378
6379 TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
6380 const std::string body = R"(
6381 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
6382 )";
6383
6384 CompileSuccessfully(GenerateKernelCode(body));
6385 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6386 EXPECT_THAT(getDiagnosticString(),
6387 HasSubstr("OpenCL.std cross: "
6388 "expected operand Y type to be equal to Result Type"));
6389 }
6390
6391 TEST_P(ValidateOpenCLStdLengthLike, Success) {
6392 const std::string ext_inst_name = GetParam();
6393 std::ostringstream ss;
6394 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
6395 ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6396 << " %f32vec4_0123\n";
6397
6398 CompileSuccessfully(GenerateKernelCode(ss.str()));
6399 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6400 }
6401
6402 TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
6403 const std::string ext_inst_name = GetParam();
6404 const std::string body =
6405 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
6406
6407 CompileSuccessfully(GenerateKernelCode(body));
6408 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6409 EXPECT_THAT(getDiagnosticString(),
6410 HasSubstr("OpenCL.std " + ext_inst_name +
6411 ": "
6412 "expected Result Type to be a float scalar type"));
6413 }
6414
6415 TEST_P(ValidateOpenCLStdLengthLike, IntX) {
6416 const std::string ext_inst_name = GetParam();
6417 const std::string body =
6418 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
6419
6420 CompileSuccessfully(GenerateKernelCode(body));
6421 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6422 EXPECT_THAT(getDiagnosticString(),
6423 HasSubstr("OpenCL.std " + ext_inst_name +
6424 ": "
6425 "expected operand P to be a float scalar or vector"));
6426 }
6427
6428 TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
6429 const std::string ext_inst_name = GetParam();
6430 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6431 " %f32vec8_01010101\n";
6432
6433 CompileSuccessfully(GenerateKernelCode(body));
6434 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6435 EXPECT_THAT(
6436 getDiagnosticString(),
6437 HasSubstr("OpenCL.std " + ext_inst_name +
6438 ": "
6439 "expected operand P to have no more than 4 components"));
6440 }
6441
6442 TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
6443 const std::string ext_inst_name = GetParam();
6444 const std::string body =
6445 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
6446
6447 CompileSuccessfully(GenerateKernelCode(body));
6448 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6449 EXPECT_THAT(getDiagnosticString(),
6450 HasSubstr("OpenCL.std " + ext_inst_name +
6451 ": "
6452 "expected operand P component type to be equal to "
6453 "Result Type"));
6454 }
6455
6456 INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
6457 ::testing::ValuesIn(std::vector<std::string>{
6458 "length",
6459 "fast_length",
6460 }));
6461
6462 TEST_P(ValidateOpenCLStdDistanceLike, Success) {
6463 const std::string ext_inst_name = GetParam();
6464 std::ostringstream ss;
6465 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6466 << " %f32vec2_01 %f32vec2_01\n";
6467 ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6468 << " %f32vec4_0123 %f32vec4_1234\n";
6469 ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
6470 << " %f32_0 %f32_1\n";
6471
6472 CompileSuccessfully(GenerateKernelCode(ss.str()));
6473 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6474 }
6475
6476 TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
6477 const std::string ext_inst_name = GetParam();
6478 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6479 " %f32vec2_01 %f32vec2_12\n";
6480
6481 CompileSuccessfully(GenerateKernelCode(body));
6482 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6483 EXPECT_THAT(getDiagnosticString(),
6484 HasSubstr("OpenCL.std " + ext_inst_name +
6485 ": "
6486 "expected Result Type to be a float scalar type"));
6487 }
6488
6489 TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
6490 const std::string ext_inst_name = GetParam();
6491 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6492 " %u32vec2_01 %f32vec2_12\n";
6493
6494 CompileSuccessfully(GenerateKernelCode(body));
6495 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6496 EXPECT_THAT(
6497 getDiagnosticString(),
6498 HasSubstr("OpenCL.std " + ext_inst_name +
6499 ": "
6500 "expected operand P0 to be of float scalar or vector type"));
6501 }
6502
6503 TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
6504 const std::string ext_inst_name = GetParam();
6505 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6506 " %f32vec8_01010101 %f32vec8_01010101\n";
6507
6508 CompileSuccessfully(GenerateKernelCode(body));
6509 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6510 EXPECT_THAT(
6511 getDiagnosticString(),
6512 HasSubstr("OpenCL.std " + ext_inst_name +
6513 ": "
6514 "expected operand P0 to have no more than 4 components"));
6515 }
6516
6517 TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
6518 const std::string ext_inst_name = GetParam();
6519 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6520 " %f64vec2_01 %f32vec2_12\n";
6521
6522 CompileSuccessfully(GenerateKernelCode(body));
6523 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6524 EXPECT_THAT(
6525 getDiagnosticString(),
6526 HasSubstr(
6527 "OpenCL.std " + ext_inst_name +
6528 ": "
6529 "expected operand P0 component type to be equal to Result Type"));
6530 }
6531
6532 TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
6533 const std::string ext_inst_name = GetParam();
6534 const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
6535 " %f64vec2_01 %f32vec2_12\n";
6536
6537 CompileSuccessfully(GenerateKernelCode(body));
6538 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6539 EXPECT_THAT(getDiagnosticString(),
6540 HasSubstr("OpenCL.std " + ext_inst_name +
6541 ": "
6542 "expected operands P0 and P1 to be of the same type"));
6543 }
6544
6545 INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
6546 ::testing::ValuesIn(std::vector<std::string>{
6547 "distance",
6548 "fast_distance",
6549 }));
6550
6551 TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
6552 const std::string ext_inst_name = GetParam();
6553 std::ostringstream ss;
6554 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6555 << " %f32vec2_01\n";
6556 ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
6557 << " %f32vec4_0123\n";
6558 ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
6559
6560 CompileSuccessfully(GenerateKernelCode(ss.str()));
6561 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6562 }
6563
6564 TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
6565 const std::string ext_inst_name = GetParam();
6566 const std::string body =
6567 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
6568
6569 CompileSuccessfully(GenerateKernelCode(body));
6570 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6571 EXPECT_THAT(
6572 getDiagnosticString(),
6573 HasSubstr("OpenCL.std " + ext_inst_name +
6574 ": "
6575 "expected Result Type to be a float scalar or vector type"));
6576 }
6577
6578 TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
6579 const std::string ext_inst_name = GetParam();
6580 const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
6581 ext_inst_name + " %f32vec8_01010101\n";
6582
6583 CompileSuccessfully(GenerateKernelCode(body));
6584 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6585 EXPECT_THAT(
6586 getDiagnosticString(),
6587 HasSubstr("OpenCL.std " + ext_inst_name +
6588 ": "
6589 "expected Result Type to have no more than 4 components"));
6590 }
6591
6592 TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
6593 const std::string ext_inst_name = GetParam();
6594 const std::string body =
6595 "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
6596
6597 CompileSuccessfully(GenerateKernelCode(body));
6598 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6599 EXPECT_THAT(getDiagnosticString(),
6600 HasSubstr("OpenCL.std " + ext_inst_name +
6601 ": "
6602 "expected operand P type to be equal to Result Type"));
6603 }
6604
6605 INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
6606 ::testing::ValuesIn(std::vector<std::string>{
6607 "normalize",
6608 "fast_normalize",
6609 }));
6610
6611 TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
6612 const std::string body = R"(
6613 %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
6614 %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
6615 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
6616 %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6617 %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
6618 )";
6619
6620 CompileSuccessfully(GenerateKernelCode(body));
6621 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6622 }
6623
6624 TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
6625 const std::string body = R"(
6626 %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
6627 )";
6628
6629 CompileSuccessfully(GenerateKernelCode(body));
6630 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6631 EXPECT_THAT(
6632 getDiagnosticString(),
6633 HasSubstr(
6634 "OpenCL.std bitselect: "
6635 "expected Result Type to be an int or float scalar or vector type"));
6636 }
6637
6638 TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
6639 const std::string body = R"(
6640 %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
6641 )";
6642
6643 CompileSuccessfully(GenerateKernelCode(body));
6644 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6645 EXPECT_THAT(
6646 getDiagnosticString(),
6647 HasSubstr("OpenCL.std bitselect: "
6648 "expected types of all operands to be equal to Result Type"));
6649 }
6650
6651 TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
6652 const std::string body = R"(
6653 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
6654 )";
6655
6656 CompileSuccessfully(GenerateKernelCode(body));
6657 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6658 EXPECT_THAT(
6659 getDiagnosticString(),
6660 HasSubstr("OpenCL.std bitselect: "
6661 "expected types of all operands to be equal to Result Type"));
6662 }
6663
6664 TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
6665 const std::string body = R"(
6666 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
6667 )";
6668
6669 CompileSuccessfully(GenerateKernelCode(body));
6670 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6671 EXPECT_THAT(
6672 getDiagnosticString(),
6673 HasSubstr("OpenCL.std bitselect: "
6674 "expected types of all operands to be equal to Result Type"));
6675 }
6676
6677 TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
6678 const std::string body = R"(
6679 %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
6680 %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
6681 %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
6682 %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6683 %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
6684 )";
6685
6686 CompileSuccessfully(GenerateKernelCode(body));
6687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6688 }
6689
6690 TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
6691 const std::string body = R"(
6692 %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
6693 )";
6694
6695 CompileSuccessfully(GenerateKernelCode(body));
6696 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6697 EXPECT_THAT(
6698 getDiagnosticString(),
6699 HasSubstr(
6700 "OpenCL.std select: "
6701 "expected Result Type to be an int or float scalar or vector type"));
6702 }
6703
6704 TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
6705 const std::string body = R"(
6706 %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
6707 )";
6708
6709 CompileSuccessfully(GenerateKernelCode(body));
6710 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6711 EXPECT_THAT(getDiagnosticString(),
6712 HasSubstr("OpenCL.std select: "
6713 "expected operand A type to be equal to Result Type"));
6714 }
6715
6716 TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
6717 const std::string body = R"(
6718 %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
6719 )";
6720
6721 CompileSuccessfully(GenerateKernelCode(body));
6722 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6723 EXPECT_THAT(getDiagnosticString(),
6724 HasSubstr("OpenCL.std select: "
6725 "expected operand B type to be equal to Result Type"));
6726 }
6727
6728 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
6729 const std::string body = R"(
6730 %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
6731 )";
6732
6733 CompileSuccessfully(GenerateKernelCode(body));
6734 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6735 EXPECT_THAT(getDiagnosticString(),
6736 HasSubstr("OpenCL.std select: "
6737 "expected operand C to be an int scalar or vector"));
6738 }
6739
6740 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
6741 const std::string body = R"(
6742 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
6743 )";
6744
6745 CompileSuccessfully(GenerateKernelCode(body));
6746 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6747 EXPECT_THAT(getDiagnosticString(),
6748 HasSubstr("OpenCL.std select: "
6749 "expected operand C to have the same number of "
6750 "components as Result Type"));
6751 }
6752
6753 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
6754 const std::string body = R"(
6755 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
6756 )";
6757
6758 CompileSuccessfully(GenerateKernelCode(body));
6759 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6760 EXPECT_THAT(
6761 getDiagnosticString(),
6762 HasSubstr(
6763 "OpenCL.std select: "
6764 "expected operand C to have the same bit width as Result Type"));
6765 }
6766
6767 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
6768 const std::string ext_inst_name = GetParam();
6769 const std::string rounding_mode =
6770 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6771
6772 std::ostringstream ss;
6773 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6774 if (std::string::npos == ext_inst_name.find("halfn")) {
6775 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6776 << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6777 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6778 << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
6779 } else {
6780 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6781 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6782 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6783 << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
6784 ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6785 << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
6786 }
6787
6788 CompileSuccessfully(GenerateKernelCode(ss.str()));
6789 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6790 }
6791
6792 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
6793 const std::string ext_inst_name = GetParam();
6794 const std::string rounding_mode =
6795 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6796
6797 std::ostringstream ss;
6798 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6799 if (std::string::npos == ext_inst_name.find("halfn")) {
6800 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6801 << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
6802 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6803 << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
6804 } else {
6805 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6806 << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
6807 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6808 << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
6809 ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6810 << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
6811 }
6812
6813 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6814 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6815 }
6816
6817 TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
6818 const std::string ext_inst_name = GetParam();
6819 const std::string rounding_mode =
6820 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6821
6822 std::ostringstream ss;
6823 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6824 if (std::string::npos == ext_inst_name.find("halfn")) {
6825 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6826 << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6827 } else {
6828 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6829 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6830 }
6831
6832 CompileSuccessfully(GenerateKernelCode(ss.str()));
6833 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6834 EXPECT_THAT(getDiagnosticString(),
6835 HasSubstr("OpenCL.std " + ext_inst_name +
6836 ": expected Result Type to be void"));
6837 }
6838
6839 TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
6840 const std::string ext_inst_name = GetParam();
6841 const std::string rounding_mode =
6842 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6843
6844 std::ostringstream ss;
6845 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6846 if (std::string::npos == ext_inst_name.find("halfn")) {
6847 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6848 << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6849 CompileSuccessfully(GenerateKernelCode(ss.str()));
6850 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6851 EXPECT_THAT(getDiagnosticString(),
6852 HasSubstr("OpenCL.std " + ext_inst_name +
6853 ": expected Data to be a 32 or 64-bit float scalar"));
6854 } else {
6855 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6856 << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
6857 CompileSuccessfully(GenerateKernelCode(ss.str()));
6858 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6859 EXPECT_THAT(getDiagnosticString(),
6860 HasSubstr("OpenCL.std " + ext_inst_name +
6861 ": expected Data to be a 32 or 64-bit float vector"));
6862 }
6863 }
6864
6865 TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
6866 const std::string ext_inst_name = GetParam();
6867 const std::string rounding_mode =
6868 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6869
6870 std::ostringstream ss;
6871 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6872 if (std::string::npos == ext_inst_name.find("halfn")) {
6873 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6874 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6875 } else {
6876 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6877 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6878 }
6879
6880 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
6881 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6882 EXPECT_THAT(getDiagnosticString(),
6883 HasSubstr("OpenCL.std " + ext_inst_name +
6884 " can only be used with physical addressing models"));
6885 }
6886
6887 TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
6888 const std::string ext_inst_name = GetParam();
6889 const std::string rounding_mode =
6890 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6891
6892 std::ostringstream ss;
6893 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6894 if (std::string::npos == ext_inst_name.find("halfn")) {
6895 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6896 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6897 } else {
6898 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6899 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6900 }
6901
6902 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6903 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6904 EXPECT_THAT(
6905 getDiagnosticString(),
6906 HasSubstr("OpenCL.std " + ext_inst_name +
6907 ": "
6908 "expected operand Offset to be of type size_t (64-bit integer "
6909 "for the addressing model used in the module)"));
6910 }
6911
6912 TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
6913 const std::string ext_inst_name = GetParam();
6914 const std::string rounding_mode =
6915 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6916
6917 std::ostringstream ss;
6918 if (std::string::npos == ext_inst_name.find("halfn")) {
6919 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6920 << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
6921 } else {
6922 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6923 << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
6924 }
6925
6926 CompileSuccessfully(GenerateKernelCode(ss.str()));
6927 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6928 EXPECT_THAT(getDiagnosticString(),
6929 HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
6930 }
6931
6932 TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
6933 const std::string ext_inst_name = GetParam();
6934 const std::string rounding_mode =
6935 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6936
6937 std::ostringstream ss;
6938 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
6939 "%f16vec8_uniform_constant %u32_1\n";
6940 if (std::string::npos == ext_inst_name.find("halfn")) {
6941 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6942 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6943 } else {
6944 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6945 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6946 }
6947
6948 CompileSuccessfully(GenerateKernelCode(ss.str()));
6949 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6950 EXPECT_THAT(getDiagnosticString(),
6951 HasSubstr("OpenCL.std " + ext_inst_name +
6952 ": expected operand P storage class to be Generic, "
6953 "CrossWorkgroup, Workgroup or Function"));
6954 }
6955
6956 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
6957 const std::string ext_inst_name = GetParam();
6958 const std::string rounding_mode =
6959 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6960
6961 std::ostringstream ss;
6962 ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
6963 if (std::string::npos == ext_inst_name.find("halfn")) {
6964 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6965 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6966 } else {
6967 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6968 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6969 }
6970
6971 CompileSuccessfully(GenerateKernelCode(ss.str()));
6972 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6973 EXPECT_THAT(
6974 getDiagnosticString(),
6975 HasSubstr("OpenCL.std " + ext_inst_name +
6976 ": expected operand P data type to be 16-bit float scalar"));
6977 }
6978
6979 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
6980 const std::string ext_inst_name = GetParam();
6981 const std::string rounding_mode =
6982 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6983
6984 std::ostringstream ss;
6985 ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
6986 if (std::string::npos == ext_inst_name.find("halfn")) {
6987 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6988 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
6989 } else {
6990 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6991 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6992 }
6993
6994 CompileSuccessfully(GenerateKernelCode(ss.str()));
6995 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6996 EXPECT_THAT(
6997 getDiagnosticString(),
6998 HasSubstr("OpenCL.std " + ext_inst_name +
6999 ": expected operand P data type to be 16-bit float scalar"));
7000 }
7001
7002 INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
7003 ::testing::ValuesIn(std::vector<std::string>{
7004 "vstore_half",
7005 "vstore_half_r",
7006 "vstore_halfn",
7007 "vstore_halfn_r",
7008 "vstorea_halfn",
7009 "vstorea_halfn_r",
7010 }));
7011
7012 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
7013 const std::string ext_inst_name = GetParam();
7014
7015 std::ostringstream ss;
7016 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7017 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7018 << " %u32_1 %ptr 2\n";
7019 ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7020 << " %u32_1 %ptr 3\n";
7021 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7022 << " %u32_1 %ptr 4\n";
7023
7024 CompileSuccessfully(GenerateKernelCode(ss.str()));
7025 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7026 }
7027
7028 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
7029 const std::string ext_inst_name = GetParam();
7030
7031 std::ostringstream ss;
7032 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7033 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7034 << " %u64_1 %ptr 2\n";
7035 ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7036 << " %u64_1 %ptr 3\n";
7037 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7038 << " %u64_1 %ptr 4\n";
7039
7040 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7041 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7042 }
7043
7044 TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
7045 const std::string ext_inst_name = GetParam();
7046
7047 std::ostringstream ss;
7048 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7049 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7050 << " %u32_1 %ptr 1\n";
7051
7052 CompileSuccessfully(GenerateKernelCode(ss.str()));
7053 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7054 EXPECT_THAT(getDiagnosticString(),
7055 HasSubstr("OpenCL.std " + ext_inst_name +
7056 ": expected Result Type to be a float vector type"));
7057 }
7058
7059 TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
7060 const std::string ext_inst_name = GetParam();
7061
7062 std::ostringstream ss;
7063 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7064 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7065 << " %u32_1 %ptr 2\n";
7066
7067 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7068 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7069 EXPECT_THAT(getDiagnosticString(),
7070 HasSubstr("OpenCL.std " + ext_inst_name +
7071 " can only be used with physical addressing models"));
7072 }
7073
7074 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
7075 const std::string ext_inst_name = GetParam();
7076
7077 std::ostringstream ss;
7078 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7079 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7080 << " %u64_1 %ptr 2\n";
7081
7082 CompileSuccessfully(GenerateKernelCode(ss.str()));
7083 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7084 EXPECT_THAT(
7085 getDiagnosticString(),
7086 HasSubstr("OpenCL.std " + ext_inst_name +
7087 ": expected operand Offset to be of type size_t (32-bit "
7088 "integer for the addressing model used in the module)"));
7089 }
7090
7091 TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
7092 const std::string ext_inst_name = GetParam();
7093
7094 std::ostringstream ss;
7095 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7096 << " %u32_1 %f16_ptr_workgroup 2\n";
7097
7098 CompileSuccessfully(GenerateKernelCode(ss.str()));
7099 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7100 EXPECT_THAT(getDiagnosticString(),
7101 HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
7102 }
7103
7104 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
7105 const std::string ext_inst_name = GetParam();
7106
7107 std::ostringstream ss;
7108 ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7109 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7110 << " %u32_1 %ptr 2\n";
7111
7112 CompileSuccessfully(GenerateKernelCode(ss.str()));
7113 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7114 EXPECT_THAT(
7115 getDiagnosticString(),
7116 HasSubstr("OpenCL.std " + ext_inst_name +
7117 ": expected operand P storage class to be UniformConstant, "
7118 "Generic, CrossWorkgroup, Workgroup or Function"));
7119 }
7120
7121 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
7122 const std::string ext_inst_name = GetParam();
7123
7124 std::ostringstream ss;
7125 ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7126 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7127 << " %u32_1 %ptr 2\n";
7128
7129 CompileSuccessfully(GenerateKernelCode(ss.str()));
7130 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7131 EXPECT_THAT(
7132 getDiagnosticString(),
7133 HasSubstr("OpenCL.std " + ext_inst_name +
7134 ": expected operand P data type to be 16-bit float scalar"));
7135 }
7136
7137 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
7138 const std::string ext_inst_name = GetParam();
7139
7140 std::ostringstream ss;
7141 ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7142 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7143 << " %u32_1 %ptr 2\n";
7144
7145 CompileSuccessfully(GenerateKernelCode(ss.str()));
7146 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7147 EXPECT_THAT(
7148 getDiagnosticString(),
7149 HasSubstr("OpenCL.std " + ext_inst_name +
7150 ": expected operand P data type to be 16-bit float scalar"));
7151 }
7152
7153 TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
7154 const std::string ext_inst_name = GetParam();
7155
7156 std::ostringstream ss;
7157 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7158 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7159 << " %u32_1 %ptr 3\n";
7160
7161 CompileSuccessfully(GenerateKernelCode(ss.str()));
7162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7163 EXPECT_THAT(getDiagnosticString(),
7164 HasSubstr("OpenCL.std " + ext_inst_name +
7165 ": expected literal N to be equal to the number of "
7166 "components of Result Type"));
7167 }
7168
7169 INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
7170 ::testing::ValuesIn(std::vector<std::string>{
7171 "vload_halfn",
7172 "vloada_halfn",
7173 }));
7174
7175 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
7176 std::ostringstream ss;
7177 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7178 "%f32vec8_uniform_constant %u32_1\n";
7179 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7180 ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7181 ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7182
7183 CompileSuccessfully(GenerateKernelCode(ss.str()));
7184 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7185 }
7186
7187 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
7188 std::ostringstream ss;
7189 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7190 "%u32vec8_uniform_constant %u32_1\n";
7191 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7192 ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7193 ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7194
7195 CompileSuccessfully(GenerateKernelCode(ss.str()));
7196 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7197 }
7198
7199 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
7200 std::ostringstream ss;
7201 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7202 "%f32vec8_uniform_constant %u32_1\n";
7203 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7204 ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7205 ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7206
7207 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7208 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7209 }
7210
7211 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
7212 std::ostringstream ss;
7213 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7214 "%u32vec8_uniform_constant %u32_1\n";
7215 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7216 ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7217 ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7218
7219 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7220 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7221 }
7222
7223 TEST_F(ValidateExtInst, VLoadNWrongResultType) {
7224 std::ostringstream ss;
7225 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7226 "%f32vec8_uniform_constant %u32_1\n";
7227 ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
7228
7229 CompileSuccessfully(GenerateKernelCode(ss.str()));
7230 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7231 EXPECT_THAT(
7232 getDiagnosticString(),
7233 HasSubstr("OpenCL.std vloadn: "
7234 "expected Result Type to be an int or float vector type"));
7235 }
7236
7237 TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
7238 std::ostringstream ss;
7239 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7240 "%f32vec8_uniform_constant %u32_1\n";
7241 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7242
7243 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7244 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7245 EXPECT_THAT(getDiagnosticString(),
7246 HasSubstr("OpenCL.std vloadn can only be used with physical "
7247 "addressing models"));
7248 }
7249
7250 TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
7251 std::ostringstream ss;
7252 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7253 "%f32vec8_uniform_constant %u32_1\n";
7254 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7255
7256 CompileSuccessfully(GenerateKernelCode(ss.str()));
7257 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7258 EXPECT_THAT(
7259 getDiagnosticString(),
7260 HasSubstr(
7261 "OpenCL.std vloadn: expected operand Offset to be of type size_t "
7262 "(32-bit integer for the addressing model used in the module)"));
7263 }
7264
7265 TEST_F(ValidateExtInst, VLoadNPNotPointer) {
7266 std::ostringstream ss;
7267 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
7268 "%f32_ptr_uniform_constant 2\n";
7269
7270 CompileSuccessfully(GenerateKernelCode(ss.str()));
7271 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7272 EXPECT_THAT(getDiagnosticString(),
7273 HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
7274 "type"));
7275 }
7276
7277 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
7278 std::ostringstream ss;
7279 ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
7280 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7281
7282 CompileSuccessfully(GenerateKernelCode(ss.str()));
7283 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7284 EXPECT_THAT(getDiagnosticString(),
7285 HasSubstr("OpenCL.std vloadn: expected operand P storage class "
7286 "to be UniformConstant, Generic, CrossWorkgroup, "
7287 "Workgroup or Function"));
7288 }
7289
7290 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
7291 std::ostringstream ss;
7292 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7293 "%f32vec8_uniform_constant %u32_1\n";
7294 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7295
7296 CompileSuccessfully(GenerateKernelCode(ss.str()));
7297 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7298 EXPECT_THAT(getDiagnosticString(),
7299 HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
7300 "equal to component type of Result Type"));
7301 }
7302
7303 TEST_F(ValidateExtInst, VLoadNWrongN) {
7304 std::ostringstream ss;
7305 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7306 "%f32vec8_uniform_constant %u32_1\n";
7307 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
7308
7309 CompileSuccessfully(GenerateKernelCode(ss.str()));
7310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7311 EXPECT_THAT(getDiagnosticString(),
7312 HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
7313 "the number of components of Result Type"));
7314 }
7315
7316 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
7317 std::ostringstream ss;
7318 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7319 "%f16vec8_uniform_constant %u32_1\n";
7320 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7321 ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
7322
7323 CompileSuccessfully(GenerateKernelCode(ss.str()));
7324 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7325 }
7326
7327 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
7328 std::ostringstream ss;
7329 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7330 "%f16vec8_uniform_constant %u32_1\n";
7331 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7332 ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
7333
7334 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7335 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7336 }
7337
7338 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
7339 std::ostringstream ss;
7340 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7341 "%f16vec8_uniform_constant %u32_1\n";
7342 ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
7343
7344 CompileSuccessfully(GenerateKernelCode(ss.str()));
7345 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7346 EXPECT_THAT(getDiagnosticString(),
7347 HasSubstr("OpenCL.std vload_half: "
7348 "expected Result Type to be a float scalar type"));
7349 }
7350
7351 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
7352 std::ostringstream ss;
7353 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7354 "%f16vec8_uniform_constant %u32_1\n";
7355 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7356
7357 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7358 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7359 EXPECT_THAT(getDiagnosticString(),
7360 HasSubstr("OpenCL.std vload_half can only be used with physical "
7361 "addressing models"));
7362 }
7363
7364 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
7365 std::ostringstream ss;
7366 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7367 "%f16vec8_uniform_constant %u32_1\n";
7368 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7369
7370 CompileSuccessfully(GenerateKernelCode(ss.str()));
7371 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7372 EXPECT_THAT(
7373 getDiagnosticString(),
7374 HasSubstr(
7375 "OpenCL.std vload_half: expected operand Offset to be of type size_t "
7376 "(32-bit integer for the addressing model used in the module)"));
7377 }
7378
7379 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
7380 std::ostringstream ss;
7381 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
7382 "%f16_ptr_uniform_constant\n";
7383
7384 CompileSuccessfully(GenerateKernelCode(ss.str()));
7385 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7386 EXPECT_THAT(getDiagnosticString(),
7387 HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
7388 "type"));
7389 }
7390
7391 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
7392 std::ostringstream ss;
7393 ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7394 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7395
7396 CompileSuccessfully(GenerateKernelCode(ss.str()));
7397 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7398 EXPECT_THAT(
7399 getDiagnosticString(),
7400 HasSubstr(
7401 "OpenCL.std vload_half: expected operand P storage class to be "
7402 "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
7403 }
7404
7405 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
7406 std::ostringstream ss;
7407 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7408 "%u32vec8_uniform_constant %u32_1\n";
7409 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7410
7411 CompileSuccessfully(GenerateKernelCode(ss.str()));
7412 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7413 EXPECT_THAT(getDiagnosticString(),
7414 HasSubstr("OpenCL.std vload_half: expected operand P data type "
7415 "to be 16-bit float scalar"));
7416 }
7417
7418 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
7419 std::ostringstream ss;
7420 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7421 "%f32vec8_uniform_constant %u32_1\n";
7422 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7423
7424 CompileSuccessfully(GenerateKernelCode(ss.str()));
7425 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7426 EXPECT_THAT(getDiagnosticString(),
7427 HasSubstr("OpenCL.std vload_half: expected operand P data type "
7428 "to be 16-bit float scalar"));
7429 }
7430
7431 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
7432 std::ostringstream ss;
7433 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7434 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7435 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7436 ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
7437 "%ptr_g\n";
7438
7439 CompileSuccessfully(GenerateKernelCode(ss.str()));
7440 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7441 }
7442
7443 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
7444 std::ostringstream ss;
7445 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7446 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7447 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
7448 ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
7449 "%ptr_g\n";
7450
7451 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7452 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7453 }
7454
7455 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
7456 std::ostringstream ss;
7457 ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7458 ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7459 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7460 ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
7461 "%ptr_g\n";
7462
7463 CompileSuccessfully(GenerateKernelCode(ss.str()));
7464 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7465 }
7466
7467 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
7468 std::ostringstream ss;
7469 ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7470 ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7471 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
7472 ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
7473 "%ptr_g\n";
7474
7475 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7476 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7477 }
7478
7479 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
7480 std::ostringstream ss;
7481 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7482 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7483 ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7484
7485 CompileSuccessfully(GenerateKernelCode(ss.str()));
7486 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7487 EXPECT_THAT(getDiagnosticString(),
7488 HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
7489 }
7490
7491 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
7492 std::ostringstream ss;
7493 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7494 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7495 ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
7496
7497 CompileSuccessfully(GenerateKernelCode(ss.str()));
7498 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7499 EXPECT_THAT(
7500 getDiagnosticString(),
7501 HasSubstr(
7502 "OpenCL.std vstoren: expected Data to be an int or float vector"));
7503 }
7504
7505 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
7506 std::ostringstream ss;
7507 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7508 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7509 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7510
7511 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7512 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7513 EXPECT_THAT(getDiagnosticString(),
7514 HasSubstr("OpenCL.std vstoren can only be used with physical "
7515 "addressing models"));
7516 }
7517
7518 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
7519 std::ostringstream ss;
7520 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7521 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7522 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7523
7524 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7525 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7526 EXPECT_THAT(
7527 getDiagnosticString(),
7528 HasSubstr(
7529 "OpenCL.std vstoren: expected operand Offset to be of type size_t "
7530 "(64-bit integer for the addressing model used in the module)"));
7531 }
7532
7533 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
7534 std::ostringstream ss;
7535 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
7536 "%f32_ptr_generic\n";
7537
7538 CompileSuccessfully(GenerateKernelCode(ss.str()));
7539 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7540 EXPECT_THAT(getDiagnosticString(),
7541 HasSubstr("Operand 127[%_ptr_Generic_float] cannot be a type"));
7542 }
7543
7544 TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
7545 std::ostringstream ss;
7546 ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
7547 "%f32vec8_uniform_constant %u32_1\n";
7548 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
7549
7550 CompileSuccessfully(GenerateKernelCode(ss.str()));
7551 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7552 EXPECT_THAT(
7553 getDiagnosticString(),
7554 HasSubstr("OpenCL.std vstoren: expected operand P storage class "
7555 "to be Generic, CrossWorkgroup, Workgroup or Function"));
7556 }
7557
7558 TEST_F(ValidateExtInst, VStorePWrongDataType) {
7559 std::ostringstream ss;
7560 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7561 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7562 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7563
7564 CompileSuccessfully(GenerateKernelCode(ss.str()));
7565 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7566 EXPECT_THAT(getDiagnosticString(),
7567 HasSubstr("OpenCL.std vstoren: expected operand P data type to "
7568 "be equal to the type of operand Data components"));
7569 }
7570
7571 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
7572 const std::string body = R"(
7573 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
7574 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
7575 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
7576 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
7577 )";
7578
7579 CompileSuccessfully(GenerateKernelCode(body));
7580 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7581 }
7582
7583 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
7584 const std::string body = R"(
7585 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
7586 )";
7587
7588 CompileSuccessfully(GenerateKernelCode(body));
7589 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7590 EXPECT_THAT(
7591 getDiagnosticString(),
7592 HasSubstr("OpenCL.std shuffle: "
7593 "expected Result Type to be an int or float vector type"));
7594 }
7595
7596 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
7597 const std::string body = R"(
7598 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
7599 )";
7600
7601 CompileSuccessfully(GenerateKernelCode(body));
7602 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7603 EXPECT_THAT(
7604 getDiagnosticString(),
7605 HasSubstr("OpenCL.std shuffle: "
7606 "expected Result Type to have 2, 4, 8 or 16 components"));
7607 }
7608
7609 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
7610 const std::string body = R"(
7611 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
7612 )";
7613
7614 CompileSuccessfully(GenerateKernelCode(body));
7615 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7616 EXPECT_THAT(getDiagnosticString(),
7617 HasSubstr("OpenCL.std shuffle: "
7618 "expected operand X to be an int or float vector"));
7619 }
7620
7621 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
7622 const std::string body = R"(
7623 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
7624 )";
7625
7626 CompileSuccessfully(GenerateKernelCode(body));
7627 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7628 EXPECT_THAT(getDiagnosticString(),
7629 HasSubstr("OpenCL.std shuffle: "
7630 "expected operand X to have 2, 4, 8 or 16 components"));
7631 }
7632
7633 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
7634 const std::string body = R"(
7635 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7636 )";
7637
7638 CompileSuccessfully(GenerateKernelCode(body));
7639 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7640 EXPECT_THAT(
7641 getDiagnosticString(),
7642 HasSubstr(
7643 "OpenCL.std shuffle: "
7644 "expected operand X and Result Type to have equal component types"));
7645 }
7646
7647 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
7648 const std::string body = R"(
7649 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
7650 )";
7651
7652 CompileSuccessfully(GenerateKernelCode(body));
7653 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7654 EXPECT_THAT(getDiagnosticString(),
7655 HasSubstr("OpenCL.std shuffle: "
7656 "expected operand Shuffle Mask to be an int vector"));
7657 }
7658
7659 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
7660 const std::string body = R"(
7661 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
7662 )";
7663
7664 CompileSuccessfully(GenerateKernelCode(body));
7665 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7666 EXPECT_THAT(getDiagnosticString(),
7667 HasSubstr("OpenCL.std shuffle: "
7668 "expected operand Shuffle Mask to have the same number "
7669 "of components as Result Type"));
7670 }
7671
7672 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
7673 const std::string body = R"(
7674 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7675 )";
7676
7677 CompileSuccessfully(GenerateKernelCode(body));
7678 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7679 EXPECT_THAT(getDiagnosticString(),
7680 HasSubstr("OpenCL.std shuffle: "
7681 "expected operand Shuffle Mask components to have the "
7682 "same bit width as Result Type components"));
7683 }
7684
7685 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
7686 const std::string body = R"(
7687 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7688 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
7689 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
7690 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
7691 )";
7692
7693 CompileSuccessfully(GenerateKernelCode(body));
7694 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7695 }
7696
7697 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
7698 const std::string body = R"(
7699 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7700 )";
7701
7702 CompileSuccessfully(GenerateKernelCode(body));
7703 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7704 EXPECT_THAT(
7705 getDiagnosticString(),
7706 HasSubstr("OpenCL.std shuffle2: "
7707 "expected Result Type to be an int or float vector type"));
7708 }
7709
7710 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
7711 const std::string body = R"(
7712 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
7713 )";
7714
7715 CompileSuccessfully(GenerateKernelCode(body));
7716 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7717 EXPECT_THAT(
7718 getDiagnosticString(),
7719 HasSubstr("OpenCL.std shuffle2: "
7720 "expected Result Type to have 2, 4, 8 or 16 components"));
7721 }
7722
7723 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
7724 const std::string body = R"(
7725 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
7726 )";
7727
7728 CompileSuccessfully(GenerateKernelCode(body));
7729 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7730 EXPECT_THAT(getDiagnosticString(),
7731 HasSubstr("OpenCL.std shuffle2: "
7732 "expected operand X to be an int or float vector"));
7733 }
7734
7735 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
7736 const std::string body = R"(
7737 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
7738 )";
7739
7740 CompileSuccessfully(GenerateKernelCode(body));
7741 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7742 EXPECT_THAT(getDiagnosticString(),
7743 HasSubstr("OpenCL.std shuffle2: "
7744 "expected operands X and Y to be of the same type"));
7745 }
7746
7747 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
7748 const std::string body = R"(
7749 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
7750 )";
7751
7752 CompileSuccessfully(GenerateKernelCode(body));
7753 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7754 EXPECT_THAT(getDiagnosticString(),
7755 HasSubstr("OpenCL.std shuffle2: "
7756 "expected operand X to have 2, 4, 8 or 16 components"));
7757 }
7758
7759 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
7760 const std::string body = R"(
7761 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7762 )";
7763
7764 CompileSuccessfully(GenerateKernelCode(body));
7765 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7766 EXPECT_THAT(
7767 getDiagnosticString(),
7768 HasSubstr(
7769 "OpenCL.std shuffle2: "
7770 "expected operand X and Result Type to have equal component types"));
7771 }
7772
7773 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
7774 const std::string body = R"(
7775 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
7776 )";
7777
7778 CompileSuccessfully(GenerateKernelCode(body));
7779 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7780 EXPECT_THAT(getDiagnosticString(),
7781 HasSubstr("OpenCL.std shuffle2: "
7782 "expected operand Shuffle Mask to be an int vector"));
7783 }
7784
7785 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
7786 const std::string body = R"(
7787 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7788 )";
7789
7790 CompileSuccessfully(GenerateKernelCode(body));
7791 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7792 EXPECT_THAT(getDiagnosticString(),
7793 HasSubstr("OpenCL.std shuffle2: "
7794 "expected operand Shuffle Mask to have the same number "
7795 "of components as Result Type"));
7796 }
7797
7798 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
7799 const std::string body = R"(
7800 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7801 )";
7802
7803 CompileSuccessfully(GenerateKernelCode(body));
7804 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7805 EXPECT_THAT(getDiagnosticString(),
7806 HasSubstr("OpenCL.std shuffle2: "
7807 "expected operand Shuffle Mask components to have the "
7808 "same bit width as Result Type components"));
7809 }
7810
7811 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
7812 const std::string body = R"(
7813 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7814 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7815 )";
7816
7817 CompileSuccessfully(GenerateKernelCode(body));
7818 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7819 }
7820
7821 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
7822 const std::string body = R"(
7823 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7824 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
7825 )";
7826
7827 CompileSuccessfully(GenerateKernelCode(body));
7828 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7829 EXPECT_THAT(
7830 getDiagnosticString(),
7831 HasSubstr(
7832 "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7833 }
7834
7835 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
7836 const std::string body = R"(
7837 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7838 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
7839 )";
7840
7841 CompileSuccessfully(GenerateKernelCode(body));
7842 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7843 EXPECT_THAT(
7844 getDiagnosticString(),
7845 HasSubstr(
7846 "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7847 }
7848
7849 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
7850 const std::string body = R"(
7851 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
7852 )";
7853
7854 CompileSuccessfully(GenerateKernelCode(body));
7855 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7856 EXPECT_THAT(getDiagnosticString(),
7857 HasSubstr("Operand 137[%_ptr_UniformConstant_uchar] cannot be a "
7858 "type"));
7859 }
7860
7861 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
7862 const std::string body = R"(
7863 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7864 %format = OpBitcast %u8_ptr_generic %format_const
7865 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7866 )";
7867
7868 CompileSuccessfully(GenerateKernelCode(body));
7869 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7870 EXPECT_THAT(getDiagnosticString(),
7871 HasSubstr("OpenCL.std printf: expected Format storage class to "
7872 "be UniformConstant"));
7873 }
7874
7875 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
7876 const std::string body = R"(
7877 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
7878 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7879 )";
7880
7881 CompileSuccessfully(GenerateKernelCode(body));
7882 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7883 EXPECT_THAT(
7884 getDiagnosticString(),
7885 HasSubstr(
7886 "OpenCL.std printf: expected Format data type to be 8-bit int"));
7887 }
7888
7889 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
7890 const std::string body = R"(
7891 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7892 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7893 )";
7894
7895 CompileSuccessfully(GenerateKernelCode(body));
7896 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7897 }
7898
7899 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
7900 const std::string body = R"(
7901 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7902 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
7903 )";
7904
7905 CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
7906 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7907 }
7908
7909 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
7910 const std::string body = R"(
7911 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
7912 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7913 )";
7914
7915 CompileSuccessfully(GenerateKernelCode(body));
7916 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7917 }
7918
7919 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
7920 const std::string body = R"(
7921 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
7922 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7923 )";
7924
7925 CompileSuccessfully(GenerateKernelCode(body));
7926 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7927 }
7928
7929 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
7930 const std::string body = R"(
7931 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7932 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
7933 )";
7934
7935 CompileSuccessfully(GenerateKernelCode(body));
7936 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7937 EXPECT_THAT(
7938 getDiagnosticString(),
7939 HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
7940 }
7941
7942 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
7943 const std::string body = R"(
7944 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
7945 )";
7946
7947 CompileSuccessfully(GenerateKernelCode(body));
7948 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7949 EXPECT_THAT(getDiagnosticString(),
7950 HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
7951 "type"));
7952 }
7953
7954 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
7955 const std::string body = R"(
7956 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7957 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7958 )";
7959
7960 CompileSuccessfully(GenerateKernelCode(body));
7961 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7962 EXPECT_THAT(getDiagnosticString(),
7963 HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
7964 "class to be CrossWorkgroup"));
7965 }
7966
7967 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
7968 const std::string body = R"(
7969 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
7970 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7971 )";
7972
7973 CompileSuccessfully(GenerateKernelCode(body));
7974 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7975 EXPECT_THAT(getDiagnosticString(),
7976 HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
7977 "or float scalar or vector"));
7978 }
7979
7980 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
7981 const std::string body = R"(
7982 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
7983 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7984 )";
7985
7986 CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
7987 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7988 EXPECT_THAT(getDiagnosticString(),
7989 HasSubstr("OpenCL.std prefetch can only be used with physical "
7990 "addressing models"));
7991 }
7992
7993 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
7994 const std::string body = R"(
7995 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
7996 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
7997 )";
7998
7999 CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
8000 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8001 EXPECT_THAT(getDiagnosticString(),
8002 HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
8003 "be of type size_t (64-bit integer for the addressing "
8004 "model used in the module)"));
8005 }
8006
8007 TEST_P(ValidateOpenCLStdFractLike, Success) {
8008 const std::string ext_inst_name = GetParam();
8009 std::ostringstream ss;
8010 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8011 ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
8012 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8013 << " %f32_0 %var_f32\n";
8014 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8015 << " %f32vec2_01 %var_f32vec2\n";
8016
8017 CompileSuccessfully(GenerateKernelCode(ss.str()));
8018 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8019 }
8020
8021 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
8022 const std::string ext_inst_name = GetParam();
8023 std::ostringstream ss;
8024 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8025 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8026 << " %f32_0 %var_f32\n";
8027
8028 CompileSuccessfully(GenerateKernelCode(ss.str()));
8029 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8030 EXPECT_THAT(
8031 getDiagnosticString(),
8032 HasSubstr("OpenCL.std " + ext_inst_name +
8033 ": expected Result Type to be a float scalar or vector type"));
8034 }
8035
8036 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
8037 const std::string ext_inst_name = GetParam();
8038 std::ostringstream ss;
8039 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8040 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8041 << " %f64_0 %var_f32\n";
8042
8043 CompileSuccessfully(GenerateKernelCode(ss.str()));
8044 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8045 EXPECT_THAT(
8046 getDiagnosticString(),
8047 HasSubstr("OpenCL.std " + ext_inst_name +
8048 ": expected type of operand X to be equal to Result Type"));
8049 }
8050
8051 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
8052 const std::string ext_inst_name = GetParam();
8053 std::ostringstream ss;
8054 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8055 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8056 << " %f32_0 %f32_1\n";
8057
8058 CompileSuccessfully(GenerateKernelCode(ss.str()));
8059 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8060 EXPECT_THAT(getDiagnosticString(),
8061 HasSubstr("OpenCL.std " + ext_inst_name +
8062 ": expected the last operand to be a pointer"));
8063 }
8064
8065 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
8066 const std::string ext_inst_name = GetParam();
8067 std::ostringstream ss;
8068 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8069 "%f32vec8_uniform_constant %u32_1\n";
8070 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8071
8072 CompileSuccessfully(GenerateKernelCode(ss.str()));
8073 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8074 EXPECT_THAT(getDiagnosticString(),
8075 HasSubstr("OpenCL.std " + ext_inst_name +
8076 ": expected storage class of the pointer to be "
8077 "Generic, CrossWorkgroup, Workgroup or Function"));
8078 }
8079
8080 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
8081 const std::string ext_inst_name = GetParam();
8082 std::ostringstream ss;
8083 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8084 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8085 << " %f32_0 %var_u32\n";
8086
8087 CompileSuccessfully(GenerateKernelCode(ss.str()));
8088 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8089 EXPECT_THAT(
8090 getDiagnosticString(),
8091 HasSubstr(
8092 "OpenCL.std " + ext_inst_name +
8093 ": expected data type of the pointer to be equal to Result Type"));
8094 }
8095
8096 INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
8097 ::testing::ValuesIn(std::vector<std::string>{
8098 "fract",
8099 "modf",
8100 "sincos",
8101 }));
8102
8103 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
8104 const std::string body = R"(
8105 %var_u32 = OpVariable %u32_ptr_function Function
8106 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8107 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
8108 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
8109 )";
8110
8111 CompileSuccessfully(GenerateKernelCode(body));
8112 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8113 }
8114
8115 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
8116 const std::string body = R"(
8117 %var_u32 = OpVariable %u32_ptr_function Function
8118 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
8119 )";
8120
8121 CompileSuccessfully(GenerateKernelCode(body));
8122 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8123 EXPECT_THAT(
8124 getDiagnosticString(),
8125 HasSubstr("OpenCL.std remquo: "
8126 "expected Result Type to be a float scalar or vector type"));
8127 }
8128
8129 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
8130 const std::string body = R"(
8131 %var_u32 = OpVariable %f32_ptr_function Function
8132 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
8133 )";
8134
8135 CompileSuccessfully(GenerateKernelCode(body));
8136 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8137 EXPECT_THAT(
8138 getDiagnosticString(),
8139 HasSubstr("OpenCL.std remquo: "
8140 "expected type of operand X to be equal to Result Type"));
8141 }
8142
8143 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
8144 const std::string body = R"(
8145 %var_u32 = OpVariable %f32_ptr_function Function
8146 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
8147 )";
8148
8149 CompileSuccessfully(GenerateKernelCode(body));
8150 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8151 EXPECT_THAT(
8152 getDiagnosticString(),
8153 HasSubstr("OpenCL.std remquo: "
8154 "expected type of operand Y to be equal to Result Type"));
8155 }
8156
8157 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
8158 const std::string body = R"(
8159 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
8160 )";
8161
8162 CompileSuccessfully(GenerateKernelCode(body));
8163 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8164 EXPECT_THAT(getDiagnosticString(),
8165 HasSubstr("OpenCL.std remquo: "
8166 "expected the last operand to be a pointer"));
8167 }
8168
8169 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
8170 const std::string body = R"(
8171 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
8172 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
8173 )";
8174
8175 CompileSuccessfully(GenerateKernelCode(body));
8176 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8177 EXPECT_THAT(getDiagnosticString(),
8178 HasSubstr("OpenCL.std remquo: "
8179 "expected storage class of the pointer to be Generic, "
8180 "CrossWorkgroup, Workgroup or Function"));
8181 }
8182
8183 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
8184 const std::string body = R"(
8185 %var_f32 = OpVariable %f32_ptr_function Function
8186 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
8187 )";
8188
8189 CompileSuccessfully(GenerateKernelCode(body));
8190 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8191 EXPECT_THAT(getDiagnosticString(),
8192 HasSubstr("OpenCL.std remquo: "
8193 "expected data type of the pointer to be a 32-bit int "
8194 "scalar or vector type"));
8195 }
8196
8197 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
8198 const std::string body = R"(
8199 %var_u64 = OpVariable %u64_ptr_function Function
8200 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
8201 )";
8202 CompileSuccessfully(GenerateKernelCode(body));
8203 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8204 EXPECT_THAT(getDiagnosticString(),
8205 HasSubstr("OpenCL.std remquo: "
8206 "expected data type of the pointer to be a 32-bit int "
8207 "scalar or vector type"));
8208 }
8209
8210 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
8211 const std::string body = R"(
8212 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8213 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
8214 )";
8215
8216 CompileSuccessfully(GenerateKernelCode(body));
8217 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8218 EXPECT_THAT(
8219 getDiagnosticString(),
8220 HasSubstr("OpenCL.std remquo: "
8221 "expected data type of the pointer to have the same number "
8222 "of components as Result Type"));
8223 }
8224
8225 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
8226 const std::string ext_inst_name = GetParam();
8227 std::ostringstream ss;
8228 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8229 ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
8230 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8231 << " %f32_0 %var_u32\n";
8232 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8233 << " %f32vec2_01 %var_u32vec2\n";
8234
8235 CompileSuccessfully(GenerateKernelCode(ss.str()));
8236 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8237 }
8238
8239 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
8240 const std::string ext_inst_name = GetParam();
8241 std::ostringstream ss;
8242 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8243 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8244 << " %f32_0 %var_u32\n";
8245
8246 CompileSuccessfully(GenerateKernelCode(ss.str()));
8247 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8248 EXPECT_THAT(
8249 getDiagnosticString(),
8250 HasSubstr("OpenCL.std " + ext_inst_name +
8251 ": expected Result Type to be a float scalar or vector type"));
8252 }
8253
8254 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
8255 const std::string ext_inst_name = GetParam();
8256 std::ostringstream ss;
8257 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8258 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8259 << " %f64_0 %var_u32\n";
8260
8261 CompileSuccessfully(GenerateKernelCode(ss.str()));
8262 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8263 EXPECT_THAT(
8264 getDiagnosticString(),
8265 HasSubstr("OpenCL.std " + ext_inst_name +
8266 ": expected type of operand X to be equal to Result Type"));
8267 }
8268
8269 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
8270 const std::string ext_inst_name = GetParam();
8271 std::ostringstream ss;
8272 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8273 << " %f32_0 %u32_1\n";
8274
8275 CompileSuccessfully(GenerateKernelCode(ss.str()));
8276 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8277 EXPECT_THAT(getDiagnosticString(),
8278 HasSubstr("OpenCL.std " + ext_inst_name +
8279 ": expected the last operand to be a pointer"));
8280 }
8281
8282 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
8283 const std::string ext_inst_name = GetParam();
8284 std::ostringstream ss;
8285 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8286 "%f32vec8_uniform_constant %u32_1\n";
8287 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8288
8289 CompileSuccessfully(GenerateKernelCode(ss.str()));
8290 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8291 EXPECT_THAT(getDiagnosticString(),
8292 HasSubstr("OpenCL.std " + ext_inst_name +
8293 ": expected storage class of the pointer to be "
8294 "Generic, CrossWorkgroup, Workgroup or Function"));
8295 }
8296
8297 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
8298 const std::string ext_inst_name = GetParam();
8299 std::ostringstream ss;
8300 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8301 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8302 << " %f32_0 %var_f32\n";
8303
8304 CompileSuccessfully(GenerateKernelCode(ss.str()));
8305 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8306 EXPECT_THAT(getDiagnosticString(),
8307 HasSubstr("OpenCL.std " + ext_inst_name +
8308 ": expected data type of the pointer to be a 32-bit "
8309 "int scalar or vector type"));
8310 }
8311
8312 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
8313 const std::string ext_inst_name = GetParam();
8314 std::ostringstream ss;
8315 ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
8316 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8317 << " %f32_0 %var_u64\n";
8318
8319 CompileSuccessfully(GenerateKernelCode(ss.str()));
8320 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8321 EXPECT_THAT(getDiagnosticString(),
8322 HasSubstr("OpenCL.std " + ext_inst_name +
8323 ": expected data type of the pointer to be a 32-bit "
8324 "int scalar or vector type"));
8325 }
8326
8327 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
8328 const std::string ext_inst_name = GetParam();
8329 std::ostringstream ss;
8330 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8331 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8332 << " %f32vec2_01 %var_u32\n";
8333
8334 CompileSuccessfully(GenerateKernelCode(ss.str()));
8335 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8336 EXPECT_THAT(getDiagnosticString(),
8337 HasSubstr("OpenCL.std " + ext_inst_name +
8338 ": expected data type of the pointer to have the same "
8339 "number of components as Result Type"));
8340 }
8341
8342 INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
8343 ::testing::ValuesIn(std::vector<std::string>{
8344 "frexp",
8345 "lgamma_r",
8346 }));
8347
8348 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
8349 const std::string body = R"(
8350 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
8351 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
8352 )";
8353
8354 CompileSuccessfully(GenerateKernelCode(body));
8355 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8356 }
8357
8358 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
8359 const std::string body = R"(
8360 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
8361 )";
8362
8363 CompileSuccessfully(GenerateKernelCode(body));
8364 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8365 EXPECT_THAT(
8366 getDiagnosticString(),
8367 HasSubstr(
8368 "OpenCL.std ilogb: "
8369 "expected Result Type to be a 32-bit int scalar or vector type"));
8370 }
8371
8372 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
8373 const std::string body = R"(
8374 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
8375 )";
8376
8377 CompileSuccessfully(GenerateKernelCode(body));
8378 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8379 EXPECT_THAT(getDiagnosticString(),
8380 HasSubstr("OpenCL.std ilogb: "
8381 "expected operand X to be a float scalar or vector"));
8382 }
8383
8384 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
8385 const std::string body = R"(
8386 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
8387 )";
8388
8389 CompileSuccessfully(GenerateKernelCode(body));
8390 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8391 EXPECT_THAT(getDiagnosticString(),
8392 HasSubstr("OpenCL.std ilogb: "
8393 "expected operand X to have the same number of "
8394 "components as Result Type"));
8395 }
8396
8397 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
8398 const std::string body = R"(
8399 %val1 = OpExtInst %f32 %extinst nan %u32_3
8400 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
8401 )";
8402
8403 CompileSuccessfully(GenerateKernelCode(body));
8404 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8405 }
8406
8407 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
8408 const std::string body = R"(
8409 %val1 = OpExtInst %u32 %extinst nan %u32_3
8410 )";
8411
8412 CompileSuccessfully(GenerateKernelCode(body));
8413 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8414 EXPECT_THAT(
8415 getDiagnosticString(),
8416 HasSubstr("OpenCL.std nan: "
8417 "expected Result Type to be a float scalar or vector type"));
8418 }
8419
8420 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
8421 const std::string body = R"(
8422 %val1 = OpExtInst %f32 %extinst nan %f32_3
8423 )";
8424
8425 CompileSuccessfully(GenerateKernelCode(body));
8426 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8427 EXPECT_THAT(getDiagnosticString(),
8428 HasSubstr("OpenCL.std nan: "
8429 "expected Nancode to be an int scalar or vector type"));
8430 }
8431
8432 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
8433 const std::string body = R"(
8434 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
8435 )";
8436
8437 CompileSuccessfully(GenerateKernelCode(body));
8438 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8439 EXPECT_THAT(getDiagnosticString(),
8440 HasSubstr("OpenCL.std nan: "
8441 "expected Nancode to have the same number of "
8442 "components as Result Type"));
8443 }
8444
8445 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
8446 const std::string body = R"(
8447 %val1 = OpExtInst %f64 %extinst nan %u32_2
8448 )";
8449
8450 CompileSuccessfully(GenerateKernelCode(body));
8451 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8452 EXPECT_THAT(
8453 getDiagnosticString(),
8454 HasSubstr("OpenCL.std nan: "
8455 "expected Nancode to have the same bit width as Result Type"));
8456 }
8457
8458 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
8459 const std::string ext_inst_name = GetParam();
8460 std::ostringstream ss;
8461 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8462 << " %f32_0 %u32_1\n";
8463 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8464 << " %f32vec2_12 %u32vec2_12\n";
8465
8466 CompileSuccessfully(GenerateKernelCode(ss.str()));
8467 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8468 }
8469
8470 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
8471 const std::string ext_inst_name = GetParam();
8472 std::ostringstream ss;
8473 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8474 << " %f32_0 %u32_1\n";
8475
8476 CompileSuccessfully(GenerateKernelCode(ss.str()));
8477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8478 EXPECT_THAT(
8479 getDiagnosticString(),
8480 HasSubstr("OpenCL.std " + ext_inst_name +
8481 ": expected Result Type to be a float scalar or vector type"));
8482 }
8483
8484 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
8485 const std::string ext_inst_name = GetParam();
8486 std::ostringstream ss;
8487 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8488 << " %u32_0 %u32_1\n";
8489
8490 CompileSuccessfully(GenerateKernelCode(ss.str()));
8491 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8492 EXPECT_THAT(
8493 getDiagnosticString(),
8494 HasSubstr("OpenCL.std " + ext_inst_name +
8495 ": expected type of operand X to be equal to Result Type"));
8496 }
8497
8498 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
8499 const std::string ext_inst_name = GetParam();
8500 std::ostringstream ss;
8501 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8502 << " %f32_0 %f32_1\n";
8503
8504 CompileSuccessfully(GenerateKernelCode(ss.str()));
8505 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8506 EXPECT_THAT(
8507 getDiagnosticString(),
8508 HasSubstr("OpenCL.std " + ext_inst_name +
8509 ": expected the exponent to be a 32-bit int scalar or vector"));
8510 }
8511
8512 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
8513 const std::string ext_inst_name = GetParam();
8514 std::ostringstream ss;
8515 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8516 << " %f32_0 %u64_1\n";
8517
8518 CompileSuccessfully(GenerateKernelCode(ss.str()));
8519 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8520 EXPECT_THAT(
8521 getDiagnosticString(),
8522 HasSubstr("OpenCL.std " + ext_inst_name +
8523 ": expected the exponent to be a 32-bit int scalar or vector"));
8524 }
8525
8526 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
8527 const std::string ext_inst_name = GetParam();
8528 std::ostringstream ss;
8529 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8530 << " %f32_0 %u32vec2_01\n";
8531
8532 CompileSuccessfully(GenerateKernelCode(ss.str()));
8533 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8534 EXPECT_THAT(getDiagnosticString(),
8535 HasSubstr("OpenCL.std " + ext_inst_name +
8536 ": expected the exponent to have the same number of "
8537 "components as Result Type"));
8538 }
8539
8540 INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
8541 ::testing::ValuesIn(std::vector<std::string>{
8542 "ldexp",
8543 "pown",
8544 "rootn",
8545 }));
8546
8547 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
8548 const std::string ext_inst_name = GetParam();
8549 std::ostringstream ss;
8550 ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8551 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
8552 << " %u16_1 %u16_2\n";
8553 ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
8554 << " %u32_1 %u32_2\n";
8555 ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8556 << " %u32vec2_01 %u32vec2_01\n";
8557
8558 CompileSuccessfully(GenerateKernelCode(ss.str()));
8559 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8560 }
8561
8562 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
8563 const std::string ext_inst_name = GetParam();
8564 std::ostringstream ss;
8565 ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
8566 << " %u32_1 %u32_2\n";
8567
8568 CompileSuccessfully(GenerateKernelCode(ss.str()));
8569 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8570 EXPECT_THAT(
8571 getDiagnosticString(),
8572 HasSubstr("OpenCL.std " + ext_inst_name +
8573 ": expected Result Type to be an int scalar or vector type"));
8574 }
8575
8576 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
8577 const std::string ext_inst_name = GetParam();
8578 std::ostringstream ss;
8579 ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8580
8581 CompileSuccessfully(GenerateKernelCode(ss.str()));
8582 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8583 EXPECT_THAT(
8584 getDiagnosticString(),
8585 HasSubstr(
8586 "OpenCL.std " + ext_inst_name +
8587 ": expected bit width of Result Type components to be 16, 32 or 64"));
8588 }
8589
8590 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
8591 const std::string ext_inst_name = GetParam();
8592 std::ostringstream ss;
8593 ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8594 << " %u32_1 %u16_2\n";
8595
8596 CompileSuccessfully(GenerateKernelCode(ss.str()));
8597 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8598 EXPECT_THAT(getDiagnosticString(),
8599 HasSubstr("OpenCL.std " + ext_inst_name +
8600 ": expected Hi and Lo operands to have the same type"));
8601 }
8602
8603 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
8604 const std::string ext_inst_name = GetParam();
8605 std::ostringstream ss;
8606 ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8607 << " %u32_1 %u32_2\n";
8608
8609 CompileSuccessfully(GenerateKernelCode(ss.str()));
8610 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8611 EXPECT_THAT(getDiagnosticString(),
8612 HasSubstr("OpenCL.std " + ext_inst_name +
8613 ": expected Hi and Lo operands to have the same number "
8614 "of components as Result Type"));
8615 }
8616
8617 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
8618 const std::string ext_inst_name = GetParam();
8619 std::ostringstream ss;
8620 ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8621 << " %u16_1 %u16_2\n";
8622
8623 CompileSuccessfully(GenerateKernelCode(ss.str()));
8624 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8625 EXPECT_THAT(
8626 getDiagnosticString(),
8627 HasSubstr("OpenCL.std " + ext_inst_name +
8628 ": expected bit width of components of Hi and Lo operands to "
8629 "be half of the bit width of components of Result Type"));
8630 }
8631
8632 INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
8633 ::testing::ValuesIn(std::vector<std::string>{
8634 "u_upsample",
8635 "s_upsample",
8636 }));
8637
8638 TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) {
8639 const std::string text = R"(
8640 OpCapability Shader
8641 OpCapability Linkage
8642 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
8643 OpMemoryModel Logical GLSL450
8644 )";
8645
8646 CompileSuccessfully(text);
8647 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8648 EXPECT_THAT(getDiagnosticString(),
8649 HasSubstr("NonSemantic extended instruction sets cannot be "
8650 "declared without SPV_KHR_non_semantic_info"));
8651 }
8652
8653 TEST_F(ValidateClspvReflection, MissingVersion) {
8654 const std::string text = R"(
8655 OpCapability Shader
8656 OpCapability Linkage
8657 OpExtension "SPV_KHR_non_semantic_info"
8658 %1 = OpExtInstImport "NonSemantic.ClspvReflection."
8659 OpMemoryModel Logical GLSL450
8660 %2 = OpTypeVoid
8661 %3 = OpTypeInt 32 0
8662 %4 = OpConstant %3 1
8663 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8664 )";
8665
8666 CompileSuccessfully(text);
8667 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8668 EXPECT_THAT(getDiagnosticString(),
8669 HasSubstr("Missing NonSemantic.ClspvReflection import version"));
8670 }
8671
8672 TEST_F(ValidateClspvReflection, BadVersion0) {
8673 const std::string text = R"(
8674 OpCapability Shader
8675 OpCapability Linkage
8676 OpExtension "SPV_KHR_non_semantic_info"
8677 %1 = OpExtInstImport "NonSemantic.ClspvReflection.0"
8678 OpMemoryModel Logical GLSL450
8679 %2 = OpTypeVoid
8680 %3 = OpTypeInt 32 0
8681 %4 = OpConstant %3 1
8682 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8683 )";
8684
8685 CompileSuccessfully(text);
8686 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8687 EXPECT_THAT(getDiagnosticString(),
8688 HasSubstr("Unknown NonSemantic.ClspvReflection import version"));
8689 }
8690
8691 TEST_F(ValidateClspvReflection, BadVersionNotANumber) {
8692 const std::string text = R"(
8693 OpCapability Shader
8694 OpCapability Linkage
8695 OpExtension "SPV_KHR_non_semantic_info"
8696 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a"
8697 OpMemoryModel Logical GLSL450
8698 %2 = OpTypeVoid
8699 %3 = OpTypeInt 32 0
8700 %4 = OpConstant %3 1
8701 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8702 )";
8703
8704 CompileSuccessfully(text);
8705 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8706 EXPECT_THAT(getDiagnosticString(),
8707 HasSubstr("NonSemantic.ClspvReflection import does not encode "
8708 "the version correctly"));
8709 }
8710
8711 TEST_F(ValidateClspvReflection, Kernel) {
8712 const std::string text = R"(
8713 OpCapability Shader
8714 OpExtension "SPV_KHR_non_semantic_info"
8715 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8716 OpMemoryModel Logical GLSL450
8717 OpEntryPoint GLCompute %foo "foo"
8718 OpExecutionMode %foo LocalSize 1 1 1
8719 %foo_name = OpString "foo"
8720 %void = OpTypeVoid
8721 %void_fn = OpTypeFunction %void
8722 %foo = OpFunction %void None %void_fn
8723 %entry = OpLabel
8724 OpReturn
8725 OpFunctionEnd
8726 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8727 )";
8728
8729 CompileSuccessfully(text);
8730 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8731 }
8732
8733 TEST_F(ValidateClspvReflection, KernelNotAFunction) {
8734 const std::string text = R"(
8735 OpCapability Shader
8736 OpExtension "SPV_KHR_non_semantic_info"
8737 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8738 OpMemoryModel Logical GLSL450
8739 OpEntryPoint GLCompute %foo "foo"
8740 OpExecutionMode %foo LocalSize 1 1 1
8741 %foo_name = OpString "foo"
8742 %void = OpTypeVoid
8743 %void_fn = OpTypeFunction %void
8744 %foo = OpFunction %void None %void_fn
8745 %entry = OpLabel
8746 OpReturn
8747 OpFunctionEnd
8748 %decl = OpExtInst %void %ext Kernel %foo_name %foo_name
8749 )";
8750
8751 CompileSuccessfully(text);
8752 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8753 EXPECT_THAT(getDiagnosticString(),
8754 HasSubstr("Kernel does not reference a function"));
8755 }
8756
8757 TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) {
8758 const std::string text = R"(
8759 OpCapability Shader
8760 OpExtension "SPV_KHR_non_semantic_info"
8761 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8762 OpMemoryModel Logical GLSL450
8763 OpEntryPoint GLCompute %foo "foo"
8764 OpExecutionMode %foo LocalSize 1 1 1
8765 %foo_name = OpString "foo"
8766 %void = OpTypeVoid
8767 %void_fn = OpTypeFunction %void
8768 %foo = OpFunction %void None %void_fn
8769 %entry = OpLabel
8770 OpReturn
8771 OpFunctionEnd
8772 %bar = OpFunction %void None %void_fn
8773 %bar_entry = OpLabel
8774 OpReturn
8775 OpFunctionEnd
8776 %decl = OpExtInst %void %ext Kernel %bar %foo_name
8777 )";
8778
8779 CompileSuccessfully(text);
8780 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8781 EXPECT_THAT(getDiagnosticString(),
8782 HasSubstr("Kernel does not reference an entry-point"));
8783 }
8784
8785 TEST_F(ValidateClspvReflection, KernelNotGLCompute) {
8786 const std::string text = R"(
8787 OpCapability Shader
8788 OpExtension "SPV_KHR_non_semantic_info"
8789 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8790 OpMemoryModel Logical GLSL450
8791 OpEntryPoint Fragment %foo "foo"
8792 OpExecutionMode %foo OriginUpperLeft
8793 %foo_name = OpString "foo"
8794 %void = OpTypeVoid
8795 %void_fn = OpTypeFunction %void
8796 %foo = OpFunction %void None %void_fn
8797 %entry = OpLabel
8798 OpReturn
8799 OpFunctionEnd
8800 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8801 )";
8802
8803 CompileSuccessfully(text);
8804 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8805 EXPECT_THAT(getDiagnosticString(),
8806 HasSubstr("Kernel must refer only to GLCompute entry-points"));
8807 }
8808
8809 TEST_F(ValidateClspvReflection, KernelNameMismatch) {
8810 const std::string text = R"(
8811 OpCapability Shader
8812 OpExtension "SPV_KHR_non_semantic_info"
8813 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8814 OpMemoryModel Logical GLSL450
8815 OpEntryPoint GLCompute %foo "foo"
8816 OpExecutionMode %foo LocalSize 1 1 1
8817 %foo_name = OpString "bar"
8818 %void = OpTypeVoid
8819 %void_fn = OpTypeFunction %void
8820 %foo = OpFunction %void None %void_fn
8821 %entry = OpLabel
8822 OpReturn
8823 OpFunctionEnd
8824 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8825 )";
8826
8827 CompileSuccessfully(text);
8828 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8829 EXPECT_THAT(getDiagnosticString(),
8830 HasSubstr("Name must match an entry-point for Kernel"));
8831 }
8832
8833 using ArgumentBasics =
8834 spvtest::ValidateBase<std::pair<std::string, std::string>>;
8835
8836 INSTANTIATE_TEST_SUITE_P(
8837 ValidateClspvReflectionArgumentKernel, ArgumentBasics,
8838 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
8839 std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"),
8840 std::make_pair("ArgumentUniform", "%int_0 %int_0"),
8841 std::make_pair("ArgumentPodStorageBuffer",
8842 "%int_0 %int_0 %int_0 %int_4"),
8843 std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"),
8844 std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"),
8845 std::make_pair("ArgumentSampledImage", "%int_0 %int_0"),
8846 std::make_pair("ArgumentStorageImage", "%int_0 %int_0"),
8847 std::make_pair("ArgumentSampler", "%int_0 %int_0"),
8848 std::make_pair("ArgumentWorkgroup", "%int_0 %int_0")}));
8849
8850 TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) {
8851 const std::string ext_inst = std::get<0>(GetParam());
8852 const std::string extra = std::get<1>(GetParam());
8853 const std::string text = R"(
8854 OpCapability Shader
8855 OpExtension "SPV_KHR_non_semantic_info"
8856 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8857 OpMemoryModel Logical GLSL450
8858 OpEntryPoint GLCompute %foo "foo"
8859 OpExecutionMode %foo LocalSize 1 1 1
8860 %foo_name = OpString "foo"
8861 %void = OpTypeVoid
8862 %int = OpTypeInt 32 0
8863 %int_0 = OpConstant %int 0
8864 %int_4 = OpConstant %int 4
8865 %void_fn = OpTypeFunction %void
8866 %foo = OpFunction %void None %void_fn
8867 %entry = OpLabel
8868 OpReturn
8869 OpFunctionEnd
8870 %in = OpExtInst %void %ext )" +
8871 ext_inst + " %int_0 %int_0 " + extra;
8872
8873 CompileSuccessfully(text);
8874 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8875 EXPECT_THAT(getDiagnosticString(),
8876 HasSubstr("Kernel must be a Kernel extended instruction"));
8877 }
8878
8879 TEST_P(ArgumentBasics, KernelFromDifferentImport) {
8880 const std::string ext_inst = std::get<0>(GetParam());
8881 const std::string extra = std::get<1>(GetParam());
8882 const std::string text = R"(
8883 OpCapability Shader
8884 OpExtension "SPV_KHR_non_semantic_info"
8885 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8886 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
8887 OpMemoryModel Logical GLSL450
8888 OpEntryPoint GLCompute %foo "foo"
8889 OpExecutionMode %foo LocalSize 1 1 1
8890 %foo_name = OpString "foo"
8891 %void = OpTypeVoid
8892 %int = OpTypeInt 32 0
8893 %int_0 = OpConstant %int 0
8894 %int_4 = OpConstant %int 4
8895 %void_fn = OpTypeFunction %void
8896 %foo = OpFunction %void None %void_fn
8897 %entry = OpLabel
8898 OpReturn
8899 OpFunctionEnd
8900 %decl = OpExtInst %void %ext2 Kernel %foo %foo_name
8901 %in = OpExtInst %void %ext )" +
8902 ext_inst + " %decl %int_0 " + extra;
8903
8904 CompileSuccessfully(text);
8905 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8906 EXPECT_THAT(
8907 getDiagnosticString(),
8908 HasSubstr("Kernel must be from the same extended instruction import"));
8909 }
8910
8911 TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) {
8912 const std::string ext_inst = std::get<0>(GetParam());
8913 const std::string extra = std::get<1>(GetParam());
8914 const std::string text = R"(
8915 OpCapability Shader
8916 OpExtension "SPV_KHR_non_semantic_info"
8917 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8918 OpMemoryModel Logical GLSL450
8919 OpEntryPoint GLCompute %foo "foo"
8920 OpExecutionMode %foo LocalSize 1 1 1
8921 %foo_name = OpString "foo"
8922 %void = OpTypeVoid
8923 %int = OpTypeInt 32 0
8924 %int_0 = OpConstant %int 0
8925 %int_4 = OpConstant %int 4
8926 %void_fn = OpTypeFunction %void
8927 %foo = OpFunction %void None %void_fn
8928 %entry = OpLabel
8929 OpReturn
8930 OpFunctionEnd
8931 %decl = OpExtInst %void %ext ArgumentInfo %foo_name
8932 %in = OpExtInst %void %ext )" +
8933 ext_inst + " %decl %int_0 " + extra;
8934
8935 CompileSuccessfully(text);
8936 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8937 EXPECT_THAT(getDiagnosticString(),
8938 HasSubstr("Kernel must be a Kernel extended instruction"));
8939 }
8940
8941 TEST_P(ArgumentBasics, ArgumentInfo) {
8942 const std::string ext_inst = std::get<0>(GetParam());
8943 const std::string operands = std::get<1>(GetParam());
8944 const std::string text = R"(
8945 OpCapability Shader
8946 OpExtension "SPV_KHR_non_semantic_info"
8947 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8948 OpMemoryModel Logical GLSL450
8949 OpEntryPoint GLCompute %foo "foo"
8950 OpExecutionMode %foo LocalSize 1 1 1
8951 %foo_name = OpString "foo"
8952 %in_name = OpString "in"
8953 %void = OpTypeVoid
8954 %int = OpTypeInt 32 0
8955 %int_0 = OpConstant %int 0
8956 %int_4 = OpConstant %int 4
8957 %void_fn = OpTypeFunction %void
8958 %foo = OpFunction %void None %void_fn
8959 %entry = OpLabel
8960 OpReturn
8961 OpFunctionEnd
8962 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8963 %info = OpExtInst %void %ext ArgumentInfo %in_name
8964 %in = OpExtInst %void %ext )" +
8965 ext_inst + " %decl %int_0 " + operands + " %info";
8966
8967 CompileSuccessfully(text);
8968 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8969 }
8970
8971 TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) {
8972 const std::string ext_inst = std::get<0>(GetParam());
8973 const std::string operands = std::get<1>(GetParam());
8974 const std::string text = R"(
8975 OpCapability Shader
8976 OpExtension "SPV_KHR_non_semantic_info"
8977 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8978 OpMemoryModel Logical GLSL450
8979 OpEntryPoint GLCompute %foo "foo"
8980 OpExecutionMode %foo LocalSize 1 1 1
8981 %foo_name = OpString "foo"
8982 %void = OpTypeVoid
8983 %int = OpTypeInt 32 0
8984 %int_0 = OpConstant %int 0
8985 %int_4 = OpConstant %int 4
8986 %void_fn = OpTypeFunction %void
8987 %foo = OpFunction %void None %void_fn
8988 %entry = OpLabel
8989 OpReturn
8990 OpFunctionEnd
8991 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8992 %in = OpExtInst %void %ext )" +
8993 ext_inst + " %decl %int_0 " + operands + " %int_0";
8994
8995 CompileSuccessfully(text);
8996 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8997 EXPECT_THAT(
8998 getDiagnosticString(),
8999 HasSubstr("ArgInfo must be an ArgumentInfo extended instruction"));
9000 }
9001
9002 TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) {
9003 const std::string ext_inst = std::get<0>(GetParam());
9004 const std::string operands = std::get<1>(GetParam());
9005 const std::string text = R"(
9006 OpCapability Shader
9007 OpExtension "SPV_KHR_non_semantic_info"
9008 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9009 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
9010 OpMemoryModel Logical GLSL450
9011 OpEntryPoint GLCompute %foo "foo"
9012 OpExecutionMode %foo LocalSize 1 1 1
9013 %foo_name = OpString "foo"
9014 %in_name = OpString "in"
9015 %void = OpTypeVoid
9016 %int = OpTypeInt 32 0
9017 %int_0 = OpConstant %int 0
9018 %int_4 = OpConstant %int 4
9019 %void_fn = OpTypeFunction %void
9020 %foo = OpFunction %void None %void_fn
9021 %entry = OpLabel
9022 OpReturn
9023 OpFunctionEnd
9024 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9025 %info = OpExtInst %void %ext2 ArgumentInfo %in_name
9026 %in = OpExtInst %void %ext )" +
9027 ext_inst + " %decl %int_0 " + operands + " %info";
9028
9029 CompileSuccessfully(text);
9030 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9031 EXPECT_THAT(
9032 getDiagnosticString(),
9033 HasSubstr("ArgInfo must be from the same extended instruction import"));
9034 }
9035
9036 using Uint32Constant =
9037 spvtest::ValidateBase<std::pair<std::string, std::string>>;
9038
9039 INSTANTIATE_TEST_SUITE_P(
9040 ValidateClspvReflectionUint32Constants, Uint32Constant,
9041 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9042 std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0",
9043 "Ordinal"),
9044 std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0",
9045 "Ordinal"),
9046 std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0",
9047 "DescriptorSet"),
9048 std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0",
9049 "DescriptorSet"),
9050 std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0",
9051 "Binding"),
9052 std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null",
9053 "Binding"),
9054 std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0",
9055 "Ordinal"),
9056 std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"),
9057 std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0",
9058 "DescriptorSet"),
9059 std::make_pair("ArgumentUniform %decl %int_0 %null %int_0",
9060 "DescriptorSet"),
9061 std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0",
9062 "Binding"),
9063 std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"),
9064 std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0",
9065 "Ordinal"),
9066 std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0",
9067 "Ordinal"),
9068 std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0",
9069 "DescriptorSet"),
9070 std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0",
9071 "DescriptorSet"),
9072 std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0",
9073 "Binding"),
9074 std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null",
9075 "Binding"),
9076 std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0",
9077 "Ordinal"),
9078 std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0",
9079 "Ordinal"),
9080 std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0",
9081 "DescriptorSet"),
9082 std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0",
9083 "DescriptorSet"),
9084 std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0",
9085 "Binding"),
9086 std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null",
9087 "Binding"),
9088 std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0",
9089 "Ordinal"),
9090 std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"),
9091 std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0",
9092 "DescriptorSet"),
9093 std::make_pair("ArgumentSampler %decl %int_0 %null %int_0",
9094 "DescriptorSet"),
9095 std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0",
9096 "Binding"),
9097 std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"),
9098 std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 "
9099 "%int_0 %int_4",
9100 "Ordinal"),
9101 std::make_pair(
9102 "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4",
9103 "Ordinal"),
9104 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 "
9105 "%int_0 %int_4",
9106 "DescriptorSet"),
9107 std::make_pair(
9108 "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4",
9109 "DescriptorSet"),
9110 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 "
9111 "%int_0 %int_4",
9112 "Binding"),
9113 std::make_pair(
9114 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4",
9115 "Binding"),
9116 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9117 "%float_0 %int_4",
9118 "Offset"),
9119 std::make_pair(
9120 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4",
9121 "Offset"),
9122 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9123 "%int_0 %float_0",
9124 "Size"),
9125 std::make_pair(
9126 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null",
9127 "Size"),
9128 std::make_pair(
9129 "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
9130 "Ordinal"),
9131 std::make_pair(
9132 "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4",
9133 "Ordinal"),
9134 std::make_pair(
9135 "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
9136 "DescriptorSet"),
9137 std::make_pair(
9138 "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4",
9139 "DescriptorSet"),
9140 std::make_pair(
9141 "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
9142 "Binding"),
9143 std::make_pair(
9144 "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4",
9145 "Binding"),
9146 std::make_pair(
9147 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
9148 "Offset"),
9149 std::make_pair(
9150 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4",
9151 "Offset"),
9152 std::make_pair(
9153 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
9154 "Size"),
9155 std::make_pair(
9156 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
9157 "Size"),
9158 std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4",
9159 "Ordinal"),
9160 std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4",
9161 "Ordinal"),
9162 std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4",
9163 "Offset"),
9164 std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4",
9165 "Offset"),
9166 std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0",
9167 "Size"),
9168 std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null",
9169 "Size"),
9170 std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4",
9171 "Ordinal"),
9172 std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4",
9173 "Ordinal"),
9174 std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4",
9175 "SpecId"),
9176 std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"),
9177 std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0",
9178 "ElemSize"),
9179 std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null",
9180 "ElemSize"),
9181 std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"),
9182 std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"),
9183 std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"),
9184 std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"),
9185 std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"),
9186 std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"),
9187 std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"),
9188 std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"),
9189 std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"),
9190 std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"),
9191 std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"),
9192 std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"),
9193 std::make_pair("SpecConstantWorkDim %float_0", "Dim"),
9194 std::make_pair("SpecConstantWorkDim %null", "Dim"),
9195 std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"),
9196 std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"),
9197 std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"),
9198 std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"),
9199 std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0",
9200 "Offset"),
9201 std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"),
9202 std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"),
9203 std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"),
9204 std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"),
9205 std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"),
9206 std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"),
9207 std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"),
9208 std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"),
9209 std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"),
9210 std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"),
9211 std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"),
9212 std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"),
9213 std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"),
9214 std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"),
9215 std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"),
9216 std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0",
9217 "Offset"),
9218 std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"),
9219 std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"),
9220 std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"),
9221 std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data",
9222 "DescriptorSet"),
9223 std::make_pair("ConstantDataStorageBuffer %null %int_0 %data",
9224 "DescriptorSet"),
9225 std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data",
9226 "Binding"),
9227 std::make_pair("ConstantDataStorageBuffer %int_0 %null %data",
9228 "Binding"),
9229 std::make_pair("ConstantDataUniform %float_0 %int_0 %data",
9230 "DescriptorSet"),
9231 std::make_pair("ConstantDataUniform %null %int_0 %data",
9232 "DescriptorSet"),
9233 std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"),
9234 std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"),
9235 std::make_pair("LiteralSampler %float_0 %int_0 %int_4",
9236 "DescriptorSet"),
9237 std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"),
9238 std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"),
9239 std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"),
9240 std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"),
9241 std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"),
9242 std::make_pair(
9243 "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"),
9244 std::make_pair(
9245 "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"),
9246 std::make_pair(
9247 "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"),
9248 std::make_pair(
9249 "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"),
9250 std::make_pair(
9251 "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"),
9252 std::make_pair(
9253 "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z")}));
9254
9255 TEST_P(Uint32Constant, Invalid) {
9256 const std::string ext_inst = std::get<0>(GetParam());
9257 const std::string name = std::get<1>(GetParam());
9258 const std::string text = R"(
9259 OpCapability Shader
9260 OpExtension "SPV_KHR_non_semantic_info"
9261 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9262 OpMemoryModel Logical GLSL450
9263 OpEntryPoint GLCompute %foo "foo"
9264 OpExecutionMode %foo LocalSize 1 1 1
9265 %foo_name = OpString "foo"
9266 %data = OpString "1234"
9267 %void = OpTypeVoid
9268 %int = OpTypeInt 32 0
9269 %int_0 = OpConstant %int 0
9270 %int_1 = OpConstant %int 1
9271 %int_4 = OpConstant %int 4
9272 %null = OpConstantNull %int
9273 %float = OpTypeFloat 32
9274 %float_0 = OpConstant %float 0
9275 %void_fn = OpTypeFunction %void
9276 %foo = OpFunction %void None %void_fn
9277 %entry = OpLabel
9278 OpReturn
9279 OpFunctionEnd
9280 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9281 %inst = OpExtInst %void %ext )" +
9282 ext_inst;
9283
9284 CompileSuccessfully(text);
9285 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9286 EXPECT_THAT(
9287 getDiagnosticString(),
9288 HasSubstr(name + " must be a 32-bit unsigned integer OpConstant"));
9289 }
9290
9291 using StringOperand =
9292 spvtest::ValidateBase<std::pair<std::string, std::string>>;
9293
9294 INSTANTIATE_TEST_SUITE_P(
9295 ValidateClspvReflectionStringOperands, StringOperand,
9296 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9297 std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0",
9298 "Data"),
9299 std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data")}));
9300
9301 TEST_P(StringOperand, Invalid) {
9302 const std::string ext_inst = std::get<0>(GetParam());
9303 const std::string name = std::get<1>(GetParam());
9304 const std::string text = R"(
9305 OpCapability Shader
9306 OpExtension "SPV_KHR_non_semantic_info"
9307 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9308 OpMemoryModel Logical GLSL450
9309 OpEntryPoint GLCompute %foo "foo"
9310 OpExecutionMode %foo LocalSize 1 1 1
9311 %foo_name = OpString "foo"
9312 %data = OpString "1234"
9313 %void = OpTypeVoid
9314 %int = OpTypeInt 32 0
9315 %int_0 = OpConstant %int 0
9316 %int_1 = OpConstant %int 1
9317 %int_4 = OpConstant %int 4
9318 %null = OpConstantNull %int
9319 %float = OpTypeFloat 32
9320 %float_0 = OpConstant %float 0
9321 %void_fn = OpTypeFunction %void
9322 %foo = OpFunction %void None %void_fn
9323 %entry = OpLabel
9324 OpReturn
9325 OpFunctionEnd
9326 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9327 %inst = OpExtInst %void %ext )" +
9328 ext_inst;
9329
9330 CompileSuccessfully(text);
9331 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9332 EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString"));
9333 }
9334
9335 } // namespace
9336 } // namespace val
9337 } // namespace spvtools
9338