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}