1const std = @import("std");
2const builtin = @import("builtin");
3const mem = std.mem;
4const math = std.math;
5const assert = std.debug.assert;
6const expect = std.testing.expect;
7const expectEqual = std.testing.expectEqual;
8
9test "implicit cast vector to array - bool" {
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
12
13 const S = struct {
14 fn doTheTest() !void {
15 {
16 var v: @Vector(4, bool) = undefined;
17 v = .{ true, false, true, false };
18 const a: [4]bool = v;
19 try expect(mem.eql(bool, &a, &.{ true, false, true, false }));
20 }
21 {
22 var v: @Vector(25, bool) = undefined;
23 v = .{ false, false, false, false, true, true, false, false, false, true, false, true, false, false, true, false, false, true, false, false, true, true, true, false, false };
24 const a: [25]bool = v;
25 try expect(mem.eql(bool, &a, &.{ false, false, false, false, true, true, false, false, false, true, false, true, false, false, true, false, false, true, false, false, true, true, true, false, false }));
26 }
27 }
28 };
29 try S.doTheTest();
30 try comptime S.doTheTest();
31}
32
33test "implicit cast array to vector - bool" {
34 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
36
37 const S = struct {
38 fn doTheTest() !void {
39 {
40 var a: [4]bool = undefined;
41 a = .{ true, false, false, true };
42 const v: @Vector(4, bool) = a;
43 try expect(mem.eql(bool, &@as([4]bool, v), &.{ true, false, false, true }));
44 }
45 {
46 var a: [25]bool = undefined;
47 a = .{ true, false, false, true, false, false, false, false, false, true, true, true, true, false, false, false, false, true, false, false, false, true, true, true, false };
48 const v: @Vector(25, bool) = a;
49 try expect(mem.eql(bool, &@as([25]bool, v), &.{ true, false, false, true, false, false, false, false, false, true, true, true, true, false, false, false, false, true, false, false, false, true, true, true, false }));
50 }
51 }
52 };
53 try S.doTheTest();
54 try comptime S.doTheTest();
55}
56
57test "vector wrap operators" {
58 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
62 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
63
64 const S = struct {
65 fn doTheTest() !void {
66 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
67 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
68 try expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 }));
69 try expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 }));
70 try expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 }));
71 var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };
72 try expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 }));
73 _ = .{ &v, &x, &z };
74 }
75 };
76 try S.doTheTest();
77 try comptime S.doTheTest();
78}
79
80test "vector bin compares with mem.eql" {
81 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
82 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
85 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
86
87 const S = struct {
88 fn doTheTest() !void {
89 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
90 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };
91 _ = .{ &v, &x };
92 try expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false }));
93 try expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true }));
94 try expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false }));
95 try expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true }));
96 try expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false }));
97 try expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true }));
98 }
99 };
100 try S.doTheTest();
101 try comptime S.doTheTest();
102}
103
104test "vector int operators" {
105 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
107 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
108 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
110
111 const S = struct {
112 fn doTheTest() !void {
113 var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
114 var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
115 _ = .{ &v, &x };
116 try expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 }));
117 try expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 }));
118 try expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 }));
119 try expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 }));
120 }
121 };
122 try S.doTheTest();
123 try comptime S.doTheTest();
124}
125
126test "vector float operators" {
127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
130 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
131
132 const S = struct {
133 fn doTheTest(T: type) !void {
134 var v: @Vector(4, T) = .{ 10, 20, 30, 40 };
135 var x: @Vector(4, T) = .{ 1, 2, 3, 4 };
136 _ = .{ &v, &x };
137 try expectEqual(v + x, .{ 11, 22, 33, 44 });
138 try expectEqual(v - x, .{ 9, 18, 27, 36 });
139 try expectEqual(v * x, .{ 10, 40, 90, 160 });
140 if (builtin.zig_backend != .stage2_riscv64) try expectEqual(-x, .{ -1, -2, -3, -4 });
141 }
142 };
143
144 try S.doTheTest(f32);
145 try comptime S.doTheTest(f32);
146
147 try S.doTheTest(f64);
148 try comptime S.doTheTest(f64);
149
150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
151
152 try S.doTheTest(f16);
153 try comptime S.doTheTest(f16);
154
155 try S.doTheTest(f80);
156 try comptime S.doTheTest(f80);
157
158 try S.doTheTest(f128);
159 try comptime S.doTheTest(f128);
160}
161
162test "vector bit operators" {
163 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
164 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
167 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
168
169 const S = struct {
170 fn doTheTest() !void {
171 {
172 var v: @Vector(4, bool) = [4]bool{ false, false, true, true };
173 var x: @Vector(4, bool) = [4]bool{ true, false, true, false };
174 _ = .{ &v, &x };
175 try expect(mem.eql(bool, &@as([4]bool, v ^ x), &[4]bool{ true, false, false, true }));
176 try expect(mem.eql(bool, &@as([4]bool, v | x), &[4]bool{ true, false, true, true }));
177 try expect(mem.eql(bool, &@as([4]bool, v & x), &[4]bool{ false, false, true, false }));
178 }
179 {
180 var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
181 var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
182 _ = .{ &v, &x };
183 try expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
184 try expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
185 try expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
186 }
187 }
188 };
189 try S.doTheTest();
190 try comptime S.doTheTest();
191}
192
193test "implicit cast vector to array" {
194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
195 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
197 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
198 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
199
200 const S = struct {
201 fn doTheTest() !void {
202 var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
203 _ = &a;
204 var result_array: [4]i32 = a;
205 result_array = a;
206 try expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 }));
207 }
208 };
209 try S.doTheTest();
210 try comptime S.doTheTest();
211}
212
213test "array to vector" {
214 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
215 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
217 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
218
219 const S = struct {
220 fn doTheTest() !void {
221 var foo: f32 = 3.14;
222 _ = &foo;
223 const arr = [4]f32{ foo, 1.5, 0.0, 0.0 };
224 const vec: @Vector(4, f32) = arr;
225 try expect(mem.eql(f32, &@as([4]f32, vec), &arr));
226 }
227 };
228 try S.doTheTest();
229 try comptime S.doTheTest();
230}
231
232test "array of abi-sized integer to vector of same type" {
233 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
234 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
235 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
236 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
237
238 const S = struct {
239 const one: u32 = 1;
240 const two: u32 = 2;
241
242 fn doTheTest() !void {
243 {
244 var arr: [8]u8 = .{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
245 const vec: @Vector(8, u8) = arr;
246 arr[0] = 0; // should not affect `vec`
247 try expect(vec[0] == 0x01);
248 try expect(vec[1] == 0x23);
249 try expect(vec[2] == 0x45);
250 try expect(vec[3] == 0x67);
251 try expect(vec[4] == 0x89);
252 try expect(vec[5] == 0xAB);
253 try expect(vec[6] == 0xCD);
254 try expect(vec[7] == 0xEF);
255 }
256
257 {
258 var arr: [4]u16 = .{ 0x0123, 0x4567, 0x89AB, 0xCDEF };
259 const vec: @Vector(4, u16) = arr;
260 arr[0] = 0; // should not affect `vec`
261 try expect(vec[0] == 0x0123);
262 try expect(vec[1] == 0x4567);
263 try expect(vec[2] == 0x89AB);
264 try expect(vec[3] == 0xCDEF);
265 }
266
267 {
268 var arr: [2]u32 = .{ 0x01234567, 0x89ABCDEF };
269 const vec: @Vector(2, u32) = arr;
270 arr[0] = 0; // should not affect `vec`
271 try expect(vec[0] == 0x01234567);
272 try expect(vec[1] == 0x89ABCDEF);
273 }
274
275 {
276 var arr: [1]u64 = .{0x0123456789ABCDEF};
277 const vec: @Vector(1, u64) = arr;
278 arr[0] = 0; // should not affect `vec`
279 try expect(vec[0] == 0x0123456789ABCDEF);
280 }
281
282 // Like the u16 case, but a non-power-of-two size.
283 {
284 var arr: [5]u16 = .{ 0x0123, 0x4567, 0x89AB, 0xCDEF, 0xDEAD };
285 const vec: @Vector(5, u16) = arr;
286 arr[0] = 0; // should not affect `vec`
287 try expect(vec[0] == 0x0123);
288 try expect(vec[1] == 0x4567);
289 try expect(vec[2] == 0x89AB);
290 try expect(vec[3] == 0xCDEF);
291 try expect(vec[4] == 0xDEAD);
292 }
293
294 // Like the u32 case, but a non-power-of-two size.
295 {
296 var arr: [3]u32 = .{ 0x01234567, 0x89ABCDEF, 0xDEADBEEF };
297 const vec: @Vector(3, u32) = arr;
298 arr[0] = 0; // should not affect `vec`
299 try expect(vec[0] == 0x01234567);
300 try expect(vec[1] == 0x89ABCDEF);
301 try expect(vec[2] == 0xDEADBEEF);
302 }
303
304 {
305 var arr: [2]*const u32 = .{ &one, &two };
306 const vec: @Vector(2, *const u32) = arr;
307 arr[0] = &two; // should not affect `vec`
308 try expect(vec[0] == &one);
309 try expect(vec[1] == &two);
310 }
311 }
312 };
313 try S.doTheTest();
314 try comptime S.doTheTest();
315}
316
317test "array of float to vector of same type" {
318 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
322 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
323
324 const S = struct {
325 fn doTheTest() !void {
326 {
327 var arr: [4]f16 = .{ 1.5, 2.5, 3.5, 4.5 };
328 const vec: @Vector(4, f16) = arr;
329 arr[0] = 0; // should not affect `vec`
330 try expect(vec[0] == 1.5);
331 try expect(vec[1] == 2.5);
332 try expect(vec[2] == 3.5);
333 try expect(vec[3] == 4.5);
334 }
335
336 {
337 var arr: [4]f32 = .{ 1.5, 2.5, 3.5, 4.5 };
338 const vec: @Vector(4, f32) = arr;
339 arr[0] = 0; // should not affect `vec`
340 try expect(vec[0] == 1.5);
341 try expect(vec[1] == 2.5);
342 try expect(vec[2] == 3.5);
343 try expect(vec[3] == 4.5);
344 }
345
346 {
347 var arr: [4]f64 = .{ 1.5, 2.5, 3.5, 4.5 };
348 const vec: @Vector(4, f64) = arr;
349 arr[0] = 0; // should not affect `vec`
350 try expect(vec[0] == 1.5);
351 try expect(vec[1] == 2.5);
352 try expect(vec[2] == 3.5);
353 try expect(vec[3] == 4.5);
354 }
355
356 {
357 var arr: [2]f80 = .{ 1.5, 2.5 };
358 const vec: @Vector(2, f80) = arr;
359 arr[0] = 0; // should not affect `vec`
360 try expect(vec[0] == 1.5);
361 try expect(vec[1] == 2.5);
362 }
363
364 {
365 var arr: [2]f128 = .{ 3.5, 4.5 };
366 const vec: @Vector(2, f128) = arr;
367 arr[0] = 0; // should not affect `vec`
368 try expect(vec[0] == 3.5);
369 try expect(vec[1] == 4.5);
370 }
371 }
372 };
373 try S.doTheTest();
374 try comptime S.doTheTest();
375}
376
377test "array of non-abi-sized integer to vector of same type" {
378 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
379 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
382
383 const S = struct {
384 fn doTheTest() !void {
385 {
386 var arr: [5]bool = .{ false, true, false, true, true };
387 const vec: @Vector(5, bool) = arr;
388 arr[0] = true; // should not affect `vec`
389 try expect(vec[0] == false);
390 try expect(vec[1] == true);
391 try expect(vec[2] == false);
392 try expect(vec[3] == true);
393 try expect(vec[4] == true);
394 }
395
396 {
397 var arr: [4]u1 = .{ 1, 0, 1, 1 };
398 const vec: @Vector(4, u1) = arr;
399 arr[0] = 0; // should not affect `vec`
400 try expect(vec[0] == 1);
401 try expect(vec[1] == 0);
402 try expect(vec[2] == 1);
403 try expect(vec[3] == 1);
404 }
405
406 {
407 var arr: [4]u3 = .{ 0, 3, 5, 7 };
408 const vec: @Vector(4, u3) = arr;
409 arr[0] = 1; // should not affect `vec`
410 try expect(vec[0] == 0);
411 try expect(vec[1] == 3);
412 try expect(vec[2] == 5);
413 try expect(vec[3] == 7);
414 }
415
416 {
417 var arr: [3]u24 = .{ 0x010203, 0x040506, 0xFF0000 };
418 const vec: @Vector(3, u24) = arr;
419 arr[0] = 0; // should not affect `vec`
420 try expect(vec[0] == 0x010203);
421 try expect(vec[1] == 0x040506);
422 try expect(vec[2] == 0xFF0000);
423 }
424 }
425 };
426 try S.doTheTest();
427 try comptime S.doTheTest();
428}
429
430test "array vector coercion - odd sizes" {
431 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
434 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
435
436 const S = struct {
437 fn doTheTest() !void {
438 var foo1: i48 = 124578;
439 _ = &foo1;
440 const vec1: @Vector(2, i48) = [2]i48{ foo1, 1 };
441 const arr1: [2]i48 = vec1;
442 try expect(vec1[0] == foo1 and vec1[1] == 1);
443 try expect(arr1[0] == foo1 and arr1[1] == 1);
444
445 var foo2: u4 = 5;
446 _ = &foo2;
447 const vec2: @Vector(2, u4) = [2]u4{ foo2, 1 };
448 const arr2: [2]u4 = vec2;
449 try expect(vec2[0] == foo2 and vec2[1] == 1);
450 try expect(arr2[0] == foo2 and arr2[1] == 1);
451
452 var foo3: u13 = 13;
453 _ = &foo3;
454 const vec3: @Vector(3, u13) = [3]u13{ foo3, 0, 1 };
455 const arr3: [3]u13 = vec3;
456 try expect(vec3[0] == foo3 and vec3[1] == 0 and vec3[2] == 1);
457 try expect(arr3[0] == foo3 and arr3[1] == 0 and arr3[2] == 1);
458
459 const arr4 = [4:0]u24{ foo3, foo2, 0, 1 };
460 const vec4: @Vector(4, u24) = arr4;
461 try expect(vec4[0] == foo3 and vec4[1] == foo2 and vec4[2] == 0 and vec4[3] == 1);
462 }
463 };
464 try S.doTheTest();
465 try comptime S.doTheTest();
466}
467
468test "array to vector with element type coercion" {
469 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
471 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
472 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
473 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
474
475 const S = struct {
476 fn doTheTest() !void {
477 var foo: f16 = 3.14;
478 _ = &foo;
479 const arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 };
480 const vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 };
481 try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32));
482 }
483 };
484 try S.doTheTest();
485 try comptime S.doTheTest();
486}
487
488test "peer type resolution with coercible element types" {
489 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
490 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
491
492 const S = struct {
493 fn doTheTest() !void {
494 var b: @Vector(2, u8) = .{ 1, 2 };
495 var a: @Vector(2, u16) = .{ 2, 1 };
496 var t: bool = true;
497 _ = .{ &a, &b, &t };
498 const c = if (t) a else b;
499 try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
500 }
501 };
502 try comptime S.doTheTest();
503}
504
505test "tuple to vector" {
506 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
510 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
511
512 const S = struct {
513 fn doTheTest() !void {
514 const Vec3 = @Vector(3, i32);
515 var v: Vec3 = .{ 1, 0, 0 };
516 for ([_]Vec3{ .{ 0, 1, 0 }, .{ 0, 0, 1 } }) |it| {
517 v += it;
518 }
519
520 try std.testing.expectEqual(v, Vec3{ 1, 1, 1 });
521 try std.testing.expectEqual(v, .{ 1, 1, 1 });
522 }
523 };
524 try S.doTheTest();
525 try comptime S.doTheTest();
526}
527
528test "vector casts of sizes not divisible by 8" {
529 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
530 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
531 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
532 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
533 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
534
535 const S = struct {
536 fn doTheTest() !void {
537 {
538 var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };
539 _ = &v;
540 const x: [4]u3 = v;
541 try expect(mem.eql(u3, &x, &@as([4]u3, v)));
542 }
543 {
544 var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };
545 _ = &v;
546 const x: [4]u2 = v;
547 try expect(mem.eql(u2, &x, &@as([4]u2, v)));
548 }
549 {
550 var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };
551 _ = &v;
552 const x: [4]u1 = v;
553 try expect(mem.eql(u1, &x, &@as([4]u1, v)));
554 }
555 {
556 var v: @Vector(4, bool) = [4]bool{ false, false, true, false };
557 _ = &v;
558 const x: [4]bool = v;
559 try expect(mem.eql(bool, &x, &@as([4]bool, v)));
560 }
561 }
562 };
563 try S.doTheTest();
564 try comptime S.doTheTest();
565}
566
567test "load vector elements via comptime index" {
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
569 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
570
571 const S = struct {
572 fn doTheTest() !void {
573 var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
574 try expect(v[0] == 1);
575 try expect(v[1] == 2);
576 try expect(loadv(&v[2]) == 3);
577 }
578 fn loadv(ptr: anytype) i32 {
579 return ptr.*;
580 }
581 };
582
583 try S.doTheTest();
584 try comptime S.doTheTest();
585}
586
587test "store vector elements via comptime index" {
588 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
589 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
590
591 const S = struct {
592 fn doTheTest() !void {
593 var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
594
595 v[2] = 42;
596 try expect(v[1] == 5);
597 v[3] = -364;
598 try expect(v[2] == 42);
599 try expect(-364 == v[3]);
600
601 storev(&v[0], 100);
602 try expect(v[0] == 100);
603 }
604 fn storev(ptr: anytype, x: i32) void {
605 ptr.* = x;
606 }
607 };
608
609 try S.doTheTest();
610 try comptime S.doTheTest();
611}
612
613test "initialize vector which is a struct field" {
614 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
615 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
616
617 const Vec4Obj = struct {
618 data: @Vector(4, f32),
619 };
620
621 const S = struct {
622 fn doTheTest() !void {
623 var foo = Vec4Obj{
624 .data = [_]f32{ 1, 2, 3, 4 },
625 };
626 _ = &foo;
627 }
628 };
629 try S.doTheTest();
630 try comptime S.doTheTest();
631}
632
633test "vector comparison operators" {
634 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
635 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
636 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
637 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
638 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
639
640 const S = struct {
641 fn doTheTest() !void {
642 {
643 const V = @Vector(4, bool);
644 var v1: V = [_]bool{ true, false, true, false };
645 var v2: V = [_]bool{ false, true, false, true };
646 _ = .{ &v1, &v2 };
647 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v1)));
648 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v2)));
649 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v2)));
650 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v2 != v2)));
651 }
652 {
653 const V = @Vector(4, bool);
654 var v1: @Vector(4, u32) = @splat(0xc0ffeeee);
655 var v2: @Vector(4, c_uint) = v1;
656 var v3: @Vector(4, u32) = @splat(0xdeadbeef);
657 _ = .{ &v1, &v2, &v3 };
658 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v2)));
659 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v3)));
660 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v3)));
661 try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 != v2)));
662 }
663 {
664 // Comptime-known LHS/RHS
665 var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 };
666 _ = &v1;
667 const v2: @Vector(4, u32) = @splat(2);
668 const v3: @Vector(4, bool) = [_]bool{ true, false, true, false };
669 try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v1 == v2)));
670 try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v2 == v1)));
671 }
672 }
673 };
674 try S.doTheTest();
675 try comptime S.doTheTest();
676}
677
678test "vector division operators" {
679 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
680 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
681 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
682 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
683 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
684
685 const S = struct {
686 fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
687 const is_signed_int = switch (@typeInfo(T)) {
688 .int => |info| info.signedness == .signed,
689 else => false,
690 };
691 if (!is_signed_int) {
692 const d0 = x / y;
693 inline for (@as([4]T, d0), 0..) |v, i| {
694 try expect(x[i] / y[i] == v);
695 }
696 }
697 const d1 = @divExact(x, y);
698 inline for (@as([4]T, d1), 0..) |v, i| {
699 try expect(@divExact(x[i], y[i]) == v);
700 }
701 const d2 = @divFloor(x, y);
702 inline for (@as([4]T, d2), 0..) |v, i| {
703 try expect(@divFloor(x[i], y[i]) == v);
704 }
705 const d3 = @divCeil(x, y);
706 inline for (@as([4]T, d3), 0..) |v, i| {
707 try expect(@divCeil(x[i], y[i]) == v);
708 }
709 const d4 = @divTrunc(x, y);
710 inline for (@as([4]T, d4), 0..) |v, i| {
711 try expect(@divTrunc(x[i], y[i]) == v);
712 }
713 }
714
715 fn doTheTestDivNoExact(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
716 const is_signed_int = switch (@typeInfo(T)) {
717 .int => |info| info.signedness == .signed,
718 else => false,
719 };
720 if (!is_signed_int) {
721 const d0 = x / y;
722 inline for (@as([4]T, d0), 0..) |v, i| {
723 try expect(x[i] / y[i] == v);
724 }
725 }
726 const d2 = @divFloor(x, y);
727 inline for (@as([4]T, d2), 0..) |v, i| {
728 try expect(@divFloor(x[i], y[i]) == v);
729 }
730 const d3 = @divCeil(x, y);
731 inline for (@as([4]T, d3), 0..) |v, i| {
732 try expect(@divCeil(x[i], y[i]) == v);
733 }
734 const d4 = @divTrunc(x, y);
735 inline for (@as([4]T, d4), 0..) |v, i| {
736 try expect(@divTrunc(x[i], y[i]) == v);
737 }
738 }
739
740 fn doTheTestMod(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
741 const is_signed_int = switch (@typeInfo(T)) {
742 .int => |info| info.signedness == .signed,
743 else => false,
744 };
745 if (!is_signed_int and @typeInfo(T) != .float) {
746 const r0 = x % y;
747 inline for (@as([4]T, r0), 0..) |v, i| {
748 try expect(x[i] % y[i] == v);
749 }
750 }
751 const r1 = @mod(x, y);
752 inline for (@as([4]T, r1), 0..) |v, i| {
753 try expect(@mod(x[i], y[i]) == v);
754 }
755 const r2 = @rem(x, y);
756 inline for (@as([4]T, r2), 0..) |v, i| {
757 try expect(@rem(x[i], y[i]) == v);
758 }
759 }
760
761 fn doTheTest() !void {
762 try doTheTestDiv(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, -1.0, -2.0 });
763
764 try doTheTestDiv(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, -1.0, -2.0 });
765 try doTheTestDiv(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, -1.0, -2.0 });
766
767 try doTheTestMod(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, 0.5, 3.0 });
768 try doTheTestMod(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, 0.5, 3.0 });
769 try doTheTestMod(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, 0.5, 3.0 });
770
771 try doTheTestDiv(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, -1, -2 });
772 try doTheTestDiv(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, -1, -2 });
773 try doTheTestDiv(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, -1, -2 });
774 try doTheTestDiv(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, -1, -2 });
775
776 try doTheTestMod(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, 4, 8 });
777 try doTheTestMod(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, 4, 8 });
778 try doTheTestMod(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, 4, 8 });
779 try doTheTestMod(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, 4, 8 });
780
781 try doTheTestDiv(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
782 try doTheTestDiv(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
783 try doTheTestDiv(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
784 try doTheTestDiv(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
785
786 try doTheTestMod(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
787 try doTheTestMod(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
788 try doTheTestMod(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
789 try doTheTestMod(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
790
791 try doTheTestDivNoExact(u64, [4]u64{ 4, 5, 6, 7 }, [4]u64{ 4, 4, 4, 4 });
792 try doTheTestDivNoExact(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 3, 3, -3, -3 });
793 }
794 };
795
796 try comptime S.doTheTest();
797 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
798 try S.doTheTest();
799}
800
801test "vector bitwise not operator" {
802 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
803 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
804 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
805 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
806
807 const S = struct {
808 fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void {
809 const y = ~x;
810 inline for (@as([4]T, y), 0..) |v, i| {
811 try expect(~x[i] == v);
812 }
813 }
814 fn doTheTest() !void {
815 try doTheTestNot(bool, [_]bool{ true, false, true, false });
816
817 try doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
818 try doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
819 try doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
820 try doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
821
822 try doTheTestNot(i8, [_]i8{ 0, 2, 4, 127 });
823 try doTheTestNot(i16, [_]i16{ 0, 2, 4, 127 });
824 try doTheTestNot(i32, [_]i32{ 0, 2, 4, 127 });
825 try doTheTestNot(i64, [_]i64{ 0, 2, 4, 127 });
826 }
827 };
828
829 try S.doTheTest();
830 try comptime S.doTheTest();
831}
832
833test "vector boolean not operator" {
834 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
835 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
836 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
837 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
838
839 const S = struct {
840 fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void {
841 const y = !x;
842 inline for (@as([4]T, y), 0..) |v, i| {
843 try expect(!x[i] == v);
844 }
845 }
846 fn doTheTest() !void {
847 try doTheTestNot(bool, [_]bool{ true, false, true, false });
848 }
849 };
850
851 try S.doTheTest();
852 try comptime S.doTheTest();
853}
854
855test "vector shift operators" {
856 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
857 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
858 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
859 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
860 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
861
862 const S = struct {
863 fn doTheTestShift(x: anytype, y: anytype) !void {
864 const N = @typeInfo(@TypeOf(x)).array.len;
865 const TX = @typeInfo(@TypeOf(x)).array.child;
866 const TY = @typeInfo(@TypeOf(y)).array.child;
867
868 const xv = @as(@Vector(N, TX), x);
869 const yv = @as(@Vector(N, TY), y);
870
871 const z0 = xv >> yv;
872 for (@as([N]TX, z0), 0..) |v, i| {
873 try expect(x[i] >> y[i] == v);
874 }
875 const z1 = xv << yv;
876 for (@as([N]TX, z1), 0..) |v, i| {
877 try expect(x[i] << y[i] == v);
878 }
879 }
880 fn doTheTestShiftExact(x: anytype, y: anytype, dir: enum { Left, Right }) !void {
881 const N = @typeInfo(@TypeOf(x)).array.len;
882 const TX = @typeInfo(@TypeOf(x)).array.child;
883 const TY = @typeInfo(@TypeOf(y)).array.child;
884
885 const xv = @as(@Vector(N, TX), x);
886 const yv = @as(@Vector(N, TY), y);
887
888 const z = if (dir == .Left) @shlExact(xv, yv) else @shrExact(xv, yv);
889 for (@as([N]TX, z), 0..) |v, i| {
890 const check = if (dir == .Left) x[i] << y[i] else x[i] >> y[i];
891 try expect(check == v);
892 }
893 }
894 fn doTheTest() !void {
895 try doTheTestShift([_]u8{ 0, 2, 4, math.maxInt(u8) }, [_]u3{ 2, 0, 2, 7 });
896 try doTheTestShift([_]u16{ 0, 2, 4, math.maxInt(u16) }, [_]u4{ 2, 0, 2, 15 });
897 try doTheTestShift([_]u24{ 0, 2, 4, math.maxInt(u24) }, [_]u5{ 2, 0, 2, 23 });
898 try doTheTestShift([_]u32{ 0, 2, 4, math.maxInt(u32) }, [_]u5{ 2, 0, 2, 31 });
899 try doTheTestShift([_]u64{ 0xfe, math.maxInt(u64) }, [_]u6{ 0, 63 });
900
901 try doTheTestShift([_]i8{ 0, 2, 4, math.maxInt(i8) }, [_]u3{ 2, 0, 2, 7 });
902 try doTheTestShift([_]i16{ 0, 2, 4, math.maxInt(i16) }, [_]u4{ 2, 0, 2, 7 });
903 try doTheTestShift([_]i24{ 0, 2, 4, math.maxInt(i24) }, [_]u5{ 2, 0, 2, 7 });
904 try doTheTestShift([_]i32{ 0, 2, 4, math.maxInt(i32) }, [_]u5{ 2, 0, 2, 7 });
905 try doTheTestShift([_]i64{ 0xfe, math.maxInt(i64) }, [_]u6{ 0, 63 });
906
907 try doTheTestShiftExact([_]u8{ 0, 1, 1 << 7, math.maxInt(u8) ^ 1 }, [_]u3{ 4, 0, 7, 1 }, .Right);
908 try doTheTestShiftExact([_]u16{ 0, 1, 1 << 15, math.maxInt(u16) ^ 1 }, [_]u4{ 4, 0, 15, 1 }, .Right);
909 try doTheTestShiftExact([_]u24{ 0, 1, 1 << 23, math.maxInt(u24) ^ 1 }, [_]u5{ 4, 0, 23, 1 }, .Right);
910 try doTheTestShiftExact([_]u32{ 0, 1, 1 << 31, math.maxInt(u32) ^ 1 }, [_]u5{ 4, 0, 31, 1 }, .Right);
911 try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 63, 0 }, .Right);
912
913 try doTheTestShiftExact([_]u8{ 0, 1, 1, math.maxInt(u8) ^ (1 << 7) }, [_]u3{ 4, 0, 7, 1 }, .Left);
914 try doTheTestShiftExact([_]u16{ 0, 1, 1, math.maxInt(u16) ^ (1 << 15) }, [_]u4{ 4, 0, 15, 1 }, .Left);
915 try doTheTestShiftExact([_]u24{ 0, 1, 1, math.maxInt(u24) ^ (1 << 23) }, [_]u5{ 4, 0, 23, 1 }, .Left);
916 try doTheTestShiftExact([_]u32{ 0, 1, 1, math.maxInt(u32) ^ (1 << 31) }, [_]u5{ 4, 0, 31, 1 }, .Left);
917 try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 0, 63 }, .Left);
918 }
919 };
920
921 try comptime S.doTheTest();
922 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
923 try S.doTheTest();
924}
925
926test "vector reduce operation" {
927 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
928 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
929 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
930 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
931 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
932
933 const S = struct {
934 fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
935 const N = @typeInfo(@TypeOf(x)).array.len;
936 const TX = @typeInfo(@TypeOf(x)).array.child;
937
938 const r = @reduce(op, @as(@Vector(N, TX), x));
939 switch (@typeInfo(TX)) {
940 .int, .bool => try expect(expected == r),
941 .float => {
942 const expected_nan = math.isNan(expected);
943 const got_nan = math.isNan(r);
944
945 if (expected_nan and got_nan) {
946 // Do this check explicitly as two NaN values are never
947 // equal.
948 } else {
949 const F = @TypeOf(expected);
950 const tolerance = @sqrt(math.floatEps(TX));
951 try expect(std.math.approxEqRel(F, expected, r, tolerance));
952 }
953 },
954 else => unreachable,
955 }
956 }
957 fn doTheTest() !void {
958 try testReduce(.Add, [4]i16{ -9, -99, -999, -9999 }, @as(i32, -11106));
959 try testReduce(.Add, [4]u16{ 9, 99, 999, 9999 }, @as(u32, 11106));
960 try testReduce(.Add, [4]i32{ -9, -99, -999, -9999 }, @as(i32, -11106));
961 try testReduce(.Add, [4]u32{ 9, 99, 999, 9999 }, @as(u32, 11106));
962 try testReduce(.Add, [4]i64{ -9, -99, -999, -9999 }, @as(i64, -11106));
963 try testReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106));
964 try testReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106));
965 try testReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106));
966 try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9));
967 try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9));
968 try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9));
969 try testReduce(.Add, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 42.9));
970 try testReduce(.Add, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 42.9));
971
972 try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));
973 try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));
974 try testReduce(.And, [4]u16{ 0xffff, 0xff55, 0xaaff, 0x1010 }, @as(u16, 0x10));
975 try testReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010));
976 try testReduce(.And, [4]u64{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u64, 0x1010));
977
978 try testReduce(.Min, [4]i16{ -1, 2, 3, 4 }, @as(i16, -1));
979 try testReduce(.Min, [4]u16{ 1, 2, 3, 4 }, @as(u16, 1));
980 try testReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386));
981 try testReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9));
982 try testReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386));
983 try testReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9));
984 try testReduce(.Min, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, -386));
985 try testReduce(.Min, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 9));
986 try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0));
987 try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));
988 try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));
989 try testReduce(.Min, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, -100.0));
990 try testReduce(.Min, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, -100.0));
991
992 try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4));
993 try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4));
994 try testReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567));
995 try testReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999));
996 try testReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567));
997 try testReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999));
998 try testReduce(.Max, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, 1234567));
999 try testReduce(.Max, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 99999));
1000 try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9));
1001 try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));
1002 try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));
1003 try testReduce(.Max, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, 10.0e9));
1004 try testReduce(.Max, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, 10.0e9));
1005
1006 try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24));
1007 try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24));
1008 try testReduce(.Mul, [4]i32{ -9, -99, -999, 999 }, @as(i32, -889218891));
1009 try testReduce(.Mul, [4]u32{ 1, 2, 3, 4 }, @as(u32, 24));
1010 try testReduce(.Mul, [4]i64{ 9, 99, 999, 9999 }, @as(i64, 8900199891));
1011 try testReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891));
1012 try testReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891));
1013 try testReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891));
1014 try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7));
1015 try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7));
1016 try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7));
1017 try testReduce(.Mul, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 58430.7));
1018 try testReduce(.Mul, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 58430.7));
1019
1020 try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));
1021 try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));
1022 try testReduce(.Or, [4]u16{ 0xff00, 0xff00, 0xf0, 0xf }, ~@as(u16, 0));
1023 try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));
1024 try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff));
1025 try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff));
1026 try testReduce(.Or, [4]u80{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u80, 0xffffffff));
1027
1028 try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));
1029 try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));
1030 try testReduce(.Xor, [4]u16{ 0x0000, 0x3333, 0x8888, 0x4444 }, ~@as(u16, 0));
1031 try testReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0));
1032 try testReduce(.Xor, [4]u64{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u64, 0xffffffff));
1033 try testReduce(.Xor, [4]u128{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u128, 0xffffffff));
1034
1035 // Test the reduction on vectors containing NaNs.
1036 const f16_nan = math.nan(f16);
1037 const f32_nan = math.nan(f32);
1038 const f64_nan = math.nan(f64);
1039 const f80_nan = math.nan(f80);
1040 const f128_nan = math.nan(f128);
1041
1042 try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
1043 try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
1044 try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
1045 try testReduce(.Add, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan);
1046 try testReduce(.Add, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan);
1047
1048 try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9));
1049 try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9));
1050 try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9));
1051 try testReduce(.Min, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, -1.9));
1052 try testReduce(.Min, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, -1.9));
1053
1054 try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0));
1055 try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0));
1056 try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0));
1057 try testReduce(.Max, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, 100.0));
1058 try testReduce(.Max, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, 100.0));
1059
1060 try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
1061 try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
1062 try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
1063 try testReduce(.Mul, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan);
1064 try testReduce(.Mul, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan);
1065 }
1066 };
1067
1068 try S.doTheTest();
1069 try comptime S.doTheTest();
1070}
1071
1072test "vector @reduce comptime" {
1073 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1074 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1075
1076 const V = @Vector(4, i32);
1077
1078 const value = V{ 1, -1, 1, -1 };
1079 const result = value > @as(V, @splat(0));
1080 // result is { true, false, true, false };
1081 comptime assert(@TypeOf(result) == @Vector(4, bool));
1082 const is_all_true = @reduce(.And, result);
1083 comptime assert(@TypeOf(is_all_true) == bool);
1084 try expect(is_all_true == false);
1085}
1086
1087test "saturating add" {
1088 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1089 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1090 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1091 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1092 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1093
1094 const S = struct {
1095 fn doTheTest() !void {
1096 { // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1097 const u8x3 = @Vector(3, u8);
1098 var lhs = u8x3{ 255, 254, 1 };
1099 var rhs = u8x3{ 1, 2, 255 };
1100 _ = .{ &lhs, &rhs };
1101 const result = lhs +| rhs;
1102 const expected = u8x3{ 255, 255, 255 };
1103 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1104 }
1105 { // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1106 const i8x3 = @Vector(3, i8);
1107 var lhs = i8x3{ 127, 126, 1 };
1108 var rhs = i8x3{ 1, 2, 127 };
1109 _ = .{ &lhs, &rhs };
1110 const result = lhs +| rhs;
1111 const expected = i8x3{ 127, 127, 127 };
1112 try expect(mem.eql(i8, &@as([3]i8, expected), &@as([3]i8, result)));
1113 }
1114 try testElemType(i4);
1115 try testElemType(u4);
1116 try testElemType(i8);
1117 try testElemType(u8);
1118 try testElemType(i12);
1119 try testElemType(u12);
1120 try testElemType(i16);
1121 try testElemType(u16);
1122 try testElemType(i24);
1123 try testElemType(u24);
1124 try testElemType(i32);
1125 try testElemType(u32);
1126 try testElemType(i48);
1127 try testElemType(u48);
1128 try testElemType(i64);
1129 try testElemType(u64);
1130 }
1131 fn testElemType(comptime Elem: type) !void {
1132 const min = std.math.minInt(Elem);
1133 const max = std.math.maxInt(Elem);
1134
1135 var v: @Vector(4, Elem) = .{ 0, 1, 0, 1 };
1136 v +|= .{ 0, 0, 1, 1 };
1137 try expect(v[0] == 0);
1138 try expect(v[1] == 1);
1139 try expect(v[2] == 1);
1140 try expect(v[3] == 2);
1141
1142 v = .{ 0, max, 1, max };
1143 v +|= .{ max, 0, max, 1 };
1144 try expect(v[0] == max);
1145 try expect(v[1] == max);
1146 try expect(v[2] == max);
1147 try expect(v[3] == max);
1148
1149 v = .{ 1, max - 1, max / 2, max };
1150 v +|= .{ max - 1, 1, max / 2, max };
1151 try expect(v[0] == max);
1152 try expect(v[1] == max);
1153 try expect(v[2] == max - 1);
1154 try expect(v[3] == max);
1155
1156 switch (@typeInfo(Elem).int.signedness) {
1157 .signed => {
1158 v = .{ -1, -1, 0, -1 };
1159 v +|= .{ 1, 0, -1, -1 };
1160 try expect(v[0] == 0);
1161 try expect(v[1] == -1);
1162 try expect(v[2] == -1);
1163 try expect(v[3] == -2);
1164
1165 v = .{ 0, min, -1, min };
1166 v +|= .{ min, 0, min, -1 };
1167 try expect(v[0] == min);
1168 try expect(v[1] == min);
1169 try expect(v[2] == min);
1170 try expect(v[3] == min);
1171
1172 v = .{ -1, min + 1, min / 2, min };
1173 v +|= .{ min + 1, -1, min / 2, min };
1174 try expect(v[0] == min);
1175 try expect(v[1] == min);
1176 try expect(v[2] == min);
1177 try expect(v[3] == min);
1178 },
1179 .unsigned => {},
1180 }
1181 }
1182 };
1183 try S.doTheTest();
1184 try comptime S.doTheTest();
1185}
1186
1187test "saturating subtraction" {
1188 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1191 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1192 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1193
1194 const S = struct {
1195 fn doTheTest() !void {
1196 {
1197 // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1198 const u8x3 = @Vector(3, u8);
1199 var lhs = u8x3{ 0, 0, 0 };
1200 var rhs = u8x3{ 255, 255, 255 };
1201 _ = .{ &lhs, &rhs };
1202 const result = lhs -| rhs;
1203 const expected = u8x3{ 0, 0, 0 };
1204 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1205 }
1206 try testElemType(i4);
1207 try testElemType(u4);
1208 try testElemType(i8);
1209 try testElemType(u8);
1210 try testElemType(i12);
1211 try testElemType(u12);
1212 try testElemType(i16);
1213 try testElemType(u16);
1214 try testElemType(i24);
1215 try testElemType(u24);
1216 try testElemType(i32);
1217 try testElemType(u32);
1218 try testElemType(i48);
1219 try testElemType(u48);
1220 try testElemType(i64);
1221 try testElemType(u64);
1222 }
1223 fn testElemType(comptime Elem: type) !void {
1224 const min = std.math.minInt(Elem);
1225 const max = std.math.maxInt(Elem);
1226
1227 var v: @Vector(4, Elem) = .{ 0, 1, 0, 1 };
1228 v -|= .{ 0, 0, 1, 1 };
1229 try expect(v[0] == 0);
1230 try expect(v[1] == 1);
1231 try expect(v[2] == @max(min, -1));
1232 try expect(v[3] == 0);
1233
1234 v = .{ 0, max, 1, max };
1235 v -|= .{ max, 0, max, 1 };
1236 try expect(v[0] == @min(min + 1, 0));
1237 try expect(v[1] == max);
1238 try expect(v[2] == @min(min + 2, 0));
1239 try expect(v[3] == max - 1);
1240
1241 v = .{ 1, max - 1, max / 2, max };
1242 v -|= .{ max - 1, 1, max / 2, max };
1243 try expect(v[0] == @min(min + 3, 0));
1244 try expect(v[1] == max - 2);
1245 try expect(v[2] == 0);
1246 try expect(v[3] == 0);
1247
1248 switch (@typeInfo(Elem).int.signedness) {
1249 .signed => {
1250 v = .{ -1, -1, 0, -1 };
1251 v -|= .{ -1, 0, 1, 1 };
1252 try expect(v[0] == 0);
1253 try expect(v[1] == -1);
1254 try expect(v[2] == -1);
1255 try expect(v[3] == -2);
1256
1257 v = .{ 0, min, -1, min };
1258 v -|= .{ max, 0, max, 1 };
1259 try expect(v[0] == min + 1);
1260 try expect(v[1] == min);
1261 try expect(v[2] == min);
1262 try expect(v[3] == min);
1263
1264 v = .{ -1, min + 1, min / 2, min };
1265 v -|= .{ max, 1, max / 2, max };
1266 try expect(v[0] == min);
1267 try expect(v[1] == min);
1268 try expect(v[2] == min + 1);
1269 try expect(v[3] == min);
1270 },
1271 .unsigned => {},
1272 }
1273 }
1274 };
1275 try S.doTheTest();
1276 try comptime S.doTheTest();
1277}
1278
1279test "saturating multiplication" {
1280 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1281 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1282 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1283 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1284 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1285
1286 const S = struct {
1287 fn doTheTest() !void {
1288 // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1289 const u8x3 = @Vector(3, u8);
1290 var lhs = u8x3{ 2, 2, 2 };
1291 var rhs = u8x3{ 255, 255, 255 };
1292 _ = .{ &lhs, &rhs };
1293 const result = lhs *| rhs;
1294 const expected = u8x3{ 255, 255, 255 };
1295 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1296 }
1297 };
1298
1299 try S.doTheTest();
1300 try comptime S.doTheTest();
1301}
1302
1303test "saturating shift-left" {
1304 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1307 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1308 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1309
1310 const S = struct {
1311 fn doTheTest() !void {
1312 // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1313 const u8x3 = @Vector(3, u8);
1314 var lhs = u8x3{ 1, 1, 1 };
1315 var rhs = u8x3{ 255, 255, 255 };
1316 _ = .{ &lhs, &rhs };
1317 const result = lhs <<| rhs;
1318 const expected = u8x3{ 255, 255, 255 };
1319 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1320 }
1321 };
1322 try S.doTheTest();
1323 try comptime S.doTheTest();
1324}
1325
1326test "multiplication-assignment operator with an array operand" {
1327 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1329 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1330 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1331
1332 const S = struct {
1333 fn doTheTest() !void {
1334 var x: @Vector(3, i32) = .{ 1, 2, 3 };
1335 x *= [_]i32{ 4, 5, 6 };
1336 try expect(x[0] == 4);
1337 try expect(x[1] == 10);
1338 try expect(x[2] == 18);
1339 }
1340 };
1341 try S.doTheTest();
1342 try comptime S.doTheTest();
1343}
1344
1345test "@addWithOverflow" {
1346 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1349 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1350 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1351
1352 const S = struct {
1353 fn doTheTest() !void {
1354 {
1355 var lhs = @Vector(4, u8){ 250, 250, 250, 250 };
1356 var rhs = @Vector(4, u8){ 0, 5, 6, 10 };
1357 _ = .{ &lhs, &rhs };
1358 const overflow = @addWithOverflow(lhs, rhs)[1];
1359 const expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
1360 try expectEqual(expected, overflow);
1361 }
1362 {
1363 var lhs = @Vector(4, i8){ -125, -125, 125, 125 };
1364 var rhs = @Vector(4, i8){ -3, -4, 2, 3 };
1365 _ = .{ &lhs, &rhs };
1366 const overflow = @addWithOverflow(lhs, rhs)[1];
1367 const expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
1368 try expectEqual(expected, overflow);
1369 }
1370 {
1371 var lhs = @Vector(4, u1){ 0, 0, 1, 1 };
1372 var rhs = @Vector(4, u1){ 0, 1, 0, 1 };
1373 _ = .{ &lhs, &rhs };
1374 const overflow = @addWithOverflow(lhs, rhs)[1];
1375 const expected: @Vector(4, u1) = .{ 0, 0, 0, 1 };
1376 try expectEqual(expected, overflow);
1377 }
1378 {
1379 var lhs = @Vector(4, u0){ 0, 0, 0, 0 };
1380 var rhs = @Vector(4, u0){ 0, 0, 0, 0 };
1381 _ = .{ &lhs, &rhs };
1382 const overflow = @addWithOverflow(lhs, rhs)[1];
1383 const expected: @Vector(4, u1) = .{ 0, 0, 0, 0 };
1384 try expectEqual(expected, overflow);
1385 }
1386 }
1387 };
1388 try comptime S.doTheTest();
1389 try S.doTheTest();
1390}
1391
1392test "@subWithOverflow" {
1393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1394 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1395 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1396 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1397 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1398
1399 const S = struct {
1400 fn doTheTest() !void {
1401 {
1402 var lhs = @Vector(2, u8){ 5, 5 };
1403 var rhs = @Vector(2, u8){ 5, 6 };
1404 _ = .{ &lhs, &rhs };
1405 const overflow = @subWithOverflow(lhs, rhs)[1];
1406 const expected: @Vector(2, u1) = .{ 0, 1 };
1407 try expectEqual(expected, overflow);
1408 }
1409 {
1410 var lhs = @Vector(4, i8){ -120, -120, 120, 120 };
1411 var rhs = @Vector(4, i8){ 8, 9, -7, -8 };
1412 _ = .{ &lhs, &rhs };
1413 const overflow = @subWithOverflow(lhs, rhs)[1];
1414 const expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
1415 try expectEqual(expected, overflow);
1416 }
1417 }
1418 };
1419 try comptime S.doTheTest();
1420 try S.doTheTest();
1421}
1422
1423test "@mulWithOverflow" {
1424 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1425 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1428 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1429
1430 const S = struct {
1431 fn doTheTest() !void {
1432 var lhs = @Vector(4, u8){ 10, 10, 10, 10 };
1433 var rhs = @Vector(4, u8){ 25, 26, 0, 30 };
1434 _ = .{ &lhs, &rhs };
1435 const overflow = @mulWithOverflow(lhs, rhs)[1];
1436 const expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
1437 try expectEqual(expected, overflow);
1438 }
1439 };
1440 try comptime S.doTheTest();
1441 try S.doTheTest();
1442}
1443
1444test "@shlWithOverflow" {
1445 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1446 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1447 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1448 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1449 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1450
1451 const S = struct {
1452 fn doTheTest() !void {
1453 var lhs = @Vector(4, u8){ 0, 1, 8, 255 };
1454 var rhs = @Vector(4, u3){ 7, 7, 7, 7 };
1455 _ = .{ &lhs, &rhs };
1456 const overflow = @shlWithOverflow(lhs, rhs)[1];
1457 const expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
1458 try expectEqual(expected, overflow);
1459 }
1460 };
1461 try S.doTheTest();
1462 try comptime S.doTheTest();
1463}
1464
1465test "alignment of vectors" {
1466 try expect(@alignOf(@Vector(2, u8)) == switch (builtin.zig_backend) {
1467 else => 2,
1468 .stage2_c, .stage2_wasm => @alignOf(u8),
1469 .stage2_x86_64 => 16,
1470 });
1471 try expect(@alignOf(@Vector(2, u1)) == switch (builtin.zig_backend) {
1472 else => 1,
1473 .stage2_c, .stage2_wasm => @alignOf(u1),
1474 .stage2_x86_64 => 16,
1475 });
1476 try expect(@alignOf(@Vector(1, u1)) == switch (builtin.zig_backend) {
1477 else => 1,
1478 .stage2_c, .stage2_wasm => @alignOf(u1),
1479 .stage2_x86_64 => 16,
1480 });
1481 try expect(@alignOf(@Vector(2, u16)) == switch (builtin.zig_backend) {
1482 else => 4,
1483 .stage2_c, .stage2_wasm => @alignOf(u16),
1484 .stage2_x86_64 => 16,
1485 });
1486}
1487
1488test "loading the second vector from a slice of vectors" {
1489 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1490 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1491 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1492
1493 @setRuntimeSafety(false);
1494 var small_bases = [2]@Vector(2, u8){
1495 @Vector(2, u8){ 0, 1 },
1496 @Vector(2, u8){ 2, 3 },
1497 };
1498 const a: []const @Vector(2, u8) = &small_bases;
1499 const a4 = a[1][1];
1500 try expect(a4 == 3);
1501}
1502
1503test "array of vectors is copied" {
1504 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1505 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1507 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1508
1509 const Vec3 = @Vector(3, i32);
1510 var points = [_]Vec3{
1511 Vec3{ 404, -588, -901 },
1512 Vec3{ 528, -643, 409 },
1513 Vec3{ -838, 591, 734 },
1514 Vec3{ 390, -675, -793 },
1515 Vec3{ -537, -823, -458 },
1516 Vec3{ -485, -357, 347 },
1517 Vec3{ -345, -311, 381 },
1518 Vec3{ -661, -816, -575 },
1519 };
1520 _ = &points;
1521 var points2: [20]Vec3 = undefined;
1522 points2[0..points.len].* = points;
1523 try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });
1524}
1525
1526test "byte vector initialized in inline function" {
1527 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1528 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1529 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1530 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1531 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1532
1533 const S = struct {
1534 fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
1535 return .{ e0, e1, e2, e3 };
1536 }
1537
1538 fn all(vb: @Vector(4, bool)) bool {
1539 return @reduce(.And, vb);
1540 }
1541 };
1542
1543 try expect(S.all(S.boolx4(true, true, true, true)));
1544}
1545
1546test "zero divisor" {
1547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1548 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1549
1550 const zeros = @Vector(2, f32){ 0.0, 0.0 };
1551 const ones = @Vector(2, f32){ 1.0, 1.0 };
1552
1553 const v1 = zeros / ones;
1554 const v2 = @divExact(zeros, ones);
1555 const v3 = @divTrunc(zeros, ones);
1556 const v4 = @divFloor(zeros, ones);
1557 const v5 = @divCeil(zeros, ones);
1558
1559 _ = v1[0];
1560 _ = v2[0];
1561 _ = v3[0];
1562 _ = v4[0];
1563 _ = v5[0];
1564}
1565
1566test "zero multiplicand" {
1567 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1568 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1569 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1570 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1571 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1572
1573 const zeros = @Vector(2, u32){ 0.0, 0.0 };
1574 var ones = @Vector(2, u32){ 1.0, 1.0 };
1575 _ = &ones;
1576
1577 _ = (ones * zeros)[0];
1578 _ = (zeros * zeros)[0];
1579 _ = (zeros * ones)[0];
1580
1581 _ = (ones *| zeros)[0];
1582 _ = (zeros *| zeros)[0];
1583 _ = (zeros *| ones)[0];
1584
1585 _ = (ones *% zeros)[0];
1586 _ = (zeros *% zeros)[0];
1587 _ = (zeros *% ones)[0];
1588}
1589
1590test "@intCast to u0" {
1591 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1592 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1593 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1594 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1595
1596 var zeros = @Vector(2, u32){ 0, 0 };
1597 _ = &zeros;
1598 const casted = @as(@Vector(2, u0), @intCast(zeros));
1599
1600 _ = casted[0];
1601}
1602
1603test "modRem with zero divisor" {
1604 comptime {
1605 var zeros = @Vector(2, u32){ 0, 0 };
1606 const ones = @Vector(2, u32){ 1, 1 };
1607
1608 zeros %= ones;
1609 _ = zeros[0];
1610 }
1611}
1612
1613test "array operands to shuffle are coerced to vectors" {
1614 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1615 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1616 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1617 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1618 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1619
1620 const mask = [5]i32{ -1, 0, 1, 2, 3 };
1621
1622 var a = [5]u32{ 3, 5, 7, 9, 0 };
1623 _ = &a;
1624 const b = @shuffle(u32, a, @as(@Vector(5, u24), @splat(0)), mask);
1625 try expectEqual([_]u32{ 0, 3, 5, 7, 9 }, b);
1626}
1627
1628test "load packed vector element" {
1629 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1630 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1631 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1632 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1633
1634 var x: @Vector(2, u15) = .{ 1, 4 };
1635 try expect((&x[0]).* == 1);
1636 try expect((&x[1]).* == 4);
1637}
1638
1639test "store packed vector element" {
1640 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1641 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1642 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1643 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1644 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1645
1646 var v = @Vector(4, u1){ 1, 1, 1, 1 };
1647 try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v);
1648 const index: usize = 0;
1649 v[index] = 0;
1650 try expectEqual(@Vector(4, u1){ 0, 1, 1, 1 }, v);
1651}
1652
1653test "store to vector in slice" {
1654 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1655 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1656 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1657 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1658
1659 var v = [_]@Vector(3, f32){
1660 .{ 1, 1, 1 },
1661 .{ 0, 0, 0 },
1662 };
1663 var s: []@Vector(3, f32) = &v;
1664 var i: usize = 1;
1665 _ = &i;
1666 s[i] = s[0];
1667 try expectEqual(v[1], v[0]);
1668}
1669
1670test "store vector with memset" {
1671 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1672 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1673 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1674 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1675 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1676
1677 var a: [5]@Vector(2, i1) = undefined;
1678 var b: [5]@Vector(2, u2) = undefined;
1679 var c: [5]@Vector(2, i4) = undefined;
1680 var d: [5]@Vector(2, u8) = undefined;
1681 var e: [5]@Vector(2, i9) = undefined;
1682 var ka = @Vector(2, i1){ -1, 0 };
1683 var kb = @Vector(2, u2){ 0, 1 };
1684 var kc = @Vector(2, i4){ 2, 3 };
1685 var kd = @Vector(2, u8){ 4, 5 };
1686 var ke = @Vector(2, i9){ 6, 7 };
1687 _ = .{ &ka, &kb, &kc, &kd, &ke };
1688 @memset(&a, ka);
1689 @memset(&b, kb);
1690 @memset(&c, kc);
1691 @memset(&d, kd);
1692 @memset(&e, ke);
1693 try std.testing.expectEqual(ka, a[0]);
1694 try std.testing.expectEqual(kb, b[1]);
1695 try std.testing.expectEqual(kc, c[2]);
1696 try std.testing.expectEqual(kd, d[3]);
1697 try std.testing.expectEqual(ke, e[4]);
1698}
1699
1700test "addition of vectors represented as strings" {
1701 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1702 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1703 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1704
1705 const V = @Vector(3, u8);
1706 const foo: V = "foo".*;
1707 const bar: V = @typeName(u32).*;
1708 try expectEqual(V{ 219, 162, 161 }, foo + bar);
1709}
1710
1711test "compare vectors with different element types" {
1712 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1713 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1714 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1715 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1716 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1717
1718 var a: @Vector(2, u8) = .{ 1, 2 };
1719 var b: @Vector(2, u9) = .{ 3, 0 };
1720 _ = .{ &a, &b };
1721 try expectEqual(@Vector(2, bool){ true, false }, a < b);
1722}
1723
1724test "vector pointer is indexable" {
1725 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1726 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1727
1728 const V = @Vector(2, u32);
1729
1730 const x: V = .{ 123, 456 };
1731 comptime assert(@typeInfo(@TypeOf(&(&x)[0])).pointer.attrs.@"const");
1732 try expectEqual(@as(u32, 123), (&x)[0]);
1733 try expectEqual(@as(u32, 456), (&x)[1]);
1734
1735 var y: V = .{ 123, 456 };
1736 comptime assert(!@typeInfo(@TypeOf(&(&y)[0])).pointer.attrs.@"const");
1737 try expectEqual(@as(u32, 123), (&y)[0]);
1738 try expectEqual(@as(u32, 456), (&y)[1]);
1739
1740 (&y)[0] = 100;
1741 (&y)[1] = 200;
1742 try expectEqual(@as(u32, 100), (&y)[0]);
1743 try expectEqual(@as(u32, 200), (&y)[1]);
1744}
1745
1746test "boolean vector with 2 or more booleans" {
1747 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1748 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1749
1750 const vec1 = @Vector(2, bool){ true, true };
1751 _ = vec1;
1752
1753 const vec2 = @Vector(3, bool){ true, true, true };
1754 _ = vec2;
1755}
1756
1757test "bitcast to vector with different child type" {
1758 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1759 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1760 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1761 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1762 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1763
1764 const S = struct {
1765 fn doTheTest() !void {
1766 const VecA = @Vector(8, u16);
1767 const VecB = @Vector(4, u32);
1768
1769 var vec_a = VecA{ 1, 1, 1, 1, 1, 1, 1, 1 };
1770 _ = &vec_a;
1771 const vec_b: VecB = @bitCast(vec_a);
1772 const vec_c: VecA = @bitCast(vec_b);
1773 try expectEqual(vec_a, vec_c);
1774 }
1775 };
1776
1777 try S.doTheTest();
1778 try comptime S.doTheTest();
1779}
1780
1781test "index into comptime-known vector is comptime-known" {
1782 const vec: @Vector(2, f16) = [2]f16{ 1.5, 3.5 };
1783 if (vec[0] != 1.5) @compileError("vec should be comptime");
1784}
1785
1786test "arithmetic on zero-length vectors" {
1787 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1788 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1789
1790 {
1791 const a = @Vector(0, i32){};
1792 const b = @Vector(0, i32){};
1793 _ = a + b;
1794 }
1795 {
1796 const a = @Vector(0, i32){};
1797 const b = @Vector(0, i32){};
1798 _ = a - b;
1799 }
1800}
1801
1802test "@reduce on bool vector" {
1803 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1804
1805 const a = @Vector(2, bool){ true, true };
1806 const b = @Vector(1, bool){true};
1807 try std.testing.expect(@reduce(.And, a));
1808 try std.testing.expect(@reduce(.And, b));
1809}
1810
1811test "bitcast vector to array of smaller vectors" {
1812 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1813 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1814 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1815
1816 const u8x32 = @Vector(32, u8);
1817 const u8x64 = @Vector(64, u8);
1818 const S = struct {
1819 fn doTheTest(input_vec: u8x64) !void {
1820 try compare(@bitCast(input_vec));
1821 }
1822 fn compare(chunks: [2]u8x32) !void {
1823 try expectEqual(@as(u8x32, @splat(1)), chunks[0]);
1824 try expectEqual(@as(u8x32, @splat(2)), chunks[1]);
1825 }
1826 };
1827 const input: u8x64 = @bitCast([2]u8x32{ @splat(1), @splat(2) });
1828 try S.doTheTest(input);
1829}