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