1 // Copyright 2020 The Tint Authors.
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 #include "src/writer/spirv/spv_dump.h"
16 #include "src/writer/spirv/test_helper.h"
17
18 namespace tint {
19 namespace writer {
20 namespace spirv {
21 namespace {
22
23 using SpvBuilderConstructorTest = TestHelper;
24
TEST_F(SpvBuilderConstructorTest,Const)25 TEST_F(SpvBuilderConstructorTest, Const) {
26 auto* c = Expr(42.2f);
27 auto* g = Global("g", ty.f32(), c, ast::StorageClass::kPrivate);
28
29 spirv::Builder& b = Build();
30
31 EXPECT_EQ(b.GenerateConstructorExpression(g, c), 2u);
32 ASSERT_FALSE(b.has_error()) << b.error();
33
34 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
35 %2 = OpConstant %1 42.2000008
36 )");
37 }
38
TEST_F(SpvBuilderConstructorTest,Type_WithCasts_OutsideFunction_IsError)39 TEST_F(SpvBuilderConstructorTest, Type_WithCasts_OutsideFunction_IsError) {
40 auto* t = Construct<f32>(Construct<u32>(1));
41 WrapInFunction(t);
42
43 spirv::Builder& b = Build();
44
45 EXPECT_EQ(b.GenerateExpression(t), 0u);
46 EXPECT_TRUE(b.has_error()) << b.error();
47 EXPECT_EQ(b.error(),
48 "Internal error: trying to add SPIR-V instruction 124 outside a "
49 "function");
50 }
51
TEST_F(SpvBuilderConstructorTest,Type)52 TEST_F(SpvBuilderConstructorTest, Type) {
53 auto* t = vec3<f32>(1.0f, 1.0f, 3.0f);
54 WrapInFunction(t);
55
56 spirv::Builder& b = Build();
57
58 EXPECT_EQ(b.GenerateConstructorExpression(nullptr, t), 5u);
59 ASSERT_FALSE(b.has_error()) << b.error();
60
61 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
62 %1 = OpTypeVector %2 3
63 %3 = OpConstant %2 1
64 %4 = OpConstant %2 3
65 %5 = OpConstantComposite %1 %3 %3 %4
66 )");
67 }
68
TEST_F(SpvBuilderConstructorTest,Type_WithCasts)69 TEST_F(SpvBuilderConstructorTest, Type_WithCasts) {
70 auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(1));
71 WrapInFunction(t);
72
73 spirv::Builder& b = Build();
74
75 b.push_function(Function{});
76
77 EXPECT_EQ(b.GenerateExpression(t), 7u);
78 ASSERT_FALSE(b.has_error()) << b.error();
79
80 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
81 %1 = OpTypeVector %2 2
82 %4 = OpTypeInt 32 1
83 %5 = OpConstant %4 1
84 )");
85 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
86 R"(%3 = OpConvertSToF %2 %5
87 %6 = OpConvertSToF %2 %5
88 %7 = OpCompositeConstruct %1 %3 %6
89 )");
90 }
91
TEST_F(SpvBuilderConstructorTest,Type_WithAlias)92 TEST_F(SpvBuilderConstructorTest, Type_WithAlias) {
93 // type Int = i32
94 // cast<Int>(2.3f)
95
96 auto* alias = Alias("Int", ty.i32());
97 auto* cast = Construct(ty.Of(alias), 2.3f);
98 WrapInFunction(cast);
99
100 spirv::Builder& b = Build();
101
102 b.push_function(Function{});
103 EXPECT_EQ(b.GenerateExpression(cast), 1u);
104
105 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
106 %3 = OpTypeFloat 32
107 %4 = OpConstant %3 2.29999995
108 )");
109 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
110 R"(%1 = OpConvertFToS %2 %4
111 )");
112 }
113
TEST_F(SpvBuilderConstructorTest,Type_IdentifierExpression_Param)114 TEST_F(SpvBuilderConstructorTest, Type_IdentifierExpression_Param) {
115 auto* var = Var("ident", ty.f32());
116
117 auto* t = vec2<f32>(1.0f, "ident");
118 WrapInFunction(var, t);
119
120 spirv::Builder& b = Build();
121
122 b.push_function(Function{});
123 ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
124
125 EXPECT_EQ(b.GenerateExpression(t), 8u);
126 ASSERT_FALSE(b.has_error()) << b.error();
127
128 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
129 %2 = OpTypePointer Function %3
130 %4 = OpConstantNull %3
131 %5 = OpTypeVector %3 2
132 %6 = OpConstant %3 1
133 )");
134 EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
135 R"(%1 = OpVariable %2 Function %4
136 )");
137
138 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
139 R"(%7 = OpLoad %3 %1
140 %8 = OpCompositeConstruct %5 %6 %7
141 )");
142 }
143
TEST_F(SpvBuilderConstructorTest,Vector_Bitcast_Params)144 TEST_F(SpvBuilderConstructorTest, Vector_Bitcast_Params) {
145 auto* t = vec2<u32>(Construct<u32>(1), Construct<u32>(1));
146 WrapInFunction(t);
147
148 spirv::Builder& b = Build();
149
150 b.push_function(Function{});
151
152 EXPECT_EQ(b.GenerateExpression(t), 7u);
153 ASSERT_FALSE(b.has_error()) << b.error();
154
155 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
156 %1 = OpTypeVector %2 2
157 %4 = OpTypeInt 32 1
158 %5 = OpConstant %4 1
159 )");
160
161 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
162 R"(%3 = OpBitcast %2 %5
163 %6 = OpBitcast %2 %5
164 %7 = OpCompositeConstruct %1 %3 %6
165 )");
166 }
167
TEST_F(SpvBuilderConstructorTest,Type_Bool_With_Bool)168 TEST_F(SpvBuilderConstructorTest, Type_Bool_With_Bool) {
169 auto* cast = Construct<bool>(true);
170 WrapInFunction(cast);
171
172 spirv::Builder& b = Build();
173
174 b.push_function(Function{});
175
176 EXPECT_EQ(b.GenerateExpression(cast), 3u);
177 ASSERT_FALSE(b.has_error()) << b.error();
178
179 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
180 %3 = OpConstantTrue %2
181 )");
182 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
183 }
184
TEST_F(SpvBuilderConstructorTest,Type_I32_With_I32)185 TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
186 auto* cast = Construct<i32>(2);
187 WrapInFunction(cast);
188
189 spirv::Builder& b = Build();
190
191 b.push_function(Function{});
192 EXPECT_EQ(b.GenerateExpression(cast), 3u);
193
194 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
195 %3 = OpConstant %2 2
196 )");
197 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
198 }
199
TEST_F(SpvBuilderConstructorTest,Type_U32_With_U32)200 TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
201 auto* cast = Construct<u32>(2u);
202 WrapInFunction(cast);
203
204 spirv::Builder& b = Build();
205
206 b.push_function(Function{});
207 EXPECT_EQ(b.GenerateExpression(cast), 3u);
208
209 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
210 %3 = OpConstant %2 2
211 )");
212 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
213 }
214
TEST_F(SpvBuilderConstructorTest,Type_F32_With_F32)215 TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
216 auto* cast = Construct<f32>(2.0f);
217 WrapInFunction(cast);
218
219 spirv::Builder& b = Build();
220
221 b.push_function(Function{});
222 EXPECT_EQ(b.GenerateExpression(cast), 3u);
223
224 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
225 %3 = OpConstant %2 2
226 )");
227 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
228 }
229
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_Bool_Literal)230 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Literal) {
231 auto* cast = vec2<bool>(true);
232 WrapInFunction(cast);
233
234 spirv::Builder& b = Build();
235
236 b.push_function(Function{});
237 EXPECT_EQ(b.GenerateExpression(cast), 4u);
238
239 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
240 %1 = OpTypeVector %2 2
241 %3 = OpConstantTrue %2
242 %4 = OpConstantComposite %1 %3 %3
243 )");
244 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
245 }
246
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_Bool_Var)247 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Var) {
248 auto* var = Var("v", nullptr, Expr(true));
249 auto* cast = vec2<bool>(var);
250 WrapInFunction(var, cast);
251
252 spirv::Builder& b = Build();
253
254 b.push_function(Function{});
255 ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
256 ASSERT_EQ(b.GenerateExpression(cast), 8u) << b.error();
257
258 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
259 %2 = OpConstantTrue %1
260 %4 = OpTypePointer Function %1
261 %5 = OpConstantNull %1
262 %6 = OpTypeVector %1 2
263 )");
264 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
265 R"(OpStore %3 %2
266 %7 = OpLoad %1 %3
267 %8 = OpCompositeConstruct %6 %7 %7
268 )");
269 }
270
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_F32_Literal)271 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_Literal) {
272 auto* cast = vec2<f32>(2.0f);
273 WrapInFunction(cast);
274
275 spirv::Builder& b = Build();
276
277 b.push_function(Function{});
278 EXPECT_EQ(b.GenerateExpression(cast), 4u);
279
280 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
281 %1 = OpTypeVector %2 2
282 %3 = OpConstant %2 2
283 %4 = OpConstantComposite %1 %3 %3
284 )");
285 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
286 }
287
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_F32_Var)288 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_Var) {
289 auto* var = Var("v", nullptr, Expr(2.0f));
290 auto* cast = vec2<f32>(var);
291 WrapInFunction(var, cast);
292
293 spirv::Builder& b = Build();
294
295 b.push_function(Function{});
296 ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
297 ASSERT_EQ(b.GenerateExpression(cast), 8u) << b.error();
298
299 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
300 %2 = OpConstant %1 2
301 %4 = OpTypePointer Function %1
302 %5 = OpConstantNull %1
303 %6 = OpTypeVector %1 2
304 )");
305 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %3 %2
306 %7 = OpLoad %1 %3
307 %8 = OpCompositeConstruct %6 %7 %7
308 )");
309 }
310
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_F32_F32)311 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
312 auto* cast = vec2<f32>(2.0f, 2.0f);
313 WrapInFunction(cast);
314
315 spirv::Builder& b = Build();
316
317 b.push_function(Function{});
318 EXPECT_EQ(b.GenerateExpression(cast), 4u);
319
320 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
321 %1 = OpTypeVector %2 2
322 %3 = OpConstant %2 2
323 %4 = OpConstantComposite %1 %3 %3
324 )");
325 }
326
TEST_F(SpvBuilderConstructorTest,Type_Vec2_With_Vec2)327 TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Vec2) {
328 auto* value = vec2<f32>(2.0f, 2.0f);
329 auto* cast = vec2<f32>(value);
330 WrapInFunction(cast);
331
332 spirv::Builder& b = Build();
333
334 b.push_function(Function{});
335 EXPECT_EQ(b.GenerateExpression(cast), 5u);
336
337 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
338 %2 = OpTypeVector %3 2
339 %4 = OpConstant %3 2
340 %5 = OpConstantComposite %2 %4 %4
341 )");
342 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
343 }
344
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_F32)345 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32) {
346 auto* cast = vec3<f32>(2.0f);
347 WrapInFunction(cast);
348
349 spirv::Builder& b = Build();
350
351 b.push_function(Function{});
352 EXPECT_EQ(b.GenerateExpression(cast), 4u);
353
354 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
355 %1 = OpTypeVector %2 3
356 %3 = OpConstant %2 2
357 %4 = OpConstantComposite %1 %3 %3 %3
358 )");
359 }
360
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_Bool)361 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Bool) {
362 auto* cast = vec3<bool>(true);
363 WrapInFunction(cast);
364
365 spirv::Builder& b = Build();
366
367 b.push_function(Function{});
368 EXPECT_EQ(b.GenerateExpression(cast), 4u);
369
370 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
371 %1 = OpTypeVector %2 3
372 %3 = OpConstantTrue %2
373 %4 = OpConstantComposite %1 %3 %3 %3
374 )");
375 }
376
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_F32_F32_F32)377 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_F32_F32) {
378 auto* cast = vec3<f32>(2.0f, 2.0f, 2.0f);
379 WrapInFunction(cast);
380
381 spirv::Builder& b = Build();
382
383 b.push_function(Function{});
384 EXPECT_EQ(b.GenerateExpression(cast), 4u);
385
386 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
387 %1 = OpTypeVector %2 3
388 %3 = OpConstant %2 2
389 %4 = OpConstantComposite %1 %3 %3 %3
390 )");
391 }
392
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_F32_Vec2)393 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_Vec2) {
394 auto* cast = vec3<f32>(2.0f, vec2<f32>(2.0f, 2.0f));
395 WrapInFunction(cast);
396
397 spirv::Builder& b = Build();
398
399 b.push_function(Function{});
400 EXPECT_EQ(b.GenerateExpression(cast), 8u);
401
402 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
403 %1 = OpTypeVector %2 3
404 %3 = OpConstant %2 2
405 %4 = OpTypeVector %2 2
406 %5 = OpConstantComposite %4 %3 %3
407 )");
408 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
409 R"(%6 = OpCompositeExtract %2 %5 0
410 %7 = OpCompositeExtract %2 %5 1
411 %8 = OpCompositeConstruct %1 %3 %6 %7
412 )");
413 }
414
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_Vec2_F32)415 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F32) {
416 auto* cast = vec3<f32>(vec2<f32>(2.0f, 2.0f), 2.0f);
417 WrapInFunction(cast);
418
419 spirv::Builder& b = Build();
420
421 b.push_function(Function{});
422 EXPECT_EQ(b.GenerateExpression(cast), 8u);
423
424 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
425 %1 = OpTypeVector %2 3
426 %3 = OpTypeVector %2 2
427 %4 = OpConstant %2 2
428 %5 = OpConstantComposite %3 %4 %4
429 )");
430 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
431 R"(%6 = OpCompositeExtract %2 %5 0
432 %7 = OpCompositeExtract %2 %5 1
433 %8 = OpCompositeConstruct %1 %6 %7 %4
434 )");
435 }
436
TEST_F(SpvBuilderConstructorTest,Type_Vec3_With_Vec3)437 TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec3) {
438 auto* value = vec3<f32>(2.0f, 2.0f, 2.0f);
439 auto* cast = vec3<f32>(value);
440 WrapInFunction(cast);
441
442 spirv::Builder& b = Build();
443
444 b.push_function(Function{});
445 EXPECT_EQ(b.GenerateExpression(cast), 5u);
446
447 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
448 %2 = OpTypeVector %3 3
449 %4 = OpConstant %3 2
450 %5 = OpConstantComposite %2 %4 %4 %4
451 )");
452 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
453 }
454
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_Bool)455 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Bool) {
456 auto* cast = vec4<bool>(true);
457 WrapInFunction(cast);
458
459 spirv::Builder& b = Build();
460
461 b.push_function(Function{});
462 EXPECT_EQ(b.GenerateExpression(cast), 4u);
463
464 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
465 %1 = OpTypeVector %2 4
466 %3 = OpConstantTrue %2
467 %4 = OpConstantComposite %1 %3 %3 %3 %3
468 )");
469 }
470
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_F32)471 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32) {
472 auto* cast = vec4<f32>(2.0f);
473 WrapInFunction(cast);
474
475 spirv::Builder& b = Build();
476
477 b.push_function(Function{});
478 EXPECT_EQ(b.GenerateExpression(cast), 4u);
479
480 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
481 %1 = OpTypeVector %2 4
482 %3 = OpConstant %2 2
483 %4 = OpConstantComposite %1 %3 %3 %3 %3
484 )");
485 }
486
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_F32_F32_F32_F32)487 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_F32_F32) {
488 auto* cast = vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f);
489 WrapInFunction(cast);
490
491 spirv::Builder& b = Build();
492
493 b.push_function(Function{});
494 EXPECT_EQ(b.GenerateExpression(cast), 4u);
495
496 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
497 %1 = OpTypeVector %2 4
498 %3 = OpConstant %2 2
499 %4 = OpConstantComposite %1 %3 %3 %3 %3
500 )");
501 }
502
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_F32_F32_Vec2)503 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_Vec2) {
504 auto* cast = vec4<f32>(2.0f, 2.0f, vec2<f32>(2.0f, 2.0f));
505 WrapInFunction(cast);
506
507 spirv::Builder& b = Build();
508
509 b.push_function(Function{});
510 EXPECT_EQ(b.GenerateExpression(cast), 8u);
511
512 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
513 %1 = OpTypeVector %2 4
514 %3 = OpConstant %2 2
515 %4 = OpTypeVector %2 2
516 %5 = OpConstantComposite %4 %3 %3
517 )");
518 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
519 R"(%6 = OpCompositeExtract %2 %5 0
520 %7 = OpCompositeExtract %2 %5 1
521 %8 = OpCompositeConstruct %1 %3 %3 %6 %7
522 )");
523 }
524
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_F32_Vec2_F32)525 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec2_F32) {
526 auto* cast = vec4<f32>(2.0f, vec2<f32>(2.0f, 2.0f), 2.0f);
527 WrapInFunction(cast);
528
529 spirv::Builder& b = Build();
530
531 b.push_function(Function{});
532 EXPECT_EQ(b.GenerateExpression(cast), 8u);
533
534 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
535 %1 = OpTypeVector %2 4
536 %3 = OpConstant %2 2
537 %4 = OpTypeVector %2 2
538 %5 = OpConstantComposite %4 %3 %3
539 )");
540 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
541 R"(%6 = OpCompositeExtract %2 %5 0
542 %7 = OpCompositeExtract %2 %5 1
543 %8 = OpCompositeConstruct %1 %3 %6 %7 %3
544 )");
545 }
546
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_Vec2_F32_F32)547 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_F32_F32) {
548 auto* cast = vec4<f32>(vec2<f32>(2.0f, 2.0f), 2.0f, 2.0f);
549 WrapInFunction(cast);
550
551 spirv::Builder& b = Build();
552
553 b.push_function(Function{});
554 EXPECT_EQ(b.GenerateExpression(cast), 8u);
555
556 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
557 %1 = OpTypeVector %2 4
558 %3 = OpTypeVector %2 2
559 %4 = OpConstant %2 2
560 %5 = OpConstantComposite %3 %4 %4
561 )");
562 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
563 R"(%6 = OpCompositeExtract %2 %5 0
564 %7 = OpCompositeExtract %2 %5 1
565 %8 = OpCompositeConstruct %1 %6 %7 %4 %4
566 )");
567 }
568
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_Vec2_Vec2)569 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_Vec2) {
570 auto* cast = vec4<f32>(vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f));
571 WrapInFunction(cast);
572
573 spirv::Builder& b = Build();
574
575 b.push_function(Function{});
576 EXPECT_EQ(b.GenerateExpression(cast), 10u);
577
578 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
579 %1 = OpTypeVector %2 4
580 %3 = OpTypeVector %2 2
581 %4 = OpConstant %2 2
582 %5 = OpConstantComposite %3 %4 %4
583 )");
584 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
585 R"(%6 = OpCompositeExtract %2 %5 0
586 %7 = OpCompositeExtract %2 %5 1
587 %8 = OpCompositeExtract %2 %5 0
588 %9 = OpCompositeExtract %2 %5 1
589 %10 = OpCompositeConstruct %1 %6 %7 %8 %9
590 )");
591 }
592
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_F32_Vec3)593 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec3) {
594 auto* cast = vec4<f32>(2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
595 WrapInFunction(cast);
596
597 spirv::Builder& b = Build();
598
599 b.push_function(Function{});
600 EXPECT_EQ(b.GenerateExpression(cast), 9u);
601
602 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
603 %1 = OpTypeVector %2 4
604 %3 = OpConstant %2 2
605 %4 = OpTypeVector %2 3
606 %5 = OpConstantComposite %4 %3 %3 %3
607 )");
608 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
609 R"(%6 = OpCompositeExtract %2 %5 0
610 %7 = OpCompositeExtract %2 %5 1
611 %8 = OpCompositeExtract %2 %5 2
612 %9 = OpCompositeConstruct %1 %3 %6 %7 %8
613 )");
614 }
615
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_Vec3_F32)616 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F32) {
617 auto* cast = vec4<f32>(vec3<f32>(2.0f, 2.0f, 2.0f), 2.0f);
618 WrapInFunction(cast);
619
620 spirv::Builder& b = Build();
621
622 b.push_function(Function{});
623 EXPECT_EQ(b.GenerateExpression(cast), 9u);
624
625 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
626 %1 = OpTypeVector %2 4
627 %3 = OpTypeVector %2 3
628 %4 = OpConstant %2 2
629 %5 = OpConstantComposite %3 %4 %4 %4
630 )");
631 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
632 R"(%6 = OpCompositeExtract %2 %5 0
633 %7 = OpCompositeExtract %2 %5 1
634 %8 = OpCompositeExtract %2 %5 2
635 %9 = OpCompositeConstruct %1 %6 %7 %8 %4
636 )");
637 }
638
TEST_F(SpvBuilderConstructorTest,Type_Vec4_With_Vec4)639 TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec4) {
640 auto* value = vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f);
641 auto* cast = vec4<f32>(value);
642 WrapInFunction(cast);
643
644 spirv::Builder& b = Build();
645
646 b.push_function(Function{});
647 EXPECT_EQ(b.GenerateExpression(cast), 5u);
648
649 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
650 %2 = OpTypeVector %3 4
651 %4 = OpConstant %3 2
652 %5 = OpConstantComposite %2 %4 %4 %4 %4
653 )");
654 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
655 }
656
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_F32_With_F32)657 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_F32_With_F32) {
658 auto* ctor = Construct<f32>(2.0f);
659 GlobalConst("g", ty.f32(), ctor);
660
661 spirv::Builder& b = SanitizeAndBuild();
662 ASSERT_TRUE(b.Build());
663
664 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
665 %2 = OpConstant %1 2
666 %4 = OpTypeVoid
667 %3 = OpTypeFunction %4
668 )");
669 Validate(b);
670 }
671
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_U32_With_F32)672 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_U32_With_F32) {
673 auto* ctor = Construct<u32>(1.5f);
674 GlobalConst("g", ty.u32(), ctor);
675
676 spirv::Builder& b = SanitizeAndBuild();
677 ASSERT_TRUE(b.Build());
678
679 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
680 %2 = OpConstant %1 1
681 %4 = OpTypeVoid
682 %3 = OpTypeFunction %4
683 )");
684 Validate(b);
685 }
686
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec2_With_F32)687 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_F32) {
688 auto* cast = vec2<f32>(2.0f);
689 auto* g = Global("g", ty.vec2<f32>(), cast, ast::StorageClass::kPrivate);
690
691 spirv::Builder& b = Build();
692
693 b.push_function(Function{});
694 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
695
696 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
697 %1 = OpTypeVector %2 2
698 %3 = OpConstant %2 2
699 %4 = OpConstantComposite %1 %3 %3
700 )");
701 }
702
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec2_With_Vec2)703 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_Vec2) {
704 auto* cast = vec2<f32>(vec2<f32>(2.0f, 2.0f));
705 GlobalConst("a", ty.vec2<f32>(), cast);
706
707 spirv::Builder& b = SanitizeAndBuild();
708 ASSERT_TRUE(b.Build());
709
710 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
711 %1 = OpTypeVector %2 2
712 %3 = OpConstant %2 2
713 %4 = OpConstantComposite %1 %3 %3
714 %6 = OpTypeVoid
715 %5 = OpTypeFunction %6
716 )");
717
718 Validate(b);
719 }
720
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec3_With_Vec3)721 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec3) {
722 auto* cast = vec3<f32>(vec3<f32>(2.0f, 2.0f, 2.0f));
723 GlobalConst("a", ty.vec3<f32>(), cast);
724
725 spirv::Builder& b = SanitizeAndBuild();
726 ASSERT_TRUE(b.Build());
727
728 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
729 %1 = OpTypeVector %2 3
730 %3 = OpConstant %2 2
731 %4 = OpConstantComposite %1 %3 %3 %3
732 %6 = OpTypeVoid
733 %5 = OpTypeFunction %6
734 )");
735
736 Validate(b);
737 }
738
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_Vec4)739 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec4) {
740 auto* cast = vec4<f32>(vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f));
741 GlobalConst("a", ty.vec4<f32>(), cast);
742
743 spirv::Builder& b = SanitizeAndBuild();
744 ASSERT_TRUE(b.Build());
745
746 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
747 %1 = OpTypeVector %2 4
748 %3 = OpConstant %2 2
749 %4 = OpConstantComposite %1 %3 %3 %3 %3
750 %6 = OpTypeVoid
751 %5 = OpTypeFunction %6
752 )");
753
754 Validate(b);
755 }
756
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec3_With_F32)757 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32) {
758 auto* cast = vec3<f32>(2.0f);
759 auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
760
761 spirv::Builder& b = Build();
762
763 b.push_function(Function{});
764 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
765
766 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
767 %1 = OpTypeVector %2 3
768 %3 = OpConstant %2 2
769 %4 = OpConstantComposite %1 %3 %3 %3
770 )");
771 }
772
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec3_With_F32_Vec2)773 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32_Vec2) {
774 auto* cast = vec3<f32>(2.0f, vec2<f32>(2.0f, 2.0f));
775 auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
776
777 spirv::Builder& b = Build();
778
779 b.push_function(Function{});
780 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
781
782 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
783 %1 = OpTypeVector %2 3
784 %3 = OpConstant %2 2
785 %4 = OpTypeVector %2 2
786 %5 = OpConstantComposite %4 %3 %3
787 %7 = OpTypeInt 32 0
788 %8 = OpConstant %7 0
789 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
790 %10 = OpConstant %7 1
791 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
792 %11 = OpSpecConstantComposite %1 %3 %6 %9
793 )");
794 }
795
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec3_With_Vec2_F32)796 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec2_F32) {
797 auto* cast = vec3<f32>(vec2<f32>(2.0f, 2.0f), 2.0f);
798 auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
799
800 spirv::Builder& b = Build();
801
802 b.push_function(Function{});
803 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
804
805 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
806 %1 = OpTypeVector %2 3
807 %3 = OpTypeVector %2 2
808 %4 = OpConstant %2 2
809 %5 = OpConstantComposite %3 %4 %4
810 %7 = OpTypeInt 32 0
811 %8 = OpConstant %7 0
812 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
813 %10 = OpConstant %7 1
814 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
815 %11 = OpSpecConstantComposite %1 %6 %9 %4
816 )");
817 }
818
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_F32)819 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32) {
820 auto* cast = vec4<f32>(2.0f);
821 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
822
823 spirv::Builder& b = Build();
824
825 b.push_function(Function{});
826 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
827
828 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
829 %1 = OpTypeVector %2 4
830 %3 = OpConstant %2 2
831 %4 = OpConstantComposite %1 %3 %3 %3 %3
832 )");
833 }
834
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_F32_F32_Vec2)835 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_F32_Vec2) {
836 auto* cast = vec4<f32>(2.0f, 2.0f, vec2<f32>(2.0f, 2.0f));
837 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
838
839 spirv::Builder& b = Build();
840
841 b.push_function(Function{});
842 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
843
844 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
845 %1 = OpTypeVector %2 4
846 %3 = OpConstant %2 2
847 %4 = OpTypeVector %2 2
848 %5 = OpConstantComposite %4 %3 %3
849 %7 = OpTypeInt 32 0
850 %8 = OpConstant %7 0
851 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
852 %10 = OpConstant %7 1
853 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
854 %11 = OpSpecConstantComposite %1 %3 %3 %6 %9
855 )");
856 }
857
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_F32_Vec2_F32)858 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec2_F32) {
859 auto* cast = vec4<f32>(2.0f, vec2<f32>(2.0f, 2.0f), 2.0f);
860 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
861
862 spirv::Builder& b = Build();
863
864 b.push_function(Function{});
865 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
866
867 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
868 %1 = OpTypeVector %2 4
869 %3 = OpConstant %2 2
870 %4 = OpTypeVector %2 2
871 %5 = OpConstantComposite %4 %3 %3
872 %7 = OpTypeInt 32 0
873 %8 = OpConstant %7 0
874 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
875 %10 = OpConstant %7 1
876 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
877 %11 = OpSpecConstantComposite %1 %3 %6 %9 %3
878 )");
879 }
880
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_Vec2_F32_F32)881 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_F32_F32) {
882 auto* cast = vec4<f32>(vec2<f32>(2.0f, 2.0f), 2.0f, 2.0f);
883 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
884
885 spirv::Builder& b = Build();
886
887 b.push_function(Function{});
888 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
889
890 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
891 %1 = OpTypeVector %2 4
892 %3 = OpTypeVector %2 2
893 %4 = OpConstant %2 2
894 %5 = OpConstantComposite %3 %4 %4
895 %7 = OpTypeInt 32 0
896 %8 = OpConstant %7 0
897 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
898 %10 = OpConstant %7 1
899 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
900 %11 = OpSpecConstantComposite %1 %6 %9 %4 %4
901 )");
902 }
903
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_Vec2_Vec2)904 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_Vec2) {
905 auto* cast = vec4<f32>(vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f));
906 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
907
908 spirv::Builder& b = Build();
909
910 b.push_function(Function{});
911 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
912
913 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
914 %1 = OpTypeVector %2 4
915 %3 = OpTypeVector %2 2
916 %4 = OpConstant %2 2
917 %5 = OpConstantComposite %3 %4 %4
918 %7 = OpTypeInt 32 0
919 %8 = OpConstant %7 0
920 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
921 %10 = OpConstant %7 1
922 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
923 %11 = OpSpecConstantOp %2 CompositeExtract %5 8
924 %12 = OpSpecConstantOp %2 CompositeExtract %5 10
925 %13 = OpSpecConstantComposite %1 %6 %9 %11 %12
926 )");
927 }
928
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_F32_Vec3)929 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec3) {
930 auto* cast = vec4<f32>(2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
931 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
932
933 spirv::Builder& b = Build();
934
935 b.push_function(Function{});
936 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
937
938 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
939 %1 = OpTypeVector %2 4
940 %3 = OpConstant %2 2
941 %4 = OpTypeVector %2 3
942 %5 = OpConstantComposite %4 %3 %3 %3
943 %7 = OpTypeInt 32 0
944 %8 = OpConstant %7 0
945 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
946 %10 = OpConstant %7 1
947 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
948 %12 = OpConstant %7 2
949 %11 = OpSpecConstantOp %2 CompositeExtract %5 12
950 %13 = OpSpecConstantComposite %1 %3 %6 %9 %11
951 )");
952 }
953
TEST_F(SpvBuilderConstructorTest,Type_ModuleScope_Vec4_With_Vec3_F32)954 TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec3_F32) {
955 auto* cast = vec4<f32>(vec3<f32>(2.0f, 2.0f, 2.0f), 2.0f);
956 auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
957
958 spirv::Builder& b = Build();
959
960 b.push_function(Function{});
961 EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
962
963 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
964 %1 = OpTypeVector %2 4
965 %3 = OpTypeVector %2 3
966 %4 = OpConstant %2 2
967 %5 = OpConstantComposite %3 %4 %4 %4
968 %7 = OpTypeInt 32 0
969 %8 = OpConstant %7 0
970 %6 = OpSpecConstantOp %2 CompositeExtract %5 8
971 %10 = OpConstant %7 1
972 %9 = OpSpecConstantOp %2 CompositeExtract %5 10
973 %12 = OpConstant %7 2
974 %11 = OpSpecConstantOp %2 CompositeExtract %5 12
975 %13 = OpSpecConstantComposite %1 %6 %9 %11 %4
976 )");
977 }
978
TEST_F(SpvBuilderConstructorTest,Type_Mat2x2_With_Vec2_Vec2)979 TEST_F(SpvBuilderConstructorTest, Type_Mat2x2_With_Vec2_Vec2) {
980 auto* cast = mat2x2<f32>(vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f));
981 WrapInFunction(cast);
982
983 spirv::Builder& b = Build();
984
985 b.push_function(Function{});
986 EXPECT_EQ(b.GenerateExpression(cast), 6u);
987
988 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
989 %2 = OpTypeVector %3 2
990 %1 = OpTypeMatrix %2 2
991 %4 = OpConstant %3 2
992 %5 = OpConstantComposite %2 %4 %4
993 %6 = OpConstantComposite %1 %5 %5
994 )");
995 }
996
TEST_F(SpvBuilderConstructorTest,Type_Mat3x2_With_Vec2_Vec2_Vec2)997 TEST_F(SpvBuilderConstructorTest, Type_Mat3x2_With_Vec2_Vec2_Vec2) {
998 auto* cast = mat3x2<f32>(vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f),
999 vec2<f32>(2.0f, 2.0f));
1000 WrapInFunction(cast);
1001
1002 spirv::Builder& b = Build();
1003
1004 b.push_function(Function{});
1005 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1006
1007 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1008 %2 = OpTypeVector %3 2
1009 %1 = OpTypeMatrix %2 3
1010 %4 = OpConstant %3 2
1011 %5 = OpConstantComposite %2 %4 %4
1012 %6 = OpConstantComposite %1 %5 %5 %5
1013 )");
1014 }
1015
TEST_F(SpvBuilderConstructorTest,Type_Mat4x2_With_Vec2_Vec2_Vec2_Vec2)1016 TEST_F(SpvBuilderConstructorTest, Type_Mat4x2_With_Vec2_Vec2_Vec2_Vec2) {
1017 auto* cast = mat4x2<f32>(vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f),
1018 vec2<f32>(2.0f, 2.0f), vec2<f32>(2.0f, 2.0f));
1019 WrapInFunction(cast);
1020
1021 spirv::Builder& b = Build();
1022
1023 b.push_function(Function{});
1024 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1025
1026 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1027 %2 = OpTypeVector %3 2
1028 %1 = OpTypeMatrix %2 4
1029 %4 = OpConstant %3 2
1030 %5 = OpConstantComposite %2 %4 %4
1031 %6 = OpConstantComposite %1 %5 %5 %5 %5
1032 )");
1033 }
1034
TEST_F(SpvBuilderConstructorTest,Type_Mat2x3_With_Vec3_Vec3)1035 TEST_F(SpvBuilderConstructorTest, Type_Mat2x3_With_Vec3_Vec3) {
1036 auto* cast =
1037 mat2x3<f32>(vec3<f32>(2.0f, 2.0f, 2.0f), vec3<f32>(2.0f, 2.0f, 2.0f));
1038 WrapInFunction(cast);
1039
1040 spirv::Builder& b = Build();
1041
1042 b.push_function(Function{});
1043 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1044
1045 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1046 %2 = OpTypeVector %3 3
1047 %1 = OpTypeMatrix %2 2
1048 %4 = OpConstant %3 2
1049 %5 = OpConstantComposite %2 %4 %4 %4
1050 %6 = OpConstantComposite %1 %5 %5
1051 )");
1052 }
1053
TEST_F(SpvBuilderConstructorTest,Type_Mat3x3_With_Vec3_Vec3_Vec3)1054 TEST_F(SpvBuilderConstructorTest, Type_Mat3x3_With_Vec3_Vec3_Vec3) {
1055 auto* cast =
1056 mat3x3<f32>(vec3<f32>(2.0f, 2.0f, 2.0f), vec3<f32>(2.0f, 2.0f, 2.0f),
1057 vec3<f32>(2.0f, 2.0f, 2.0f));
1058 WrapInFunction(cast);
1059
1060 spirv::Builder& b = Build();
1061
1062 b.push_function(Function{});
1063 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1064
1065 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1066 %2 = OpTypeVector %3 3
1067 %1 = OpTypeMatrix %2 3
1068 %4 = OpConstant %3 2
1069 %5 = OpConstantComposite %2 %4 %4 %4
1070 %6 = OpConstantComposite %1 %5 %5 %5
1071 )");
1072 }
1073
TEST_F(SpvBuilderConstructorTest,Type_Mat4x3_With_Vec3_Vec3_Vec3_Vec3)1074 TEST_F(SpvBuilderConstructorTest, Type_Mat4x3_With_Vec3_Vec3_Vec3_Vec3) {
1075 auto* cast =
1076 mat4x3<f32>(vec3<f32>(2.0f, 2.0f, 2.0f), vec3<f32>(2.0f, 2.0f, 2.0f),
1077 vec3<f32>(2.0f, 2.0f, 2.0f), vec3<f32>(2.0f, 2.0f, 2.0f));
1078 WrapInFunction(cast);
1079
1080 spirv::Builder& b = Build();
1081
1082 b.push_function(Function{});
1083 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1084
1085 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1086 %2 = OpTypeVector %3 3
1087 %1 = OpTypeMatrix %2 4
1088 %4 = OpConstant %3 2
1089 %5 = OpConstantComposite %2 %4 %4 %4
1090 %6 = OpConstantComposite %1 %5 %5 %5 %5
1091 )");
1092 }
1093
TEST_F(SpvBuilderConstructorTest,Type_Mat2x4_With_Vec4_Vec4)1094 TEST_F(SpvBuilderConstructorTest, Type_Mat2x4_With_Vec4_Vec4) {
1095 auto* cast = mat2x4<f32>(vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f),
1096 vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f));
1097 WrapInFunction(cast);
1098
1099 spirv::Builder& b = Build();
1100
1101 b.push_function(Function{});
1102 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1103
1104 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1105 %2 = OpTypeVector %3 4
1106 %1 = OpTypeMatrix %2 2
1107 %4 = OpConstant %3 2
1108 %5 = OpConstantComposite %2 %4 %4 %4 %4
1109 %6 = OpConstantComposite %1 %5 %5
1110 )");
1111 }
1112
TEST_F(SpvBuilderConstructorTest,Type_Mat3x4_With_Vec4_Vec4_Vec4)1113 TEST_F(SpvBuilderConstructorTest, Type_Mat3x4_With_Vec4_Vec4_Vec4) {
1114 auto* cast = mat3x4<f32>(vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f),
1115 vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f),
1116 vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f));
1117 WrapInFunction(cast);
1118
1119 spirv::Builder& b = Build();
1120
1121 b.push_function(Function{});
1122 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1123
1124 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1125 %2 = OpTypeVector %3 4
1126 %1 = OpTypeMatrix %2 3
1127 %4 = OpConstant %3 2
1128 %5 = OpConstantComposite %2 %4 %4 %4 %4
1129 %6 = OpConstantComposite %1 %5 %5 %5
1130 )");
1131 }
1132
TEST_F(SpvBuilderConstructorTest,Type_Mat4x4_With_Vec4_Vec4_Vec4_Vec4)1133 TEST_F(SpvBuilderConstructorTest, Type_Mat4x4_With_Vec4_Vec4_Vec4_Vec4) {
1134 auto* cast = mat4x4<f32>(
1135 vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f), vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f),
1136 vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f), vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f));
1137 WrapInFunction(cast);
1138
1139 spirv::Builder& b = Build();
1140
1141 b.push_function(Function{});
1142 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1143
1144 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1145 %2 = OpTypeVector %3 4
1146 %1 = OpTypeMatrix %2 4
1147 %4 = OpConstant %3 2
1148 %5 = OpConstantComposite %2 %4 %4 %4 %4
1149 %6 = OpConstantComposite %1 %5 %5 %5 %5
1150 )");
1151 }
1152
TEST_F(SpvBuilderConstructorTest,Type_Array_5_F32)1153 TEST_F(SpvBuilderConstructorTest, Type_Array_5_F32) {
1154 auto* cast = array<f32, 5>(2.0f, 2.0f, 2.0f, 2.0f, 2.0f);
1155 WrapInFunction(cast);
1156
1157 spirv::Builder& b = Build();
1158
1159 b.push_function(Function{});
1160 EXPECT_EQ(b.GenerateExpression(cast), 6u);
1161
1162 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1163 %3 = OpTypeInt 32 0
1164 %4 = OpConstant %3 5
1165 %1 = OpTypeArray %2 %4
1166 %5 = OpConstant %2 2
1167 %6 = OpConstantComposite %1 %5 %5 %5 %5 %5
1168 )");
1169 }
1170
TEST_F(SpvBuilderConstructorTest,Type_Array_2_Vec3)1171 TEST_F(SpvBuilderConstructorTest, Type_Array_2_Vec3) {
1172 auto* first = vec3<f32>(1.f, 2.f, 3.f);
1173 auto* second = vec3<f32>(1.f, 2.f, 3.f);
1174 auto* t = Construct(ty.array(ty.vec3<f32>(), 2), first, second);
1175 WrapInFunction(t);
1176 spirv::Builder& b = Build();
1177
1178 b.push_function(Function{});
1179 EXPECT_EQ(b.GenerateExpression(t), 10u);
1180 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1181 %2 = OpTypeVector %3 3
1182 %4 = OpTypeInt 32 0
1183 %5 = OpConstant %4 2
1184 %1 = OpTypeArray %2 %5
1185 %6 = OpConstant %3 1
1186 %7 = OpConstant %3 2
1187 %8 = OpConstant %3 3
1188 %9 = OpConstantComposite %2 %6 %7 %8
1189 %10 = OpConstantComposite %1 %9 %9
1190 )");
1191 }
1192
TEST_F(SpvBuilderConstructorTest,CommonInitializer_TwoVectors)1193 TEST_F(SpvBuilderConstructorTest, CommonInitializer_TwoVectors) {
1194 auto* v1 = vec3<f32>(2.0f, 2.0f, 2.0f);
1195 auto* v2 = vec3<f32>(2.0f, 2.0f, 2.0f);
1196 ast::StatementList stmts = {
1197 WrapInStatement(v1),
1198 WrapInStatement(v2),
1199 };
1200 WrapInFunction(stmts);
1201
1202 spirv::Builder& b = Build();
1203
1204 b.push_function(Function{});
1205 EXPECT_EQ(b.GenerateExpression(v1), 4u);
1206 EXPECT_EQ(b.GenerateExpression(v2), 4u);
1207
1208 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1209 %1 = OpTypeVector %2 3
1210 %3 = OpConstant %2 2
1211 %4 = OpConstantComposite %1 %3 %3 %3
1212 )");
1213 }
1214
TEST_F(SpvBuilderConstructorTest,CommonInitializer_TwoArrays)1215 TEST_F(SpvBuilderConstructorTest, CommonInitializer_TwoArrays) {
1216 auto* a1 = array<f32, 3>(2.0f, 2.0f, 2.0f);
1217 auto* a2 = array<f32, 3>(2.0f, 2.0f, 2.0f);
1218 ast::StatementList stmts = {
1219 WrapInStatement(a1),
1220 WrapInStatement(a2),
1221 };
1222 WrapInFunction(stmts);
1223
1224 spirv::Builder& b = Build();
1225
1226 b.push_function(Function{});
1227 EXPECT_EQ(b.GenerateExpression(a1), 6u);
1228 EXPECT_EQ(b.GenerateExpression(a2), 6u);
1229
1230 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1231 %3 = OpTypeInt 32 0
1232 %4 = OpConstant %3 3
1233 %1 = OpTypeArray %2 %4
1234 %5 = OpConstant %2 2
1235 %6 = OpConstantComposite %1 %5 %5 %5
1236 )");
1237 }
1238
TEST_F(SpvBuilderConstructorTest,CommonInitializer_Array_VecArray)1239 TEST_F(SpvBuilderConstructorTest, CommonInitializer_Array_VecArray) {
1240 // Test that initializers of different types with the same values produce
1241 // different OpConstantComposite instructions.
1242 // crbug.com/tint/777
1243 auto* a1 = array<f32, 2>(1.0f, 2.0f);
1244 auto* a2 = vec2<f32>(1.0f, 2.0f);
1245 ast::StatementList stmts = {
1246 WrapInStatement(a1),
1247 WrapInStatement(a2),
1248 };
1249 WrapInFunction(stmts);
1250 spirv::Builder& b = Build();
1251
1252 b.push_function(Function{});
1253 EXPECT_EQ(b.GenerateExpression(a1), 7u);
1254 EXPECT_EQ(b.GenerateExpression(a2), 9u);
1255
1256 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1257 %3 = OpTypeInt 32 0
1258 %4 = OpConstant %3 2
1259 %1 = OpTypeArray %2 %4
1260 %5 = OpConstant %2 1
1261 %6 = OpConstant %2 2
1262 %7 = OpConstantComposite %1 %5 %6
1263 %8 = OpTypeVector %2 2
1264 %9 = OpConstantComposite %8 %5 %6
1265 )");
1266 }
1267
TEST_F(SpvBuilderConstructorTest,Type_Struct)1268 TEST_F(SpvBuilderConstructorTest, Type_Struct) {
1269 auto* s = Structure("my_struct", {
1270 Member("a", ty.f32()),
1271 Member("b", ty.vec3<f32>()),
1272 });
1273
1274 auto* t = Construct(ty.Of(s), 2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
1275 WrapInFunction(t);
1276
1277 spirv::Builder& b = Build();
1278
1279 b.push_function(Function{});
1280
1281 EXPECT_EQ(b.GenerateExpression(t), 6u);
1282 ASSERT_FALSE(b.has_error()) << b.error();
1283
1284 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1285 %3 = OpTypeVector %2 3
1286 %1 = OpTypeStruct %2 %3
1287 %4 = OpConstant %2 2
1288 %5 = OpConstantComposite %3 %4 %4 %4
1289 %6 = OpConstantComposite %1 %4 %5
1290 )");
1291 }
1292
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_F32)1293 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_F32) {
1294 auto* t = Construct<f32>();
1295
1296 WrapInFunction(t);
1297
1298 spirv::Builder& b = Build();
1299
1300 b.push_function(Function{});
1301
1302 EXPECT_EQ(b.GenerateExpression(t), 2u);
1303 ASSERT_FALSE(b.has_error()) << b.error();
1304
1305 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
1306 %2 = OpConstantNull %1
1307 )");
1308 }
1309
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_I32)1310 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_I32) {
1311 auto* t = Construct<i32>();
1312
1313 WrapInFunction(t);
1314
1315 spirv::Builder& b = Build();
1316
1317 b.push_function(Function{});
1318
1319 EXPECT_EQ(b.GenerateExpression(t), 2u);
1320 ASSERT_FALSE(b.has_error()) << b.error();
1321
1322 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
1323 %2 = OpConstantNull %1
1324 )");
1325 }
1326
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_U32)1327 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_U32) {
1328 auto* t = Construct<u32>();
1329
1330 WrapInFunction(t);
1331
1332 spirv::Builder& b = Build();
1333
1334 b.push_function(Function{});
1335
1336 EXPECT_EQ(b.GenerateExpression(t), 2u);
1337 ASSERT_FALSE(b.has_error()) << b.error();
1338
1339 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
1340 %2 = OpConstantNull %1
1341 )");
1342 }
1343
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_Bool)1344 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Bool) {
1345 auto* t = Construct<bool>();
1346
1347 WrapInFunction(t);
1348
1349 spirv::Builder& b = Build();
1350
1351 b.push_function(Function{});
1352
1353 EXPECT_EQ(b.GenerateExpression(t), 2u);
1354 ASSERT_FALSE(b.has_error()) << b.error();
1355
1356 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
1357 %2 = OpConstantNull %1
1358 )");
1359 }
1360
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_Vector)1361 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Vector) {
1362 auto* t = vec2<i32>();
1363
1364 WrapInFunction(t);
1365
1366 spirv::Builder& b = Build();
1367
1368 b.push_function(Function{});
1369
1370 EXPECT_EQ(b.GenerateExpression(t), 3u);
1371 ASSERT_FALSE(b.has_error()) << b.error();
1372
1373 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
1374 %1 = OpTypeVector %2 2
1375 %3 = OpConstantNull %1
1376 )");
1377 }
1378
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_Matrix)1379 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Matrix) {
1380 auto* t = mat4x2<f32>();
1381
1382 WrapInFunction(t);
1383
1384 spirv::Builder& b = Build();
1385
1386 b.push_function(Function{});
1387
1388 EXPECT_EQ(b.GenerateExpression(t), 4u);
1389 ASSERT_FALSE(b.has_error()) << b.error();
1390
1391 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
1392 %2 = OpTypeVector %3 2
1393 %1 = OpTypeMatrix %2 4
1394 %4 = OpConstantNull %1
1395 )");
1396 }
1397
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_Array)1398 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Array) {
1399 auto* t = array<i32, 2>();
1400
1401 WrapInFunction(t);
1402
1403 spirv::Builder& b = Build();
1404
1405 b.push_function(Function{});
1406
1407 EXPECT_EQ(b.GenerateExpression(t), 5u);
1408 ASSERT_FALSE(b.has_error()) << b.error();
1409
1410 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
1411 %3 = OpTypeInt 32 0
1412 %4 = OpConstant %3 2
1413 %1 = OpTypeArray %2 %4
1414 %5 = OpConstantNull %1
1415 )");
1416 }
1417
TEST_F(SpvBuilderConstructorTest,Type_ZeroInit_Struct)1418 TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) {
1419 auto* s = Structure("my_struct", {Member("a", ty.f32())});
1420 auto* t = Construct(ty.Of(s));
1421 WrapInFunction(t);
1422
1423 spirv::Builder& b = Build();
1424
1425 b.push_function(Function{});
1426
1427 EXPECT_EQ(b.GenerateExpression(t), 3u);
1428 ASSERT_FALSE(b.has_error()) << b.error();
1429
1430 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1431 %1 = OpTypeStruct %2
1432 %3 = OpConstantNull %1
1433 )");
1434 }
1435
TEST_F(SpvBuilderConstructorTest,Type_Convert_U32_To_I32)1436 TEST_F(SpvBuilderConstructorTest, Type_Convert_U32_To_I32) {
1437 auto* cast = Construct<i32>(2u);
1438 WrapInFunction(cast);
1439
1440 spirv::Builder& b = Build();
1441
1442 b.push_function(Function{});
1443 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1444
1445 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
1446 %3 = OpTypeInt 32 0
1447 %4 = OpConstant %3 2
1448 )");
1449 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1450 R"(%1 = OpBitcast %2 %4
1451 )");
1452 }
1453
TEST_F(SpvBuilderConstructorTest,Type_Convert_I32_To_U32)1454 TEST_F(SpvBuilderConstructorTest, Type_Convert_I32_To_U32) {
1455 auto* cast = Construct<u32>(2);
1456 WrapInFunction(cast);
1457
1458 spirv::Builder& b = Build();
1459
1460 b.push_function(Function{});
1461 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1462
1463 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
1464 %3 = OpTypeInt 32 1
1465 %4 = OpConstant %3 2
1466 )");
1467 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1468 R"(%1 = OpBitcast %2 %4
1469 )");
1470 }
1471
TEST_F(SpvBuilderConstructorTest,Type_Convert_F32_To_I32)1472 TEST_F(SpvBuilderConstructorTest, Type_Convert_F32_To_I32) {
1473 auto* cast = Construct<i32>(2.4f);
1474 WrapInFunction(cast);
1475
1476 spirv::Builder& b = Build();
1477
1478 b.push_function(Function{});
1479 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1480
1481 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
1482 %3 = OpTypeFloat 32
1483 %4 = OpConstant %3 2.4000001
1484 )");
1485 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1486 R"(%1 = OpConvertFToS %2 %4
1487 )");
1488 }
1489
TEST_F(SpvBuilderConstructorTest,Type_Convert_F32_To_U32)1490 TEST_F(SpvBuilderConstructorTest, Type_Convert_F32_To_U32) {
1491 auto* cast = Construct<u32>(2.4f);
1492 WrapInFunction(cast);
1493
1494 spirv::Builder& b = Build();
1495
1496 b.push_function(Function{});
1497 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1498
1499 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
1500 %3 = OpTypeFloat 32
1501 %4 = OpConstant %3 2.4000001
1502 )");
1503 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1504 R"(%1 = OpConvertFToU %2 %4
1505 )");
1506 }
1507
TEST_F(SpvBuilderConstructorTest,Type_Convert_I32_To_F32)1508 TEST_F(SpvBuilderConstructorTest, Type_Convert_I32_To_F32) {
1509 auto* cast = Construct<f32>(2);
1510 WrapInFunction(cast);
1511
1512 spirv::Builder& b = Build();
1513
1514 b.push_function(Function{});
1515 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1516
1517 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1518 %3 = OpTypeInt 32 1
1519 %4 = OpConstant %3 2
1520 )");
1521 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1522 R"(%1 = OpConvertSToF %2 %4
1523 )");
1524 }
1525
TEST_F(SpvBuilderConstructorTest,Type_Convert_U32_To_F32)1526 TEST_F(SpvBuilderConstructorTest, Type_Convert_U32_To_F32) {
1527 auto* cast = Construct<f32>(2u);
1528 WrapInFunction(cast);
1529
1530 spirv::Builder& b = Build();
1531
1532 b.push_function(Function{});
1533 EXPECT_EQ(b.GenerateExpression(cast), 1u);
1534
1535 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
1536 %3 = OpTypeInt 32 0
1537 %4 = OpConstant %3 2
1538 )");
1539 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1540 R"(%1 = OpConvertUToF %2 %4
1541 )");
1542 }
1543
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_U32_to_I32)1544 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_I32) {
1545 auto* var = Global("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
1546
1547 auto* cast = vec3<i32>("i");
1548 WrapInFunction(cast);
1549
1550 spirv::Builder& b = Build();
1551
1552 b.push_function(Function{});
1553 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1554 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1555
1556 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
1557 %3 = OpTypeVector %4 3
1558 %2 = OpTypePointer Private %3
1559 %5 = OpConstantNull %3
1560 %1 = OpVariable %2 Private %5
1561 %8 = OpTypeInt 32 1
1562 %7 = OpTypeVector %8 3
1563 )");
1564 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1565 R"(%9 = OpLoad %3 %1
1566 %6 = OpBitcast %7 %9
1567 )");
1568 }
1569
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_F32_to_I32)1570 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_I32) {
1571 auto* var = Global("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
1572
1573 auto* cast = vec3<i32>("i");
1574 WrapInFunction(cast);
1575
1576 spirv::Builder& b = Build();
1577
1578 b.push_function(Function{});
1579 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1580 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1581
1582 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
1583 %3 = OpTypeVector %4 3
1584 %2 = OpTypePointer Private %3
1585 %5 = OpConstantNull %3
1586 %1 = OpVariable %2 Private %5
1587 %8 = OpTypeInt 32 1
1588 %7 = OpTypeVector %8 3
1589 )");
1590 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1591 R"(%9 = OpLoad %3 %1
1592 %6 = OpConvertFToS %7 %9
1593 )");
1594 }
1595
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_I32_to_U32)1596 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_U32) {
1597 auto* var = Global("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
1598
1599 auto* cast = vec3<u32>("i");
1600 WrapInFunction(cast);
1601
1602 spirv::Builder& b = Build();
1603
1604 b.push_function(Function{});
1605 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1606 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1607
1608 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
1609 %3 = OpTypeVector %4 3
1610 %2 = OpTypePointer Private %3
1611 %5 = OpConstantNull %3
1612 %1 = OpVariable %2 Private %5
1613 %8 = OpTypeInt 32 0
1614 %7 = OpTypeVector %8 3
1615 )");
1616 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1617 R"(%9 = OpLoad %3 %1
1618 %6 = OpBitcast %7 %9
1619 )");
1620 }
1621
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_F32_to_U32)1622 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_U32) {
1623 auto* var = Global("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
1624
1625 auto* cast = vec3<u32>("i");
1626 WrapInFunction(cast);
1627
1628 spirv::Builder& b = Build();
1629
1630 b.push_function(Function{});
1631 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1632 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1633
1634 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
1635 %3 = OpTypeVector %4 3
1636 %2 = OpTypePointer Private %3
1637 %5 = OpConstantNull %3
1638 %1 = OpVariable %2 Private %5
1639 %8 = OpTypeInt 32 0
1640 %7 = OpTypeVector %8 3
1641 )");
1642 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1643 R"(%9 = OpLoad %3 %1
1644 %6 = OpConvertFToU %7 %9
1645 )");
1646 }
1647
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_I32_to_F32)1648 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_F32) {
1649 auto* var = Global("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
1650
1651 auto* cast = vec3<f32>("i");
1652 WrapInFunction(cast);
1653
1654 spirv::Builder& b = Build();
1655
1656 b.push_function(Function{});
1657 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1658 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1659
1660 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
1661 %3 = OpTypeVector %4 3
1662 %2 = OpTypePointer Private %3
1663 %5 = OpConstantNull %3
1664 %1 = OpVariable %2 Private %5
1665 %8 = OpTypeFloat 32
1666 %7 = OpTypeVector %8 3
1667 )");
1668 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1669 R"(%9 = OpLoad %3 %1
1670 %6 = OpConvertSToF %7 %9
1671 )");
1672 }
1673
TEST_F(SpvBuilderConstructorTest,Type_Convert_Vectors_U32_to_F32)1674 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_F32) {
1675 auto* var = Global("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
1676
1677 auto* cast = vec3<f32>("i");
1678 WrapInFunction(cast);
1679
1680 spirv::Builder& b = Build();
1681
1682 b.push_function(Function{});
1683 ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
1684 EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
1685
1686 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
1687 %3 = OpTypeVector %4 3
1688 %2 = OpTypePointer Private %3
1689 %5 = OpConstantNull %3
1690 %1 = OpVariable %2 Private %5
1691 %8 = OpTypeFloat 32
1692 %7 = OpTypeVector %8 3
1693 )");
1694 EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
1695 R"(%9 = OpLoad %3 %1
1696 %6 = OpConvertUToF %7 %9
1697 )");
1698 }
1699
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_GlobalVectorWithAllConstConstructors)1700 TEST_F(SpvBuilderConstructorTest,
1701 IsConstructorConst_GlobalVectorWithAllConstConstructors) {
1702 // vec3<f32>(1.0, 2.0, 3.0) -> true
1703 auto* t = vec3<f32>(1.f, 2.f, 3.f);
1704 WrapInFunction(t);
1705
1706 spirv::Builder& b = Build();
1707
1708 EXPECT_TRUE(b.IsConstructorConst(t));
1709 EXPECT_FALSE(b.has_error());
1710 }
1711
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_GlobalArrayWithAllConstConstructors)1712 TEST_F(SpvBuilderConstructorTest,
1713 IsConstructorConst_GlobalArrayWithAllConstConstructors) {
1714 // array<vec3<f32>, 2>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
1715 // -> true
1716 auto* t = Construct(ty.array(ty.vec3<f32>(), 2), vec3<f32>(1.f, 2.f, 3.f),
1717 vec3<f32>(1.f, 2.f, 3.f));
1718 WrapInFunction(t);
1719
1720 spirv::Builder& b = Build();
1721
1722 EXPECT_TRUE(b.IsConstructorConst(t));
1723 EXPECT_FALSE(b.has_error());
1724 }
1725
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_GlobalVectorWithMatchingTypeConstructors)1726 TEST_F(SpvBuilderConstructorTest,
1727 IsConstructorConst_GlobalVectorWithMatchingTypeConstructors) {
1728 // vec2<f32>(f32(1.0), f32(2.0)) -> false
1729
1730 auto* t = vec2<f32>(Construct<f32>(1.f), Construct<f32>(2.f));
1731 WrapInFunction(t);
1732
1733 spirv::Builder& b = Build();
1734
1735 EXPECT_TRUE(b.IsConstructorConst(t));
1736 EXPECT_FALSE(b.has_error());
1737 }
1738
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_GlobalWithTypeConversionConstructor)1739 TEST_F(SpvBuilderConstructorTest,
1740 IsConstructorConst_GlobalWithTypeConversionConstructor) {
1741 // vec2<f32>(f32(1), f32(2)) -> false
1742
1743 auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(2));
1744 WrapInFunction(t);
1745
1746 spirv::Builder& b = Build();
1747
1748 EXPECT_FALSE(b.IsConstructorConst(t));
1749 EXPECT_FALSE(b.has_error());
1750 }
1751
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_VectorWithAllConstConstructors)1752 TEST_F(SpvBuilderConstructorTest,
1753 IsConstructorConst_VectorWithAllConstConstructors) {
1754 // vec3<f32>(1.0, 2.0, 3.0) -> true
1755
1756 auto* t = vec3<f32>(1.f, 2.f, 3.f);
1757 WrapInFunction(t);
1758
1759 spirv::Builder& b = Build();
1760
1761 EXPECT_TRUE(b.IsConstructorConst(t));
1762 EXPECT_FALSE(b.has_error());
1763 }
1764
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_Vector_WithIdent)1765 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Vector_WithIdent) {
1766 // vec3<f32>(a, b, c) -> false
1767
1768 Global("a", ty.f32(), ast::StorageClass::kPrivate);
1769 Global("b", ty.f32(), ast::StorageClass::kPrivate);
1770 Global("c", ty.f32(), ast::StorageClass::kPrivate);
1771
1772 auto* t = vec3<f32>("a", "b", "c");
1773 WrapInFunction(t);
1774
1775 spirv::Builder& b = Build();
1776
1777 EXPECT_FALSE(b.IsConstructorConst(t));
1778 EXPECT_FALSE(b.has_error());
1779 }
1780
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_ArrayWithAllConstConstructors)1781 TEST_F(SpvBuilderConstructorTest,
1782 IsConstructorConst_ArrayWithAllConstConstructors) {
1783 // array<vec3<f32>, 2>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
1784 // -> true
1785
1786 auto* first = vec3<f32>(1.f, 2.f, 3.f);
1787 auto* second = vec3<f32>(1.f, 2.f, 3.f);
1788
1789 auto* t = Construct(ty.array(ty.vec3<f32>(), 2), first, second);
1790 WrapInFunction(t);
1791
1792 spirv::Builder& b = Build();
1793
1794 EXPECT_TRUE(b.IsConstructorConst(t));
1795 EXPECT_FALSE(b.has_error());
1796 }
1797
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_VectorWithTypeConversionConstConstructors)1798 TEST_F(SpvBuilderConstructorTest,
1799 IsConstructorConst_VectorWithTypeConversionConstConstructors) {
1800 // vec2<f32>(f32(1), f32(2)) -> false
1801
1802 auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(2));
1803 WrapInFunction(t);
1804
1805 spirv::Builder& b = Build();
1806
1807 EXPECT_FALSE(b.IsConstructorConst(t));
1808 EXPECT_FALSE(b.has_error());
1809 }
1810
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_BitCastScalars)1811 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_BitCastScalars) {
1812 auto* t = vec2<u32>(Construct<u32>(1), Construct<u32>(1));
1813 WrapInFunction(t);
1814
1815 spirv::Builder& b = Build();
1816
1817 EXPECT_FALSE(b.IsConstructorConst(t));
1818 EXPECT_FALSE(b.has_error());
1819 }
1820
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_Struct)1821 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) {
1822 auto* s = Structure("my_struct", {
1823 Member("a", ty.f32()),
1824 Member("b", ty.vec3<f32>()),
1825 });
1826
1827 auto* t = Construct(ty.Of(s), 2.f, vec3<f32>(2.f, 2.f, 2.f));
1828 WrapInFunction(t);
1829
1830 spirv::Builder& b = Build();
1831
1832 EXPECT_TRUE(b.IsConstructorConst(t));
1833 EXPECT_FALSE(b.has_error());
1834 }
1835
TEST_F(SpvBuilderConstructorTest,IsConstructorConst_Struct_WithIdentSubExpression)1836 TEST_F(SpvBuilderConstructorTest,
1837 IsConstructorConst_Struct_WithIdentSubExpression) {
1838 auto* s = Structure("my_struct", {
1839 Member("a", ty.f32()),
1840 Member("b", ty.vec3<f32>()),
1841 });
1842
1843 Global("a", ty.f32(), ast::StorageClass::kPrivate);
1844 Global("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
1845
1846 auto* t = Construct(ty.Of(s), "a", "b");
1847 WrapInFunction(t);
1848
1849 spirv::Builder& b = Build();
1850
1851 EXPECT_FALSE(b.IsConstructorConst(t));
1852 EXPECT_FALSE(b.has_error());
1853 }
1854
1855 } // namespace
1856 } // namespace spirv
1857 } // namespace writer
1858 } // namespace tint
1859