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