• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/append_vector.h"
16 #include "src/program_builder.h"
17 #include "src/resolver/resolver.h"
18 #include "src/sem/type_constructor.h"
19 
20 #include "gtest/gtest.h"
21 
22 namespace tint {
23 namespace writer {
24 namespace {
25 
26 class AppendVectorTest : public ::testing::Test, public ProgramBuilder {};
27 
28 // AppendVector(vec2<i32>(1, 2), 3) -> vec3<i32>(1, 2, 3)
TEST_F(AppendVectorTest,Vec2i32_i32)29 TEST_F(AppendVectorTest, Vec2i32_i32) {
30   auto* scalar_1 = Expr(1);
31   auto* scalar_2 = Expr(2);
32   auto* scalar_3 = Expr(3);
33   auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
34   WrapInFunction(vec_12, scalar_3);
35 
36   resolver::Resolver resolver(this);
37   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
38 
39   auto* append = AppendVector(this, vec_12, scalar_3);
40 
41   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
42   ASSERT_NE(vec_123, nullptr);
43   ASSERT_EQ(vec_123->args.size(), 3u);
44   EXPECT_EQ(vec_123->args[0], scalar_1);
45   EXPECT_EQ(vec_123->args[1], scalar_2);
46   EXPECT_EQ(vec_123->args[2], scalar_3);
47 
48   auto* call = Sem().Get(vec_123);
49   ASSERT_NE(call, nullptr);
50   ASSERT_EQ(call->Arguments().size(), 3u);
51   EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
52   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_2));
53   EXPECT_EQ(call->Arguments()[2], Sem().Get(scalar_3));
54 
55   auto* ctor = call->Target()->As<sem::TypeConstructor>();
56   ASSERT_NE(ctor, nullptr);
57   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
58   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
59   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
60   EXPECT_EQ(ctor->ReturnType(), call->Type());
61 
62   ASSERT_EQ(ctor->Parameters().size(), 3u);
63   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
64   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
65   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
66 }
67 
68 // AppendVector(vec2<i32>(1, 2), 3u) -> vec3<i32>(1, 2, i32(3u))
TEST_F(AppendVectorTest,Vec2i32_u32)69 TEST_F(AppendVectorTest, Vec2i32_u32) {
70   auto* scalar_1 = Expr(1);
71   auto* scalar_2 = Expr(2);
72   auto* scalar_3 = Expr(3u);
73   auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
74   WrapInFunction(vec_12, scalar_3);
75 
76   resolver::Resolver resolver(this);
77   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
78 
79   auto* append = AppendVector(this, vec_12, scalar_3);
80 
81   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
82   ASSERT_NE(vec_123, nullptr);
83   ASSERT_EQ(vec_123->args.size(), 3u);
84   EXPECT_EQ(vec_123->args[0], scalar_1);
85   EXPECT_EQ(vec_123->args[1], scalar_2);
86   auto* u32_to_i32 = vec_123->args[2]->As<ast::CallExpression>();
87   ASSERT_NE(u32_to_i32, nullptr);
88   EXPECT_TRUE(u32_to_i32->target.type->Is<ast::I32>());
89   ASSERT_EQ(u32_to_i32->args.size(), 1u);
90   EXPECT_EQ(u32_to_i32->args[0], scalar_3);
91 
92   auto* call = Sem().Get(vec_123);
93   ASSERT_NE(call, nullptr);
94   ASSERT_EQ(call->Arguments().size(), 3u);
95   EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
96   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_2));
97   EXPECT_EQ(call->Arguments()[2], Sem().Get(u32_to_i32));
98 
99   auto* ctor = call->Target()->As<sem::TypeConstructor>();
100   ASSERT_NE(ctor, nullptr);
101   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
102   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
103   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
104   EXPECT_EQ(ctor->ReturnType(), call->Type());
105 
106   ASSERT_EQ(ctor->Parameters().size(), 3u);
107   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
108   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
109   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
110 }
111 
112 // AppendVector(vec2<i32>(vec2<u32>(1u, 2u)), 3u) ->
113 //    vec3<i32>(vec2<i32>(vec2<u32>(1u, 2u)), i32(3u))
TEST_F(AppendVectorTest,Vec2i32FromVec2u32_u32)114 TEST_F(AppendVectorTest, Vec2i32FromVec2u32_u32) {
115   auto* scalar_1 = Expr(1u);
116   auto* scalar_2 = Expr(2u);
117   auto* scalar_3 = Expr(3u);
118   auto* uvec_12 = vec2<u32>(scalar_1, scalar_2);
119   auto* vec_12 = vec2<i32>(uvec_12);
120   WrapInFunction(vec_12, scalar_3);
121 
122   resolver::Resolver resolver(this);
123   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
124 
125   auto* append = AppendVector(this, vec_12, scalar_3);
126 
127   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
128   ASSERT_NE(vec_123, nullptr);
129   ASSERT_EQ(vec_123->args.size(), 2u);
130   auto* v2u32_to_v2i32 = vec_123->args[0]->As<ast::CallExpression>();
131   ASSERT_NE(v2u32_to_v2i32, nullptr);
132   ASSERT_TRUE(v2u32_to_v2i32->target.type->Is<ast::Vector>());
133   EXPECT_EQ(v2u32_to_v2i32->target.type->As<ast::Vector>()->width, 2u);
134   EXPECT_TRUE(
135       v2u32_to_v2i32->target.type->As<ast::Vector>()->type->Is<ast::I32>());
136   EXPECT_EQ(v2u32_to_v2i32->args.size(), 1u);
137   EXPECT_EQ(v2u32_to_v2i32->args[0], uvec_12);
138 
139   auto* u32_to_i32 = vec_123->args[1]->As<ast::CallExpression>();
140   ASSERT_NE(u32_to_i32, nullptr);
141   EXPECT_TRUE(u32_to_i32->target.type->Is<ast::I32>());
142   ASSERT_EQ(u32_to_i32->args.size(), 1u);
143   EXPECT_EQ(u32_to_i32->args[0], scalar_3);
144 
145   auto* call = Sem().Get(vec_123);
146   ASSERT_NE(call, nullptr);
147   ASSERT_EQ(call->Arguments().size(), 2u);
148   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
149   EXPECT_EQ(call->Arguments()[1], Sem().Get(u32_to_i32));
150 
151   auto* ctor = call->Target()->As<sem::TypeConstructor>();
152   ASSERT_NE(ctor, nullptr);
153   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
154   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
155   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
156   EXPECT_EQ(ctor->ReturnType(), call->Type());
157 
158   ASSERT_EQ(ctor->Parameters().size(), 2u);
159   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::Vector>());
160   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
161 }
162 
163 // AppendVector(vec2<i32>(1, 2), 3.0f) -> vec3<i32>(1, 2, i32(3.0f))
TEST_F(AppendVectorTest,Vec2i32_f32)164 TEST_F(AppendVectorTest, Vec2i32_f32) {
165   auto* scalar_1 = Expr(1);
166   auto* scalar_2 = Expr(2);
167   auto* scalar_3 = Expr(3.0f);
168   auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
169   WrapInFunction(vec_12, scalar_3);
170 
171   resolver::Resolver resolver(this);
172   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
173 
174   auto* append = AppendVector(this, vec_12, scalar_3);
175 
176   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
177   ASSERT_NE(vec_123, nullptr);
178   ASSERT_EQ(vec_123->args.size(), 3u);
179   EXPECT_EQ(vec_123->args[0], scalar_1);
180   EXPECT_EQ(vec_123->args[1], scalar_2);
181   auto* f32_to_i32 = vec_123->args[2]->As<ast::CallExpression>();
182   ASSERT_NE(f32_to_i32, nullptr);
183   EXPECT_TRUE(f32_to_i32->target.type->Is<ast::I32>());
184   ASSERT_EQ(f32_to_i32->args.size(), 1u);
185   EXPECT_EQ(f32_to_i32->args[0], scalar_3);
186 
187   auto* call = Sem().Get(vec_123);
188   ASSERT_NE(call, nullptr);
189   ASSERT_EQ(call->Arguments().size(), 3u);
190   EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
191   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_2));
192   EXPECT_EQ(call->Arguments()[2], Sem().Get(f32_to_i32));
193 
194   auto* ctor = call->Target()->As<sem::TypeConstructor>();
195   ASSERT_NE(ctor, nullptr);
196   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
197   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
198   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
199   EXPECT_EQ(ctor->ReturnType(), call->Type());
200 
201   ASSERT_EQ(ctor->Parameters().size(), 3u);
202   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
203   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
204   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
205 }
206 
207 // AppendVector(vec3<i32>(1, 2, 3), 4) -> vec4<i32>(1, 2, 3, 4)
TEST_F(AppendVectorTest,Vec3i32_i32)208 TEST_F(AppendVectorTest, Vec3i32_i32) {
209   auto* scalar_1 = Expr(1);
210   auto* scalar_2 = Expr(2);
211   auto* scalar_3 = Expr(3);
212   auto* scalar_4 = Expr(4);
213   auto* vec_123 = vec3<i32>(scalar_1, scalar_2, scalar_3);
214   WrapInFunction(vec_123, scalar_4);
215 
216   resolver::Resolver resolver(this);
217   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
218 
219   auto* append = AppendVector(this, vec_123, scalar_4);
220 
221   auto* vec_1234 = As<ast::CallExpression>(append->Declaration());
222   ASSERT_NE(vec_1234, nullptr);
223   ASSERT_EQ(vec_1234->args.size(), 4u);
224   EXPECT_EQ(vec_1234->args[0], scalar_1);
225   EXPECT_EQ(vec_1234->args[1], scalar_2);
226   EXPECT_EQ(vec_1234->args[2], scalar_3);
227   EXPECT_EQ(vec_1234->args[3], scalar_4);
228 
229   auto* call = Sem().Get(vec_1234);
230   ASSERT_NE(call, nullptr);
231   ASSERT_EQ(call->Arguments().size(), 4u);
232   EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
233   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_2));
234   EXPECT_EQ(call->Arguments()[2], Sem().Get(scalar_3));
235   EXPECT_EQ(call->Arguments()[3], Sem().Get(scalar_4));
236 
237   auto* ctor = call->Target()->As<sem::TypeConstructor>();
238   ASSERT_NE(ctor, nullptr);
239   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
240   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 4u);
241   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
242   EXPECT_EQ(ctor->ReturnType(), call->Type());
243 
244   ASSERT_EQ(ctor->Parameters().size(), 4u);
245   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
246   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
247   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
248   EXPECT_TRUE(ctor->Parameters()[3]->Type()->Is<sem::I32>());
249 }
250 
251 // AppendVector(vec_12, 3) -> vec3<i32>(vec_12, 3)
TEST_F(AppendVectorTest,Vec2i32Var_i32)252 TEST_F(AppendVectorTest, Vec2i32Var_i32) {
253   Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
254   auto* vec_12 = Expr("vec_12");
255   auto* scalar_3 = Expr(3);
256   WrapInFunction(vec_12, scalar_3);
257 
258   resolver::Resolver resolver(this);
259   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
260 
261   auto* append = AppendVector(this, vec_12, scalar_3);
262 
263   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
264   ASSERT_NE(vec_123, nullptr);
265   ASSERT_EQ(vec_123->args.size(), 2u);
266   EXPECT_EQ(vec_123->args[0], vec_12);
267   EXPECT_EQ(vec_123->args[1], scalar_3);
268 
269   auto* call = Sem().Get(vec_123);
270   ASSERT_NE(call, nullptr);
271   ASSERT_EQ(call->Arguments().size(), 2u);
272   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
273   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_3));
274 
275   auto* ctor = call->Target()->As<sem::TypeConstructor>();
276   ASSERT_NE(ctor, nullptr);
277   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
278   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
279   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
280   EXPECT_EQ(ctor->ReturnType(), call->Type());
281 
282   ASSERT_EQ(ctor->Parameters().size(), 2u);
283   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::Vector>());
284   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
285 }
286 
287 // AppendVector(1, 2, scalar_3) -> vec3<i32>(1, 2, scalar_3)
TEST_F(AppendVectorTest,Vec2i32_i32Var)288 TEST_F(AppendVectorTest, Vec2i32_i32Var) {
289   Global("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
290   auto* scalar_1 = Expr(1);
291   auto* scalar_2 = Expr(2);
292   auto* scalar_3 = Expr("scalar_3");
293   auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
294   WrapInFunction(vec_12, scalar_3);
295 
296   resolver::Resolver resolver(this);
297   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
298 
299   auto* append = AppendVector(this, vec_12, scalar_3);
300 
301   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
302   ASSERT_NE(vec_123, nullptr);
303   ASSERT_EQ(vec_123->args.size(), 3u);
304   EXPECT_EQ(vec_123->args[0], scalar_1);
305   EXPECT_EQ(vec_123->args[1], scalar_2);
306   EXPECT_EQ(vec_123->args[2], scalar_3);
307 
308   auto* call = Sem().Get(vec_123);
309   ASSERT_NE(call, nullptr);
310   ASSERT_EQ(call->Arguments().size(), 3u);
311   EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
312   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_2));
313   EXPECT_EQ(call->Arguments()[2], Sem().Get(scalar_3));
314 
315   auto* ctor = call->Target()->As<sem::TypeConstructor>();
316   ASSERT_NE(ctor, nullptr);
317   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
318   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
319   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
320   EXPECT_EQ(ctor->ReturnType(), call->Type());
321 
322   ASSERT_EQ(ctor->Parameters().size(), 3u);
323   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
324   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
325   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
326 }
327 
328 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, scalar_3)
TEST_F(AppendVectorTest,Vec2i32Var_i32Var)329 TEST_F(AppendVectorTest, Vec2i32Var_i32Var) {
330   Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
331   Global("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
332   auto* vec_12 = Expr("vec_12");
333   auto* scalar_3 = Expr("scalar_3");
334   WrapInFunction(vec_12, scalar_3);
335 
336   resolver::Resolver resolver(this);
337   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
338 
339   auto* append = AppendVector(this, vec_12, scalar_3);
340 
341   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
342   ASSERT_NE(vec_123, nullptr);
343   ASSERT_EQ(vec_123->args.size(), 2u);
344   EXPECT_EQ(vec_123->args[0], vec_12);
345   EXPECT_EQ(vec_123->args[1], scalar_3);
346 
347   auto* call = Sem().Get(vec_123);
348   ASSERT_NE(call, nullptr);
349   ASSERT_EQ(call->Arguments().size(), 2u);
350   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
351   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_3));
352 
353   auto* ctor = call->Target()->As<sem::TypeConstructor>();
354   ASSERT_NE(ctor, nullptr);
355   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
356   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
357   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
358   EXPECT_EQ(ctor->ReturnType(), call->Type());
359 
360   ASSERT_EQ(ctor->Parameters().size(), 2u);
361   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::Vector>());
362   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
363 }
364 
365 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, i32(scalar_3))
TEST_F(AppendVectorTest,Vec2i32Var_f32Var)366 TEST_F(AppendVectorTest, Vec2i32Var_f32Var) {
367   Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
368   Global("scalar_3", ty.f32(), ast::StorageClass::kPrivate);
369   auto* vec_12 = Expr("vec_12");
370   auto* scalar_3 = Expr("scalar_3");
371   WrapInFunction(vec_12, scalar_3);
372 
373   resolver::Resolver resolver(this);
374   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
375 
376   auto* append = AppendVector(this, vec_12, scalar_3);
377 
378   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
379   ASSERT_NE(vec_123, nullptr);
380   ASSERT_EQ(vec_123->args.size(), 2u);
381   EXPECT_EQ(vec_123->args[0], vec_12);
382   auto* f32_to_i32 = vec_123->args[1]->As<ast::CallExpression>();
383   ASSERT_NE(f32_to_i32, nullptr);
384   EXPECT_TRUE(f32_to_i32->target.type->Is<ast::I32>());
385   ASSERT_EQ(f32_to_i32->args.size(), 1u);
386   EXPECT_EQ(f32_to_i32->args[0], scalar_3);
387 
388   auto* call = Sem().Get(vec_123);
389   ASSERT_NE(call, nullptr);
390   ASSERT_EQ(call->Arguments().size(), 2u);
391   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
392   EXPECT_EQ(call->Arguments()[1], Sem().Get(f32_to_i32));
393 
394   auto* ctor = call->Target()->As<sem::TypeConstructor>();
395   ASSERT_NE(ctor, nullptr);
396   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
397   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
398   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
399   EXPECT_EQ(ctor->ReturnType(), call->Type());
400 
401   ASSERT_EQ(ctor->Parameters().size(), 2u);
402   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::Vector>());
403   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
404 }
405 
406 // AppendVector(vec_12, scalar_3) -> vec3<bool>(vec_12, scalar_3)
TEST_F(AppendVectorTest,Vec2boolVar_boolVar)407 TEST_F(AppendVectorTest, Vec2boolVar_boolVar) {
408   Global("vec_12", ty.vec2<bool>(), ast::StorageClass::kPrivate);
409   Global("scalar_3", ty.bool_(), ast::StorageClass::kPrivate);
410   auto* vec_12 = Expr("vec_12");
411   auto* scalar_3 = Expr("scalar_3");
412   WrapInFunction(vec_12, scalar_3);
413 
414   resolver::Resolver resolver(this);
415   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
416 
417   auto* append = AppendVector(this, vec_12, scalar_3);
418 
419   auto* vec_123 = As<ast::CallExpression>(append->Declaration());
420   ASSERT_NE(vec_123, nullptr);
421   ASSERT_EQ(vec_123->args.size(), 2u);
422   EXPECT_EQ(vec_123->args[0], vec_12);
423   EXPECT_EQ(vec_123->args[1], scalar_3);
424 
425   auto* call = Sem().Get(vec_123);
426   ASSERT_NE(call, nullptr);
427   ASSERT_EQ(call->Arguments().size(), 2u);
428   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
429   EXPECT_EQ(call->Arguments()[1], Sem().Get(scalar_3));
430 
431   auto* ctor = call->Target()->As<sem::TypeConstructor>();
432   ASSERT_NE(ctor, nullptr);
433   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
434   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 3u);
435   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::Bool>());
436   EXPECT_EQ(ctor->ReturnType(), call->Type());
437 
438   ASSERT_EQ(ctor->Parameters().size(), 2u);
439   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::Vector>());
440   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::Bool>());
441 }
442 
443 // AppendVector(vec3<i32>(), 4) -> vec3<bool>(0, 0, 0, 4)
TEST_F(AppendVectorTest,ZeroVec3i32_i32)444 TEST_F(AppendVectorTest, ZeroVec3i32_i32) {
445   auto* scalar = Expr(4);
446   auto* vec000 = vec3<i32>();
447   WrapInFunction(vec000, scalar);
448 
449   resolver::Resolver resolver(this);
450   ASSERT_TRUE(resolver.Resolve()) << resolver.error();
451 
452   auto* append = AppendVector(this, vec000, scalar);
453 
454   auto* vec_0004 = As<ast::CallExpression>(append->Declaration());
455   ASSERT_NE(vec_0004, nullptr);
456   ASSERT_EQ(vec_0004->args.size(), 4u);
457   for (size_t i = 0; i < 3; i++) {
458     auto* literal = As<ast::SintLiteralExpression>(vec_0004->args[i]);
459     ASSERT_NE(literal, nullptr);
460     EXPECT_EQ(literal->value, 0);
461   }
462   EXPECT_EQ(vec_0004->args[3], scalar);
463 
464   auto* call = Sem().Get(vec_0004);
465   ASSERT_NE(call, nullptr);
466   ASSERT_EQ(call->Arguments().size(), 4u);
467   EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_0004->args[0]));
468   EXPECT_EQ(call->Arguments()[1], Sem().Get(vec_0004->args[1]));
469   EXPECT_EQ(call->Arguments()[2], Sem().Get(vec_0004->args[2]));
470   EXPECT_EQ(call->Arguments()[3], Sem().Get(scalar));
471 
472   auto* ctor = call->Target()->As<sem::TypeConstructor>();
473   ASSERT_NE(ctor, nullptr);
474   ASSERT_TRUE(ctor->ReturnType()->Is<sem::Vector>());
475   EXPECT_EQ(ctor->ReturnType()->As<sem::Vector>()->Width(), 4u);
476   EXPECT_TRUE(ctor->ReturnType()->As<sem::Vector>()->type()->Is<sem::I32>());
477   EXPECT_EQ(ctor->ReturnType(), call->Type());
478 
479   ASSERT_EQ(ctor->Parameters().size(), 4u);
480   EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
481   EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::I32>());
482   EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::I32>());
483   EXPECT_TRUE(ctor->Parameters()[3]->Type()->Is<sem::I32>());
484 }
485 
486 }  // namespace
487 }  // namespace writer
488 }  // namespace tint
489