zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob c2c2993f (62441B) - Raw


      1 const std = @import("std");
      2 const builtin = @import("builtin");
      3 const mem = std.mem;
      4 const math = std.math;
      5 const assert = std.debug.assert;
      6 const expect = std.testing.expect;
      7 const expectEqual = std.testing.expectEqual;
      8 
      9 test "implicit cast vector to array - bool" {
     10     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     11     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     12     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     13     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     14     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     15     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
     16 
     17     const S = struct {
     18         fn doTheTest() !void {
     19             const a: @Vector(4, bool) = [_]bool{ true, false, true, false };
     20             const result_array: [4]bool = a;
     21             try expect(mem.eql(bool, &result_array, &[4]bool{ true, false, true, false }));
     22         }
     23     };
     24     try S.doTheTest();
     25     try comptime S.doTheTest();
     26 }
     27 
     28 test "vector wrap operators" {
     29     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     30     if (builtin.zig_backend == .stage2_x86_64 and
     31         !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO
     32     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     33     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     34     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     35     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
     36 
     37     const S = struct {
     38         fn doTheTest() !void {
     39             var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
     40             var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
     41             try expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 }));
     42             try expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 }));
     43             try expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 }));
     44             var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };
     45             try expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 }));
     46         }
     47     };
     48     try S.doTheTest();
     49     try comptime S.doTheTest();
     50 }
     51 
     52 test "vector bin compares with mem.eql" {
     53     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     54     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     55     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     56     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     57     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     58     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
     59 
     60     const S = struct {
     61         fn doTheTest() !void {
     62             var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
     63             var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };
     64             try expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false }));
     65             try expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true }));
     66             try expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false }));
     67             try expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true }));
     68             try expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false }));
     69             try expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true }));
     70         }
     71     };
     72     try S.doTheTest();
     73     try comptime S.doTheTest();
     74 }
     75 
     76 test "vector int operators" {
     77     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     78     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     79     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     80     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     81     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     82     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
     83 
     84     const S = struct {
     85         fn doTheTest() !void {
     86             var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
     87             var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
     88             try expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 }));
     89             try expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 }));
     90             try expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 }));
     91             try expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 }));
     92         }
     93     };
     94     try S.doTheTest();
     95     try comptime S.doTheTest();
     96 }
     97 
     98 test "vector float operators" {
     99     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    100     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    101     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    102     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    103     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    104     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    105 
    106     inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
    107         const S = struct {
    108             fn doTheTest() !void {
    109                 var v: @Vector(4, T) = [4]T{ 10, 20, 30, 40 };
    110                 var x: @Vector(4, T) = [4]T{ 1, 2, 3, 4 };
    111                 try expect(mem.eql(T, &@as([4]T, v + x), &[4]T{ 11, 22, 33, 44 }));
    112                 try expect(mem.eql(T, &@as([4]T, v - x), &[4]T{ 9, 18, 27, 36 }));
    113                 try expect(mem.eql(T, &@as([4]T, v * x), &[4]T{ 10, 40, 90, 160 }));
    114                 try expect(mem.eql(T, &@as([4]T, -x), &[4]T{ -1, -2, -3, -4 }));
    115             }
    116         };
    117         try S.doTheTest();
    118         try comptime S.doTheTest();
    119     }
    120 }
    121 
    122 test "vector bit operators" {
    123     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    124     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    125     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    126     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    127     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    128 
    129     const S = struct {
    130         fn doTheTest() !void {
    131             var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
    132             var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
    133             try expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
    134             try expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
    135             try expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
    136         }
    137     };
    138     try S.doTheTest();
    139     try comptime S.doTheTest();
    140 }
    141 
    142 test "implicit cast vector to array" {
    143     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    144     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    145     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    146     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    147 
    148     const S = struct {
    149         fn doTheTest() !void {
    150             var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
    151             var result_array: [4]i32 = a;
    152             result_array = a;
    153             try expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 }));
    154         }
    155     };
    156     try S.doTheTest();
    157     try comptime S.doTheTest();
    158 }
    159 
    160 test "array to vector" {
    161     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    162     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    163     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    164     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    165 
    166     const S = struct {
    167         fn doTheTest() !void {
    168             var foo: f32 = 3.14;
    169             var arr = [4]f32{ foo, 1.5, 0.0, 0.0 };
    170             var vec: @Vector(4, f32) = arr;
    171             try expect(mem.eql(f32, &@as([4]f32, vec), &arr));
    172         }
    173     };
    174     try S.doTheTest();
    175     try comptime S.doTheTest();
    176 }
    177 
    178 test "array to vector with element type coercion" {
    179     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    180     if (builtin.zig_backend == .stage2_x86_64 and
    181         !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; // TODO
    182     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    183     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    184     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    185     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    186 
    187     const S = struct {
    188         fn doTheTest() !void {
    189             var foo: f16 = 3.14;
    190             var arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 };
    191             var vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 };
    192             try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32));
    193         }
    194     };
    195     try S.doTheTest();
    196     try comptime S.doTheTest();
    197 }
    198 
    199 test "peer type resolution with coercible element types" {
    200     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    201     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    202     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    203     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    204     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    205     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    206 
    207     const S = struct {
    208         fn doTheTest() !void {
    209             var b: @Vector(2, u8) = .{ 1, 2 };
    210             var a: @Vector(2, u16) = .{ 2, 1 };
    211             var t: bool = true;
    212             var c = if (t) a else b;
    213             try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
    214         }
    215     };
    216     try comptime S.doTheTest();
    217 }
    218 
    219 test "tuple to vector" {
    220     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    221     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    222     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    223     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    224     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    225     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    226 
    227     if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
    228         // Regressed with LLVM 14:
    229         // https://github.com/ziglang/zig/issues/12012
    230         return error.SkipZigTest;
    231     }
    232 
    233     const S = struct {
    234         fn doTheTest() !void {
    235             const Vec3 = @Vector(3, i32);
    236             var v: Vec3 = .{ 1, 0, 0 };
    237             for ([_]Vec3{ .{ 0, 1, 0 }, .{ 0, 0, 1 } }) |it| {
    238                 v += it;
    239             }
    240 
    241             try std.testing.expectEqual(v, Vec3{ 1, 1, 1 });
    242             try std.testing.expectEqual(v, .{ 1, 1, 1 });
    243         }
    244     };
    245     try S.doTheTest();
    246     try comptime S.doTheTest();
    247 }
    248 
    249 test "vector casts of sizes not divisible by 8" {
    250     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    251     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    252     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    253     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    254     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    255     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    256 
    257     const S = struct {
    258         fn doTheTest() !void {
    259             {
    260                 var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };
    261                 var x: [4]u3 = v;
    262                 try expect(mem.eql(u3, &x, &@as([4]u3, v)));
    263             }
    264             {
    265                 var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };
    266                 var x: [4]u2 = v;
    267                 try expect(mem.eql(u2, &x, &@as([4]u2, v)));
    268             }
    269             {
    270                 var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };
    271                 var x: [4]u1 = v;
    272                 try expect(mem.eql(u1, &x, &@as([4]u1, v)));
    273             }
    274             {
    275                 var v: @Vector(4, bool) = [4]bool{ false, false, true, false };
    276                 var x: [4]bool = v;
    277                 try expect(mem.eql(bool, &x, &@as([4]bool, v)));
    278             }
    279         }
    280     };
    281     try S.doTheTest();
    282     try comptime S.doTheTest();
    283 }
    284 
    285 test "vector @splat" {
    286     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    287     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    288     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    289     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    290     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    291 
    292     if (builtin.zig_backend == .stage2_llvm and
    293         builtin.os.tag == .macos)
    294     {
    295         // LLVM 15 regression: https://github.com/ziglang/zig/issues/12827
    296         return error.SkipZigTest;
    297     }
    298 
    299     const S = struct {
    300         fn testForT(comptime N: comptime_int, v: anytype) !void {
    301             const T = @TypeOf(v);
    302             var vec = @splat(N, v);
    303             try expect(@Vector(N, T) == @TypeOf(vec));
    304             var as_array = @as([N]T, vec);
    305             for (as_array) |elem| try expect(v == elem);
    306         }
    307         fn doTheTest() !void {
    308             // Splats with multiple-of-8 bit types that fill a 128bit vector.
    309             try testForT(16, @as(u8, 0xEE));
    310             try testForT(8, @as(u16, 0xBEEF));
    311             try testForT(4, @as(u32, 0xDEADBEEF));
    312             try testForT(2, @as(u64, 0xCAFEF00DDEADBEEF));
    313 
    314             try testForT(8, @as(f16, 3.1415));
    315             try testForT(4, @as(f32, 3.1415));
    316             try testForT(2, @as(f64, 3.1415));
    317 
    318             // Same but fill more than 128 bits.
    319             try testForT(16 * 2, @as(u8, 0xEE));
    320             try testForT(8 * 2, @as(u16, 0xBEEF));
    321             try testForT(4 * 2, @as(u32, 0xDEADBEEF));
    322             try testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF));
    323 
    324             try testForT(8 * 2, @as(f16, 3.1415));
    325             try testForT(4 * 2, @as(f32, 3.1415));
    326             try testForT(2 * 2, @as(f64, 3.1415));
    327         }
    328     };
    329     try S.doTheTest();
    330     try comptime S.doTheTest();
    331 }
    332 
    333 test "load vector elements via comptime index" {
    334     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    335     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    336     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    337     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    338 
    339     const S = struct {
    340         fn doTheTest() !void {
    341             var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
    342             try expect(v[0] == 1);
    343             try expect(v[1] == 2);
    344             try expect(loadv(&v[2]) == 3);
    345         }
    346         fn loadv(ptr: anytype) i32 {
    347             return ptr.*;
    348         }
    349     };
    350 
    351     try S.doTheTest();
    352     try comptime S.doTheTest();
    353 }
    354 
    355 test "store vector elements via comptime index" {
    356     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    357     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    358     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    359     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    360 
    361     const S = struct {
    362         fn doTheTest() !void {
    363             var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
    364 
    365             v[2] = 42;
    366             try expect(v[1] == 5);
    367             v[3] = -364;
    368             try expect(v[2] == 42);
    369             try expect(-364 == v[3]);
    370 
    371             storev(&v[0], 100);
    372             try expect(v[0] == 100);
    373         }
    374         fn storev(ptr: anytype, x: i32) void {
    375             ptr.* = x;
    376         }
    377     };
    378 
    379     try S.doTheTest();
    380     try comptime S.doTheTest();
    381 }
    382 
    383 test "load vector elements via runtime index" {
    384     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    385     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    386     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    387     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    388 
    389     const S = struct {
    390         fn doTheTest() !void {
    391             var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
    392             var i: u32 = 0;
    393             try expect(v[i] == 1);
    394             i += 1;
    395             try expect(v[i] == 2);
    396             i += 1;
    397             try expect(v[i] == 3);
    398         }
    399     };
    400 
    401     try S.doTheTest();
    402     try comptime S.doTheTest();
    403 }
    404 
    405 test "store vector elements via runtime index" {
    406     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    407     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    408     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    409     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    410 
    411     const S = struct {
    412         fn doTheTest() !void {
    413             var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
    414             var i: u32 = 2;
    415             v[i] = 1;
    416             try expect(v[1] == 5);
    417             try expect(v[2] == 1);
    418             i += 1;
    419             v[i] = -364;
    420             try expect(-364 == v[3]);
    421         }
    422     };
    423 
    424     try S.doTheTest();
    425     try comptime S.doTheTest();
    426 }
    427 
    428 test "initialize vector which is a struct field" {
    429     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    430     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    431     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    432     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    433 
    434     const Vec4Obj = struct {
    435         data: @Vector(4, f32),
    436     };
    437 
    438     const S = struct {
    439         fn doTheTest() !void {
    440             var foo = Vec4Obj{
    441                 .data = [_]f32{ 1, 2, 3, 4 },
    442             };
    443             _ = foo;
    444         }
    445     };
    446     try S.doTheTest();
    447     try comptime S.doTheTest();
    448 }
    449 
    450 test "vector comparison operators" {
    451     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    452     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    453     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    454     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    455     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    456     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    457 
    458     const S = struct {
    459         fn doTheTest() !void {
    460             {
    461                 var v1: @Vector(4, bool) = [_]bool{ true, false, true, false };
    462                 var v2: @Vector(4, bool) = [_]bool{ false, true, false, true };
    463                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 == v1)));
    464                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 == v2)));
    465                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 != v2)));
    466                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v2 != v2)));
    467             }
    468             {
    469                 var v1 = @splat(4, @as(u32, 0xc0ffeeee));
    470                 var v2: @Vector(4, c_uint) = v1;
    471                 var v3 = @splat(4, @as(u32, 0xdeadbeef));
    472                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 == v2)));
    473                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 == v3)));
    474                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 != v3)));
    475                 try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 != v2)));
    476             }
    477             {
    478                 // Comptime-known LHS/RHS
    479                 var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 };
    480                 const v2 = @splat(4, @as(u32, 2));
    481                 const v3: @Vector(4, bool) = [_]bool{ true, false, true, false };
    482                 try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v1 == v2)));
    483                 try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v2 == v1)));
    484             }
    485         }
    486     };
    487     try S.doTheTest();
    488     try comptime S.doTheTest();
    489 }
    490 
    491 test "vector division operators" {
    492     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    493     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    494     if (builtin.zig_backend == .stage2_aarch64) 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_spirv64) return error.SkipZigTest;
    498 
    499     const S = struct {
    500         fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
    501             if (!comptime std.meta.trait.isSignedInt(T)) {
    502                 const d0 = x / y;
    503                 for (@as([4]T, d0), 0..) |v, i| {
    504                     try expect(x[i] / y[i] == v);
    505                 }
    506             }
    507             const d1 = @divExact(x, y);
    508             for (@as([4]T, d1), 0..) |v, i| {
    509                 try expect(@divExact(x[i], y[i]) == v);
    510             }
    511             const d2 = @divFloor(x, y);
    512             for (@as([4]T, d2), 0..) |v, i| {
    513                 try expect(@divFloor(x[i], y[i]) == v);
    514             }
    515             const d3 = @divTrunc(x, y);
    516             for (@as([4]T, d3), 0..) |v, i| {
    517                 try expect(@divTrunc(x[i], y[i]) == v);
    518             }
    519         }
    520 
    521         fn doTheTestMod(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
    522             if ((!comptime std.meta.trait.isSignedInt(T)) and @typeInfo(T) != .Float) {
    523                 const r0 = x % y;
    524                 for (@as([4]T, r0), 0..) |v, i| {
    525                     try expect(x[i] % y[i] == v);
    526                 }
    527             }
    528             const r1 = @mod(x, y);
    529             for (@as([4]T, r1), 0..) |v, i| {
    530                 try expect(@mod(x[i], y[i]) == v);
    531             }
    532             const r2 = @rem(x, y);
    533             for (@as([4]T, r2), 0..) |v, i| {
    534                 try expect(@rem(x[i], y[i]) == v);
    535             }
    536         }
    537 
    538         fn doTheTest() !void {
    539             try doTheTestDiv(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, -1.0, -2.0 });
    540 
    541             try doTheTestDiv(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, -1.0, -2.0 });
    542             try doTheTestDiv(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, -1.0, -2.0 });
    543 
    544             try doTheTestMod(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, 0.5, 3.0 });
    545             try doTheTestMod(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, 0.5, 3.0 });
    546             try doTheTestMod(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, 0.5, 3.0 });
    547 
    548             try doTheTestDiv(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, -1, -2 });
    549             try doTheTestDiv(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, -1, -2 });
    550             try doTheTestDiv(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, -1, -2 });
    551             try doTheTestDiv(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, -1, -2 });
    552 
    553             try doTheTestMod(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, 4, 8 });
    554             try doTheTestMod(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, 4, 8 });
    555             try doTheTestMod(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, 4, 8 });
    556             try doTheTestMod(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, 4, 8 });
    557 
    558             try doTheTestDiv(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
    559             try doTheTestDiv(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
    560             try doTheTestDiv(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
    561             try doTheTestDiv(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
    562 
    563             try doTheTestMod(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
    564             try doTheTestMod(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
    565             try doTheTestMod(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
    566             try doTheTestMod(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
    567         }
    568     };
    569 
    570     try S.doTheTest();
    571     try comptime S.doTheTest();
    572 }
    573 
    574 test "vector bitwise not operator" {
    575     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    576     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    577     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    578     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    579     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    580     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    581 
    582     const S = struct {
    583         fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void {
    584             var y = ~x;
    585             for (@as([4]T, y), 0..) |v, i| {
    586                 try expect(~x[i] == v);
    587             }
    588         }
    589         fn doTheTest() !void {
    590             try doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
    591             try doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
    592             try doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
    593             try doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
    594 
    595             try doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
    596             try doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
    597             try doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
    598             try doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
    599         }
    600     };
    601 
    602     try S.doTheTest();
    603     try comptime S.doTheTest();
    604 }
    605 
    606 test "vector shift operators" {
    607     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    608     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    609     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    610     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    611     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    612     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    613 
    614     const S = struct {
    615         fn doTheTestShift(x: anytype, y: anytype) !void {
    616             const N = @typeInfo(@TypeOf(x)).Array.len;
    617             const TX = @typeInfo(@TypeOf(x)).Array.child;
    618             const TY = @typeInfo(@TypeOf(y)).Array.child;
    619 
    620             var xv = @as(@Vector(N, TX), x);
    621             var yv = @as(@Vector(N, TY), y);
    622 
    623             var z0 = xv >> yv;
    624             for (@as([N]TX, z0), 0..) |v, i| {
    625                 try expect(x[i] >> y[i] == v);
    626             }
    627             var z1 = xv << yv;
    628             for (@as([N]TX, z1), 0..) |v, i| {
    629                 try expect(x[i] << y[i] == v);
    630             }
    631         }
    632         fn doTheTestShiftExact(x: anytype, y: anytype, dir: enum { Left, Right }) !void {
    633             const N = @typeInfo(@TypeOf(x)).Array.len;
    634             const TX = @typeInfo(@TypeOf(x)).Array.child;
    635             const TY = @typeInfo(@TypeOf(y)).Array.child;
    636 
    637             var xv = @as(@Vector(N, TX), x);
    638             var yv = @as(@Vector(N, TY), y);
    639 
    640             var z = if (dir == .Left) @shlExact(xv, yv) else @shrExact(xv, yv);
    641             for (@as([N]TX, z), 0..) |v, i| {
    642                 const check = if (dir == .Left) x[i] << y[i] else x[i] >> y[i];
    643                 try expect(check == v);
    644             }
    645         }
    646         fn doTheTest() !void {
    647             try doTheTestShift([_]u8{ 0, 2, 4, math.maxInt(u8) }, [_]u3{ 2, 0, 2, 7 });
    648             try doTheTestShift([_]u16{ 0, 2, 4, math.maxInt(u16) }, [_]u4{ 2, 0, 2, 15 });
    649             try doTheTestShift([_]u24{ 0, 2, 4, math.maxInt(u24) }, [_]u5{ 2, 0, 2, 23 });
    650             try doTheTestShift([_]u32{ 0, 2, 4, math.maxInt(u32) }, [_]u5{ 2, 0, 2, 31 });
    651             try doTheTestShift([_]u64{ 0xfe, math.maxInt(u64) }, [_]u6{ 0, 63 });
    652 
    653             try doTheTestShift([_]i8{ 0, 2, 4, math.maxInt(i8) }, [_]u3{ 2, 0, 2, 7 });
    654             try doTheTestShift([_]i16{ 0, 2, 4, math.maxInt(i16) }, [_]u4{ 2, 0, 2, 7 });
    655             try doTheTestShift([_]i24{ 0, 2, 4, math.maxInt(i24) }, [_]u5{ 2, 0, 2, 7 });
    656             try doTheTestShift([_]i32{ 0, 2, 4, math.maxInt(i32) }, [_]u5{ 2, 0, 2, 7 });
    657             try doTheTestShift([_]i64{ 0xfe, math.maxInt(i64) }, [_]u6{ 0, 63 });
    658 
    659             try doTheTestShiftExact([_]u8{ 0, 1, 1 << 7, math.maxInt(u8) ^ 1 }, [_]u3{ 4, 0, 7, 1 }, .Right);
    660             try doTheTestShiftExact([_]u16{ 0, 1, 1 << 15, math.maxInt(u16) ^ 1 }, [_]u4{ 4, 0, 15, 1 }, .Right);
    661             try doTheTestShiftExact([_]u24{ 0, 1, 1 << 23, math.maxInt(u24) ^ 1 }, [_]u5{ 4, 0, 23, 1 }, .Right);
    662             try doTheTestShiftExact([_]u32{ 0, 1, 1 << 31, math.maxInt(u32) ^ 1 }, [_]u5{ 4, 0, 31, 1 }, .Right);
    663             try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 63, 0 }, .Right);
    664 
    665             try doTheTestShiftExact([_]u8{ 0, 1, 1, math.maxInt(u8) ^ (1 << 7) }, [_]u3{ 4, 0, 7, 1 }, .Left);
    666             try doTheTestShiftExact([_]u16{ 0, 1, 1, math.maxInt(u16) ^ (1 << 15) }, [_]u4{ 4, 0, 15, 1 }, .Left);
    667             try doTheTestShiftExact([_]u24{ 0, 1, 1, math.maxInt(u24) ^ (1 << 23) }, [_]u5{ 4, 0, 23, 1 }, .Left);
    668             try doTheTestShiftExact([_]u32{ 0, 1, 1, math.maxInt(u32) ^ (1 << 31) }, [_]u5{ 4, 0, 31, 1 }, .Left);
    669             try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 0, 63 }, .Left);
    670         }
    671     };
    672 
    673     switch (builtin.target.cpu.arch) {
    674         .x86,
    675         .aarch64,
    676         .aarch64_be,
    677         .aarch64_32,
    678         .arm,
    679         .armeb,
    680         .thumb,
    681         .thumbeb,
    682         .mips,
    683         .mipsel,
    684         .mips64,
    685         .mips64el,
    686         .riscv64,
    687         .sparc64,
    688         => {
    689             // LLVM miscompiles on this architecture
    690             // https://github.com/ziglang/zig/issues/4951
    691             return error.SkipZigTest;
    692         },
    693         else => {},
    694     }
    695 
    696     try S.doTheTest();
    697     try comptime S.doTheTest();
    698 }
    699 
    700 test "vector reduce operation" {
    701     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    702     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    703     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    704     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    705     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    706     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    707 
    708     const S = struct {
    709         fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
    710             const N = @typeInfo(@TypeOf(x)).Array.len;
    711             const TX = @typeInfo(@TypeOf(x)).Array.child;
    712 
    713             var r = @reduce(op, @as(@Vector(N, TX), x));
    714             switch (@typeInfo(TX)) {
    715                 .Int, .Bool => try expect(expected == r),
    716                 .Float => {
    717                     const expected_nan = math.isNan(expected);
    718                     const got_nan = math.isNan(r);
    719 
    720                     if (expected_nan and got_nan) {
    721                         // Do this check explicitly as two NaN values are never
    722                         // equal.
    723                     } else {
    724                         const F = @TypeOf(expected);
    725                         const tolerance = @sqrt(math.floatEps(TX));
    726                         try expect(std.math.approxEqRel(F, expected, r, tolerance));
    727                     }
    728                 },
    729                 else => unreachable,
    730             }
    731         }
    732         fn doTheTest() !void {
    733             try testReduce(.Add, [4]i16{ -9, -99, -999, -9999 }, @as(i32, -11106));
    734             try testReduce(.Add, [4]u16{ 9, 99, 999, 9999 }, @as(u32, 11106));
    735             try testReduce(.Add, [4]i32{ -9, -99, -999, -9999 }, @as(i32, -11106));
    736             try testReduce(.Add, [4]u32{ 9, 99, 999, 9999 }, @as(u32, 11106));
    737             try testReduce(.Add, [4]i64{ -9, -99, -999, -9999 }, @as(i64, -11106));
    738             try testReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106));
    739             try testReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106));
    740             try testReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106));
    741             try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9));
    742             try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9));
    743             try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9));
    744 
    745             try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));
    746             try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));
    747             try testReduce(.And, [4]u16{ 0xffff, 0xff55, 0xaaff, 0x1010 }, @as(u16, 0x10));
    748             try testReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010));
    749             try testReduce(.And, [4]u64{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u64, 0x1010));
    750 
    751             try testReduce(.Min, [4]i16{ -1, 2, 3, 4 }, @as(i16, -1));
    752             try testReduce(.Min, [4]u16{ 1, 2, 3, 4 }, @as(u16, 1));
    753             try testReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386));
    754             try testReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9));
    755 
    756             // LLVM 11 ERROR: Cannot select type
    757             // https://github.com/ziglang/zig/issues/7138
    758             if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) {
    759                 try testReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386));
    760                 try testReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9));
    761             }
    762 
    763             try testReduce(.Min, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, -386));
    764             try testReduce(.Min, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 9));
    765             try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0));
    766             try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));
    767             try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));
    768 
    769             try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4));
    770             try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4));
    771             try testReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567));
    772             try testReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999));
    773 
    774             // LLVM 11 ERROR: Cannot select type
    775             // https://github.com/ziglang/zig/issues/7138
    776             if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) {
    777                 try testReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567));
    778                 try testReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999));
    779             }
    780 
    781             try testReduce(.Max, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, 1234567));
    782             try testReduce(.Max, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 99999));
    783             try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9));
    784             try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));
    785             try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));
    786 
    787             try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24));
    788             try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24));
    789             try testReduce(.Mul, [4]i32{ -9, -99, -999, 999 }, @as(i32, -889218891));
    790             try testReduce(.Mul, [4]u32{ 1, 2, 3, 4 }, @as(u32, 24));
    791             try testReduce(.Mul, [4]i64{ 9, 99, 999, 9999 }, @as(i64, 8900199891));
    792             try testReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891));
    793             try testReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891));
    794             try testReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891));
    795             try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7));
    796             try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7));
    797             try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7));
    798 
    799             try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));
    800             try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));
    801             try testReduce(.Or, [4]u16{ 0xff00, 0xff00, 0xf0, 0xf }, ~@as(u16, 0));
    802             try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));
    803             try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff));
    804             try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff));
    805 
    806             try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));
    807             try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));
    808             try testReduce(.Xor, [4]u16{ 0x0000, 0x3333, 0x8888, 0x4444 }, ~@as(u16, 0));
    809             try testReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0));
    810             try testReduce(.Xor, [4]u64{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u64, 0xffffffff));
    811             try testReduce(.Xor, [4]u128{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u128, 0xffffffff));
    812 
    813             // Test the reduction on vectors containing NaNs.
    814             const f16_nan = math.nan(f16);
    815             const f32_nan = math.nan(f32);
    816             const f64_nan = math.nan(f64);
    817 
    818             try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
    819             try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
    820             try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
    821 
    822             // LLVM 11 ERROR: Cannot select type
    823             // https://github.com/ziglang/zig/issues/7138
    824             if (builtin.zig_backend != .stage2_llvm) {
    825                 try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9));
    826                 try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9));
    827                 try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9));
    828 
    829                 try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0));
    830                 try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0));
    831                 try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0));
    832             }
    833 
    834             try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
    835             try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
    836             try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
    837         }
    838     };
    839 
    840     try S.doTheTest();
    841     try comptime S.doTheTest();
    842 }
    843 
    844 test "vector @reduce comptime" {
    845     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    846     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    847     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    848     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    849 
    850     const value = @Vector(4, i32){ 1, -1, 1, -1 };
    851     const result = value > @splat(4, @as(i32, 0));
    852     // result is { true, false, true, false };
    853     try comptime expect(@TypeOf(result) == @Vector(4, bool));
    854     const is_all_true = @reduce(.And, result);
    855     try comptime expect(@TypeOf(is_all_true) == bool);
    856     try expect(is_all_true == false);
    857 }
    858 
    859 test "mask parameter of @shuffle is comptime scope" {
    860     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    861     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    862     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    863     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    864     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    865 
    866     const __v4hi = @Vector(4, i16);
    867     var v4_a = __v4hi{ 0, 0, 0, 0 };
    868     var v4_b = __v4hi{ 0, 0, 0, 0 };
    869     var shuffled: __v4hi = @shuffle(i16, v4_a, v4_b, @Vector(4, i32){
    870         std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
    871         std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
    872         std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
    873         std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
    874     });
    875     _ = shuffled;
    876 }
    877 
    878 test "saturating add" {
    879     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    880     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    881     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    882     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    883     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    884     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    885 
    886     const S = struct {
    887         fn doTheTest() !void {
    888             { // Broken out to avoid https://github.com/ziglang/zig/issues/11251
    889                 const u8x3 = @Vector(3, u8);
    890                 var lhs = u8x3{ 255, 254, 1 };
    891                 var rhs = u8x3{ 1, 2, 255 };
    892                 var result = lhs +| rhs;
    893                 const expected = u8x3{ 255, 255, 255 };
    894                 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
    895             }
    896             { // Broken out to avoid https://github.com/ziglang/zig/issues/11251
    897                 const i8x3 = @Vector(3, i8);
    898                 var lhs = i8x3{ 127, 126, 1 };
    899                 var rhs = i8x3{ 1, 2, 127 };
    900                 var result = lhs +| rhs;
    901                 const expected = i8x3{ 127, 127, 127 };
    902                 try expect(mem.eql(i8, &@as([3]i8, expected), &@as([3]i8, result)));
    903             }
    904         }
    905     };
    906     try S.doTheTest();
    907     try comptime S.doTheTest();
    908 }
    909 
    910 test "saturating subtraction" {
    911     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    912     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    913     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    914     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    915     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    916     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    917 
    918     const S = struct {
    919         fn doTheTest() !void {
    920             // Broken out to avoid https://github.com/ziglang/zig/issues/11251
    921             const u8x3 = @Vector(3, u8);
    922             var lhs = u8x3{ 0, 0, 0 };
    923             var rhs = u8x3{ 255, 255, 255 };
    924             var result = lhs -| rhs;
    925             const expected = u8x3{ 0, 0, 0 };
    926             try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
    927         }
    928     };
    929     try S.doTheTest();
    930     try comptime S.doTheTest();
    931 }
    932 
    933 test "saturating multiplication" {
    934     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    935     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    936     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    937     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    938     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    939     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    940 
    941     // TODO: once #9660 has been solved, remove this line
    942     if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest;
    943 
    944     const S = struct {
    945         fn doTheTest() !void {
    946             // Broken out to avoid https://github.com/ziglang/zig/issues/11251
    947             const u8x3 = @Vector(3, u8);
    948             var lhs = u8x3{ 2, 2, 2 };
    949             var rhs = u8x3{ 255, 255, 255 };
    950             var result = lhs *| rhs;
    951             const expected = u8x3{ 255, 255, 255 };
    952             try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
    953         }
    954     };
    955 
    956     try S.doTheTest();
    957     try comptime S.doTheTest();
    958 }
    959 
    960 test "saturating shift-left" {
    961     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    962     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    963     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    964     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    965     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    966     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    967 
    968     const S = struct {
    969         fn doTheTest() !void {
    970             // Broken out to avoid https://github.com/ziglang/zig/issues/11251
    971             const u8x3 = @Vector(3, u8);
    972             var lhs = u8x3{ 1, 1, 1 };
    973             var rhs = u8x3{ 255, 255, 255 };
    974             var result = lhs <<| rhs;
    975             const expected = u8x3{ 255, 255, 255 };
    976             try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
    977         }
    978     };
    979     try S.doTheTest();
    980     try comptime S.doTheTest();
    981 }
    982 
    983 test "multiplication-assignment operator with an array operand" {
    984     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
    985     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
    986     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
    987     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
    988     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
    989     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
    990 
    991     const S = struct {
    992         fn doTheTest() !void {
    993             var x: @Vector(3, i32) = .{ 1, 2, 3 };
    994             x *= [_]i32{ 4, 5, 6 };
    995             try expect(x[0] == 4);
    996             try expect(x[1] == 10);
    997             try expect(x[2] == 18);
    998         }
    999     };
   1000     try S.doTheTest();
   1001     try comptime S.doTheTest();
   1002 }
   1003 
   1004 test "@addWithOverflow" {
   1005     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1006     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1007     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1008     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1009     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1010     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1011 
   1012     const S = struct {
   1013         fn doTheTest() !void {
   1014             {
   1015                 var lhs = @Vector(4, u8){ 250, 250, 250, 250 };
   1016                 var rhs = @Vector(4, u8){ 0, 5, 6, 10 };
   1017                 var overflow = @addWithOverflow(lhs, rhs)[1];
   1018                 var expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
   1019                 try expectEqual(expected, overflow);
   1020             }
   1021             {
   1022                 var lhs = @Vector(4, i8){ -125, -125, 125, 125 };
   1023                 var rhs = @Vector(4, i8){ -3, -4, 2, 3 };
   1024                 var overflow = @addWithOverflow(lhs, rhs)[1];
   1025                 var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
   1026                 try expectEqual(expected, overflow);
   1027             }
   1028             {
   1029                 var lhs = @Vector(4, u1){ 0, 0, 1, 1 };
   1030                 var rhs = @Vector(4, u1){ 0, 1, 0, 1 };
   1031                 var overflow = @addWithOverflow(lhs, rhs)[1];
   1032                 var expected: @Vector(4, u1) = .{ 0, 0, 0, 1 };
   1033                 try expectEqual(expected, overflow);
   1034             }
   1035             {
   1036                 var lhs = @Vector(4, u0){ 0, 0, 0, 0 };
   1037                 var rhs = @Vector(4, u0){ 0, 0, 0, 0 };
   1038                 var overflow = @addWithOverflow(lhs, rhs)[1];
   1039                 var expected: @Vector(4, u1) = .{ 0, 0, 0, 0 };
   1040                 try expectEqual(expected, overflow);
   1041             }
   1042         }
   1043     };
   1044     try S.doTheTest();
   1045     try comptime S.doTheTest();
   1046 }
   1047 
   1048 test "@subWithOverflow" {
   1049     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1050     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1051     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1052     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1053     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1054     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1055 
   1056     const S = struct {
   1057         fn doTheTest() !void {
   1058             {
   1059                 var lhs = @Vector(2, u8){ 5, 5 };
   1060                 var rhs = @Vector(2, u8){ 5, 6 };
   1061                 var overflow = @subWithOverflow(lhs, rhs)[1];
   1062                 var expected: @Vector(2, u1) = .{ 0, 1 };
   1063                 try expectEqual(expected, overflow);
   1064             }
   1065             {
   1066                 var lhs = @Vector(4, i8){ -120, -120, 120, 120 };
   1067                 var rhs = @Vector(4, i8){ 8, 9, -7, -8 };
   1068                 var overflow = @subWithOverflow(lhs, rhs)[1];
   1069                 var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
   1070                 try expectEqual(expected, overflow);
   1071             }
   1072         }
   1073     };
   1074     try S.doTheTest();
   1075     try comptime S.doTheTest();
   1076 }
   1077 
   1078 test "@mulWithOverflow" {
   1079     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1080     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1081     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1082     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1083     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1084     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1085 
   1086     const S = struct {
   1087         fn doTheTest() !void {
   1088             var lhs = @Vector(4, u8){ 10, 10, 10, 10 };
   1089             var rhs = @Vector(4, u8){ 25, 26, 0, 30 };
   1090             var overflow = @mulWithOverflow(lhs, rhs)[1];
   1091             var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
   1092             try expectEqual(expected, overflow);
   1093         }
   1094     };
   1095     try S.doTheTest();
   1096     try comptime S.doTheTest();
   1097 }
   1098 
   1099 test "@shlWithOverflow" {
   1100     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1101     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1102     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1103     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1104     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1105     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1106 
   1107     const S = struct {
   1108         fn doTheTest() !void {
   1109             var lhs = @Vector(4, u8){ 0, 1, 8, 255 };
   1110             var rhs = @Vector(4, u3){ 7, 7, 7, 7 };
   1111             var overflow = @shlWithOverflow(lhs, rhs)[1];
   1112             var expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
   1113             try expectEqual(expected, overflow);
   1114         }
   1115     };
   1116     try S.doTheTest();
   1117     try comptime S.doTheTest();
   1118 }
   1119 
   1120 test "alignment of vectors" {
   1121     try expect(@alignOf(@Vector(2, u8)) == 2);
   1122     try expect(@alignOf(@Vector(2, u1)) == 1);
   1123     try expect(@alignOf(@Vector(1, u1)) == 1);
   1124     try expect(@alignOf(@Vector(2, u16)) == 4);
   1125 }
   1126 
   1127 test "loading the second vector from a slice of vectors" {
   1128     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1129     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1130     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1131     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1132     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1133 
   1134     @setRuntimeSafety(false);
   1135     var small_bases = [2]@Vector(2, u8){
   1136         @Vector(2, u8){ 0, 1 },
   1137         @Vector(2, u8){ 2, 3 },
   1138     };
   1139     var a: []const @Vector(2, u8) = &small_bases;
   1140     var a4 = a[1][1];
   1141     try expect(a4 == 3);
   1142 }
   1143 
   1144 test "array of vectors is copied" {
   1145     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1146     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1147     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1148     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1149     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1150 
   1151     const Vec3 = @Vector(3, i32);
   1152     var points = [_]Vec3{
   1153         Vec3{ 404, -588, -901 },
   1154         Vec3{ 528, -643, 409 },
   1155         Vec3{ -838, 591, 734 },
   1156         Vec3{ 390, -675, -793 },
   1157         Vec3{ -537, -823, -458 },
   1158         Vec3{ -485, -357, 347 },
   1159         Vec3{ -345, -311, 381 },
   1160         Vec3{ -661, -816, -575 },
   1161     };
   1162     var points2: [20]Vec3 = undefined;
   1163     points2[0..points.len].* = points;
   1164     try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });
   1165 }
   1166 
   1167 test "byte vector initialized in inline function" {
   1168     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1169     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1170     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1171     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1172     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1173     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1174 
   1175     if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and
   1176         builtin.cpu.features.isEnabled(@intFromEnum(std.Target.x86.Feature.avx512f)))
   1177     {
   1178         // TODO https://github.com/ziglang/zig/issues/13279
   1179         return error.SkipZigTest;
   1180     }
   1181 
   1182     const S = struct {
   1183         fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
   1184             return .{ e0, e1, e2, e3 };
   1185         }
   1186 
   1187         fn all(vb: @Vector(4, bool)) bool {
   1188             return @reduce(.And, vb);
   1189         }
   1190     };
   1191 
   1192     try expect(S.all(S.boolx4(true, true, true, true)));
   1193 }
   1194 
   1195 test "zero divisor" {
   1196     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1197     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1198     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1199     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1200 
   1201     const zeros = @Vector(2, f32){ 0.0, 0.0 };
   1202     const ones = @Vector(2, f32){ 1.0, 1.0 };
   1203 
   1204     const v1 = zeros / ones;
   1205     const v2 = @divExact(zeros, ones);
   1206     const v3 = @divTrunc(zeros, ones);
   1207     const v4 = @divFloor(zeros, ones);
   1208 
   1209     _ = v1[0];
   1210     _ = v2[0];
   1211     _ = v3[0];
   1212     _ = v4[0];
   1213 }
   1214 
   1215 test "zero multiplicand" {
   1216     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1217     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1218     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1219     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1220     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1221 
   1222     const zeros = @Vector(2, u32){ 0.0, 0.0 };
   1223     var ones = @Vector(2, u32){ 1.0, 1.0 };
   1224 
   1225     _ = (ones * zeros)[0];
   1226     _ = (zeros * zeros)[0];
   1227     _ = (zeros * ones)[0];
   1228 
   1229     _ = (ones *| zeros)[0];
   1230     _ = (zeros *| zeros)[0];
   1231     _ = (zeros *| ones)[0];
   1232 
   1233     _ = (ones *% zeros)[0];
   1234     _ = (zeros *% zeros)[0];
   1235     _ = (zeros *% ones)[0];
   1236 }
   1237 
   1238 test "@intCast to u0" {
   1239     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1240     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1241     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1242     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1243     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1244     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1245 
   1246     var zeros = @Vector(2, u32){ 0, 0 };
   1247     const casted = @as(@Vector(2, u0), @intCast(zeros));
   1248 
   1249     _ = casted[0];
   1250 }
   1251 
   1252 test "modRem with zero divisor" {
   1253     comptime {
   1254         var zeros = @Vector(2, u32){ 0, 0 };
   1255         const ones = @Vector(2, u32){ 1, 1 };
   1256 
   1257         zeros %= ones;
   1258         _ = zeros[0];
   1259     }
   1260 }
   1261 
   1262 test "array operands to shuffle are coerced to vectors" {
   1263     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1264     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1265     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1266     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1267     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1268     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1269 
   1270     const mask = [5]i32{ -1, 0, 1, 2, 3 };
   1271 
   1272     var a = [5]u32{ 3, 5, 7, 9, 0 };
   1273     var b = @shuffle(u32, a, @splat(5, @as(u24, 0)), mask);
   1274     try expectEqual([_]u32{ 0, 3, 5, 7, 9 }, b);
   1275 }
   1276 
   1277 test "load packed vector element" {
   1278     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1279     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1280     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1281     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1282     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1283     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1284 
   1285     var x: @Vector(2, u15) = .{ 1, 4 };
   1286     try expect((&x[0]).* == 1);
   1287     try expect((&x[1]).* == 4);
   1288 }
   1289 
   1290 test "store packed vector element" {
   1291     if (builtin.zig_backend == .stage2_aarch64) 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_spirv64) return error.SkipZigTest;
   1295     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1296     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1297     if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
   1298 
   1299     var v = @Vector(4, u1){ 1, 1, 1, 1 };
   1300     try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v);
   1301     var index: usize = 0;
   1302     v[index] = 0;
   1303     try expectEqual(@Vector(4, u1){ 0, 1, 1, 1 }, v);
   1304 }
   1305 
   1306 test "store to vector in slice" {
   1307     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1308     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1309     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1310     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1311     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1312     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1313 
   1314     var v = [_]@Vector(3, f32){
   1315         .{ 1, 1, 1 },
   1316         .{ 0, 0, 0 },
   1317     };
   1318     var s: []@Vector(3, f32) = &v;
   1319     var i: usize = 1;
   1320     s[i] = s[0];
   1321     try expectEqual(v[1], v[0]);
   1322 }
   1323 
   1324 test "addition of vectors represented as strings" {
   1325     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1326     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1327     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
   1328 
   1329     const V = @Vector(3, u8);
   1330     const foo: V = "foo".*;
   1331     const bar: V = @typeName(u32).*;
   1332     try expectEqual(V{ 219, 162, 161 }, foo + bar);
   1333 }
   1334 
   1335 test "compare vectors with different element types" {
   1336     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1337     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1338     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1339     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1340     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1341     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
   1342 
   1343     var a: @Vector(2, u8) = .{ 1, 2 };
   1344     var b: @Vector(2, u9) = .{ 3, 0 };
   1345     try expectEqual(@Vector(2, bool){ true, false }, a < b);
   1346 }
   1347 
   1348 test "vector pointer is indexable" {
   1349     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1350     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1351     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1352     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1353     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1354     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
   1355 
   1356     const V = @Vector(2, u32);
   1357 
   1358     const x: V = .{ 123, 456 };
   1359     comptime assert(@TypeOf(&(&x)[0]) == *const u32); // validate constness
   1360     try expectEqual(@as(u32, 123), (&x)[0]);
   1361     try expectEqual(@as(u32, 456), (&x)[1]);
   1362 
   1363     var y: V = .{ 123, 456 };
   1364     comptime assert(@TypeOf(&(&y)[0]) == *u32); // validate constness
   1365     try expectEqual(@as(u32, 123), (&y)[0]);
   1366     try expectEqual(@as(u32, 456), (&y)[1]);
   1367 
   1368     (&y)[0] = 100;
   1369     (&y)[1] = 200;
   1370     try expectEqual(@as(u32, 100), (&y)[0]);
   1371     try expectEqual(@as(u32, 200), (&y)[1]);
   1372 }
   1373 
   1374 test "boolean vector with 2 or more booleans" {
   1375     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
   1376     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
   1377     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
   1378     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
   1379     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
   1380     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
   1381 
   1382     // TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>:
   1383     if (!(builtin.os.tag == .linux and builtin.cpu.arch == .x86_64)) return;
   1384 
   1385     const vec1 = @Vector(2, bool){ true, true };
   1386     _ = vec1;
   1387 
   1388     const vec2 = @Vector(3, bool){ true, true, true };
   1389     _ = vec2;
   1390 }