zig

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

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