master
1const std = @import("std");
2const builtin = @import("builtin");
3const mem = std.mem;
4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;
6
7test "@shuffle int" {
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13
14 const S = struct {
15 fn doTheTest() !void {
16 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
17 _ = &v;
18 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
19 _ = &x;
20 const mask = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) };
21 var res = @shuffle(i32, v, x, mask);
22 try expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 }));
23
24 // Implicit cast from array (of mask)
25 res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) });
26 try expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 }));
27
28 // Undefined
29 const mask2 = [4]i32{ 3, 1, 2, 0 };
30 res = @shuffle(i32, v, undefined, mask2);
31 try expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 40, -2, 30, 2147483647 }));
32
33 // Upcasting of b
34 var v2: @Vector(2, i32) = [2]i32{ 2147483647, undefined };
35 _ = &v2;
36 const mask3 = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 };
37 res = @shuffle(i32, x, v2, mask3);
38 try expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 2147483647, 4 }));
39
40 // Upcasting of a
41 var v3: @Vector(2, i32) = [2]i32{ 2147483647, -2 };
42 _ = &v3;
43 const mask4 = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) };
44 res = @shuffle(i32, v3, x, mask4);
45 try expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, -2, 4 }));
46 }
47 };
48 try S.doTheTest();
49 try comptime S.doTheTest();
50}
51
52test "@shuffle int strange sizes" {
53 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
54 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
58 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
59
60 try comptime testShuffle(2, 2, 2);
61 try testShuffle(2, 2, 2);
62 try comptime testShuffle(4, 4, 4);
63 try testShuffle(4, 4, 4);
64 try comptime testShuffle(7, 4, 4);
65 try testShuffle(7, 4, 4);
66 try comptime testShuffle(8, 6, 4);
67 try testShuffle(8, 6, 4);
68 try comptime testShuffle(2, 7, 5);
69 try testShuffle(2, 7, 5);
70 try comptime testShuffle(13, 16, 12);
71 try testShuffle(13, 16, 12);
72 try comptime testShuffle(19, 3, 17);
73 try testShuffle(19, 3, 17);
74 try comptime testShuffle(1, 10, 1);
75 try testShuffle(1, 10, 1);
76}
77
78fn testShuffle(
79 comptime x_len: comptime_int,
80 comptime a_len: comptime_int,
81 comptime b_len: comptime_int,
82) !void {
83 const T = i32;
84 const XT = @Vector(x_len, T);
85 const AT = @Vector(a_len, T);
86 const BT = @Vector(b_len, T);
87
88 const a_elems = comptime blk: {
89 var elems: [a_len]T = undefined;
90 for (&elems, 0..) |*elem, i| elem.* = @intCast(100 + i);
91 break :blk elems;
92 };
93 var a: AT = a_elems;
94 _ = &a;
95
96 const b_elems = comptime blk: {
97 var elems: [b_len]T = undefined;
98 for (&elems, 0..) |*elem, i| elem.* = @intCast(1000 + i);
99 break :blk elems;
100 };
101 var b: BT = b_elems;
102 _ = &b;
103
104 const mask_seed: []const i32 = &.{ -14, -31, 23, 1, 21, 13, 17, -21, -10, -27, -16, -5, 15, 14, -2, 26, 2, -31, -24, -16 };
105
106 const mask = comptime blk: {
107 var elems: [x_len]i32 = undefined;
108 for (&elems, 0..) |*elem, i| {
109 const mask_val = mask_seed[i];
110 if (mask_val >= 0) {
111 elem.* = @mod(mask_val, a_len);
112 } else {
113 elem.* = @mod(mask_val, -b_len);
114 }
115 }
116
117 break :blk elems;
118 };
119
120 const x: XT = @shuffle(T, a, b, mask);
121
122 const x_elems: [x_len]T = x;
123 for (mask, x_elems) |m, x_elem| {
124 if (m >= 0) {
125 // Element from A
126 try expectEqual(x_elem, a_elems[@intCast(m)]);
127 } else {
128 // Element from B
129 try expectEqual(x_elem, b_elems[@intCast(~m)]);
130 }
131 }
132}
133
134test "@shuffle bool 1" {
135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
136 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
140 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
141
142 const S = struct {
143 fn doTheTest() !void {
144 var x: @Vector(4, bool) = [4]bool{ false, true, false, true };
145 _ = &x;
146 var v: @Vector(2, bool) = [2]bool{ true, false };
147 _ = &v;
148 const mask = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
149 const res = @shuffle(bool, x, v, mask);
150 try expect(mem.eql(bool, &@as([4]bool, res), &[4]bool{ false, false, true, false }));
151 }
152 };
153 try S.doTheTest();
154 try comptime S.doTheTest();
155}
156
157test "@shuffle bool 2" {
158 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
159 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
164
165 const S = struct {
166 fn doTheTest() !void {
167 var x: @Vector(3, bool) = [3]bool{ false, true, false };
168 _ = &x;
169 var v: @Vector(2, bool) = [2]bool{ true, false };
170 _ = &v;
171 const mask = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
172 const res = @shuffle(bool, x, v, mask);
173 try expect(mem.eql(bool, &@as([4]bool, res), &[4]bool{ false, false, true, false }));
174 }
175 };
176 try S.doTheTest();
177 try comptime S.doTheTest();
178}