• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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