zig/test/behavior/vector.zig
Xavier Bouchoux 77dd64b5f4 Sema: fix coerceArrayLike() for vectors with padding
as explainded at https://llvm.org/docs/LangRef.html#vector-type :

"In general vector elements are laid out in memory in the same way as array types.
Such an analogy works fine as long as the vector elements are byte sized.
However, when the elements of the vector aren’t byte sized it gets a bit more complicated.
One way to describe the layout is by describing what happens when a vector such
as <N x iM> is bitcasted to an integer type with N*M bits, and then following the
rules for storing such an integer to memory."

"When <N*M> isn’t evenly divisible by the byte size the exact memory layout
is unspecified (just like it is for an integral type of the same size)."
2023-08-10 16:10:59 -07:00

1508 lines
66 KiB
Zig

const std = @import("std");
const builtin = @import("builtin");
const mem = std.mem;
const math = std.math;
const assert = std.debug.assert;
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
test "implicit cast vector to array - bool" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
const a: @Vector(4, bool) = [_]bool{ true, false, true, false };
const result_array: [4]bool = a;
try expect(mem.eql(bool, &result_array, &[4]bool{ true, false, true, false }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector wrap operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
try expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 }));
try expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 }));
try expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 }));
var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };
try expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector bin compares with mem.eql" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };
try expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false }));
try expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true }));
try expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false }));
try expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true }));
try expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false }));
try expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector int operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
try expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 }));
try expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 }));
try expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 }));
try expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector float operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, T) = [4]T{ 10, 20, 30, 40 };
var x: @Vector(4, T) = [4]T{ 1, 2, 3, 4 };
try expect(mem.eql(T, &@as([4]T, v + x), &[4]T{ 11, 22, 33, 44 }));
try expect(mem.eql(T, &@as([4]T, v - x), &[4]T{ 9, 18, 27, 36 }));
try expect(mem.eql(T, &@as([4]T, v * x), &[4]T{ 10, 40, 90, 160 }));
try expect(mem.eql(T, &@as([4]T, -x), &[4]T{ -1, -2, -3, -4 }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
}
test "vector bit operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
try expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
try expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
try expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "implicit cast vector to array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
var result_array: [4]i32 = a;
result_array = a;
try expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 }));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "array to vector" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var foo: f32 = 3.14;
var arr = [4]f32{ foo, 1.5, 0.0, 0.0 };
var vec: @Vector(4, f32) = arr;
try expect(mem.eql(f32, &@as([4]f32, vec), &arr));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "array vector coercion - odd sizes" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var foo1: i48 = 124578;
var vec1: @Vector(2, i48) = [2]i48{ foo1, 1 };
var arr1: [2]i48 = vec1;
try expect(vec1[0] == foo1 and vec1[1] == 1);
try expect(arr1[0] == foo1 and arr1[1] == 1);
var foo2: u4 = 5;
var vec2: @Vector(2, u4) = [2]u4{ foo2, 1 };
var arr2: [2]u4 = vec2;
try expect(vec2[0] == foo2 and vec2[1] == 1);
try expect(arr2[0] == foo2 and arr2[1] == 1);
var foo3: u13 = 13;
var vec3: @Vector(3, u13) = [3]u13{ foo3, 0, 1 };
var arr3: [3]u13 = vec3;
try expect(vec3[0] == foo3 and vec3[1] == 0 and vec3[2] == 1);
try expect(arr3[0] == foo3 and arr3[1] == 0 and arr3[2] == 1);
var arr4 = [4:0]u24{ foo3, foo2, 0, 1 };
var vec4: @Vector(4, u24) = arr4;
try expect(vec4[0] == foo3 and vec4[1] == foo2 and vec4[2] == 0 and vec4[3] == 1);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "array to vector with element type coercion" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var foo: f16 = 3.14;
var arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 };
var vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 };
try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "peer type resolution with coercible element types" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var b: @Vector(2, u8) = .{ 1, 2 };
var a: @Vector(2, u16) = .{ 2, 1 };
var t: bool = true;
var c = if (t) a else b;
try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
}
};
try comptime S.doTheTest();
}
test "tuple to vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
// Regressed with LLVM 14:
// https://github.com/ziglang/zig/issues/12012
return error.SkipZigTest;
}
const S = struct {
fn doTheTest() !void {
const Vec3 = @Vector(3, i32);
var v: Vec3 = .{ 1, 0, 0 };
for ([_]Vec3{ .{ 0, 1, 0 }, .{ 0, 0, 1 } }) |it| {
v += it;
}
try std.testing.expectEqual(v, Vec3{ 1, 1, 1 });
try std.testing.expectEqual(v, .{ 1, 1, 1 });
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector casts of sizes not divisible by 8" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{
var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };
var x: [4]u3 = v;
try expect(mem.eql(u3, &x, &@as([4]u3, v)));
}
{
var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };
var x: [4]u2 = v;
try expect(mem.eql(u2, &x, &@as([4]u2, v)));
}
{
var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };
var x: [4]u1 = v;
try expect(mem.eql(u1, &x, &@as([4]u1, v)));
}
{
var v: @Vector(4, bool) = [4]bool{ false, false, true, false };
var x: [4]bool = v;
try expect(mem.eql(bool, &x, &@as([4]bool, v)));
}
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector @splat" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and
builtin.os.tag == .macos)
{
// LLVM 15 regression: https://github.com/ziglang/zig/issues/12827
return error.SkipZigTest;
}
const S = struct {
fn testForT(comptime N: comptime_int, v: anytype) !void {
const T = @TypeOf(v);
var vec: @Vector(N, T) = @splat(v);
var as_array = @as([N]T, vec);
for (as_array) |elem| try expect(v == elem);
}
fn doTheTest() !void {
// Splats with multiple-of-8 bit types that fill a 128bit vector.
try testForT(16, @as(u8, 0xEE));
try testForT(8, @as(u16, 0xBEEF));
try testForT(4, @as(u32, 0xDEADBEEF));
try testForT(2, @as(u64, 0xCAFEF00DDEADBEEF));
try testForT(8, @as(f16, 3.1415));
try testForT(4, @as(f32, 3.1415));
try testForT(2, @as(f64, 3.1415));
// Same but fill more than 128 bits.
try testForT(16 * 2, @as(u8, 0xEE));
try testForT(8 * 2, @as(u16, 0xBEEF));
try testForT(4 * 2, @as(u32, 0xDEADBEEF));
try testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF));
try testForT(8 * 2, @as(f16, 3.1415));
try testForT(4 * 2, @as(f32, 3.1415));
try testForT(2 * 2, @as(f64, 3.1415));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "load vector elements via comptime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
try expect(v[0] == 1);
try expect(v[1] == 2);
try expect(loadv(&v[2]) == 3);
}
fn loadv(ptr: anytype) i32 {
return ptr.*;
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "store vector elements via comptime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
v[2] = 42;
try expect(v[1] == 5);
v[3] = -364;
try expect(v[2] == 42);
try expect(-364 == v[3]);
storev(&v[0], 100);
try expect(v[0] == 100);
}
fn storev(ptr: anytype, x: i32) void {
ptr.* = x;
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "load vector elements via runtime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
var i: u32 = 0;
try expect(v[i] == 1);
i += 1;
try expect(v[i] == 2);
i += 1;
try expect(v[i] == 3);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "store vector elements via runtime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
var i: u32 = 2;
v[i] = 1;
try expect(v[1] == 5);
try expect(v[2] == 1);
i += 1;
v[i] = -364;
try expect(-364 == v[3]);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "initialize vector which is a struct field" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const Vec4Obj = struct {
data: @Vector(4, f32),
};
const S = struct {
fn doTheTest() !void {
var foo = Vec4Obj{
.data = [_]f32{ 1, 2, 3, 4 },
};
_ = foo;
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector comparison operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{
const V = @Vector(4, bool);
var v1: V = [_]bool{ true, false, true, false };
var v2: V = [_]bool{ false, true, false, true };
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v1)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v2)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v2)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v2 != v2)));
}
{
const V = @Vector(4, bool);
var v1: @Vector(4, u32) = @splat(0xc0ffeeee);
var v2: @Vector(4, c_uint) = v1;
var v3: @Vector(4, u32) = @splat(0xdeadbeef);
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v2)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v3)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v3)));
try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 != v2)));
}
{
// Comptime-known LHS/RHS
var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 };
const v2: @Vector(4, u32) = @splat(2);
const v3: @Vector(4, bool) = [_]bool{ true, false, true, false };
try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v1 == v2)));
try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v2 == v1)));
}
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector division operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
if (!comptime std.meta.trait.isSignedInt(T)) {
const d0 = x / y;
for (@as([4]T, d0), 0..) |v, i| {
try expect(x[i] / y[i] == v);
}
}
const d1 = @divExact(x, y);
for (@as([4]T, d1), 0..) |v, i| {
try expect(@divExact(x[i], y[i]) == v);
}
const d2 = @divFloor(x, y);
for (@as([4]T, d2), 0..) |v, i| {
try expect(@divFloor(x[i], y[i]) == v);
}
const d3 = @divTrunc(x, y);
for (@as([4]T, d3), 0..) |v, i| {
try expect(@divTrunc(x[i], y[i]) == v);
}
}
fn doTheTestMod(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
if ((!comptime std.meta.trait.isSignedInt(T)) and @typeInfo(T) != .Float) {
const r0 = x % y;
for (@as([4]T, r0), 0..) |v, i| {
try expect(x[i] % y[i] == v);
}
}
const r1 = @mod(x, y);
for (@as([4]T, r1), 0..) |v, i| {
try expect(@mod(x[i], y[i]) == v);
}
const r2 = @rem(x, y);
for (@as([4]T, r2), 0..) |v, i| {
try expect(@rem(x[i], y[i]) == v);
}
}
fn doTheTest() !void {
try doTheTestDiv(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, -1.0, -2.0 });
try doTheTestDiv(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, -1.0, -2.0 });
try doTheTestDiv(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, -1.0, -2.0 });
try doTheTestMod(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, 0.5, 3.0 });
try doTheTestMod(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, 0.5, 3.0 });
try doTheTestMod(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, 0.5, 3.0 });
try doTheTestDiv(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, -1, -2 });
try doTheTestDiv(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, -1, -2 });
try doTheTestDiv(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, -1, -2 });
try doTheTestDiv(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, -1, -2 });
try doTheTestMod(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, 4, 8 });
try doTheTestMod(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, 4, 8 });
try doTheTestMod(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, 4, 8 });
try doTheTestMod(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, 4, 8 });
try doTheTestDiv(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
try doTheTestDiv(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
try doTheTestDiv(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
try doTheTestDiv(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
try doTheTestMod(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 });
try doTheTestMod(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 });
try doTheTestMod(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 });
try doTheTestMod(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 });
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector bitwise not operator" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void {
var y = ~x;
for (@as([4]T, y), 0..) |v, i| {
try expect(~x[i] == v);
}
}
fn doTheTest() !void {
try doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
try doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
try doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
try doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
try doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
try doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
try doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
try doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector shift operators" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTestShift(x: anytype, y: anytype) !void {
const N = @typeInfo(@TypeOf(x)).Array.len;
const TX = @typeInfo(@TypeOf(x)).Array.child;
const TY = @typeInfo(@TypeOf(y)).Array.child;
var xv = @as(@Vector(N, TX), x);
var yv = @as(@Vector(N, TY), y);
var z0 = xv >> yv;
for (@as([N]TX, z0), 0..) |v, i| {
try expect(x[i] >> y[i] == v);
}
var z1 = xv << yv;
for (@as([N]TX, z1), 0..) |v, i| {
try expect(x[i] << y[i] == v);
}
}
fn doTheTestShiftExact(x: anytype, y: anytype, dir: enum { Left, Right }) !void {
const N = @typeInfo(@TypeOf(x)).Array.len;
const TX = @typeInfo(@TypeOf(x)).Array.child;
const TY = @typeInfo(@TypeOf(y)).Array.child;
var xv = @as(@Vector(N, TX), x);
var yv = @as(@Vector(N, TY), y);
var z = if (dir == .Left) @shlExact(xv, yv) else @shrExact(xv, yv);
for (@as([N]TX, z), 0..) |v, i| {
const check = if (dir == .Left) x[i] << y[i] else x[i] >> y[i];
try expect(check == v);
}
}
fn doTheTest() !void {
try doTheTestShift([_]u8{ 0, 2, 4, math.maxInt(u8) }, [_]u3{ 2, 0, 2, 7 });
try doTheTestShift([_]u16{ 0, 2, 4, math.maxInt(u16) }, [_]u4{ 2, 0, 2, 15 });
try doTheTestShift([_]u24{ 0, 2, 4, math.maxInt(u24) }, [_]u5{ 2, 0, 2, 23 });
try doTheTestShift([_]u32{ 0, 2, 4, math.maxInt(u32) }, [_]u5{ 2, 0, 2, 31 });
try doTheTestShift([_]u64{ 0xfe, math.maxInt(u64) }, [_]u6{ 0, 63 });
try doTheTestShift([_]i8{ 0, 2, 4, math.maxInt(i8) }, [_]u3{ 2, 0, 2, 7 });
try doTheTestShift([_]i16{ 0, 2, 4, math.maxInt(i16) }, [_]u4{ 2, 0, 2, 7 });
try doTheTestShift([_]i24{ 0, 2, 4, math.maxInt(i24) }, [_]u5{ 2, 0, 2, 7 });
try doTheTestShift([_]i32{ 0, 2, 4, math.maxInt(i32) }, [_]u5{ 2, 0, 2, 7 });
try doTheTestShift([_]i64{ 0xfe, math.maxInt(i64) }, [_]u6{ 0, 63 });
try doTheTestShiftExact([_]u8{ 0, 1, 1 << 7, math.maxInt(u8) ^ 1 }, [_]u3{ 4, 0, 7, 1 }, .Right);
try doTheTestShiftExact([_]u16{ 0, 1, 1 << 15, math.maxInt(u16) ^ 1 }, [_]u4{ 4, 0, 15, 1 }, .Right);
try doTheTestShiftExact([_]u24{ 0, 1, 1 << 23, math.maxInt(u24) ^ 1 }, [_]u5{ 4, 0, 23, 1 }, .Right);
try doTheTestShiftExact([_]u32{ 0, 1, 1 << 31, math.maxInt(u32) ^ 1 }, [_]u5{ 4, 0, 31, 1 }, .Right);
try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 63, 0 }, .Right);
try doTheTestShiftExact([_]u8{ 0, 1, 1, math.maxInt(u8) ^ (1 << 7) }, [_]u3{ 4, 0, 7, 1 }, .Left);
try doTheTestShiftExact([_]u16{ 0, 1, 1, math.maxInt(u16) ^ (1 << 15) }, [_]u4{ 4, 0, 15, 1 }, .Left);
try doTheTestShiftExact([_]u24{ 0, 1, 1, math.maxInt(u24) ^ (1 << 23) }, [_]u5{ 4, 0, 23, 1 }, .Left);
try doTheTestShiftExact([_]u32{ 0, 1, 1, math.maxInt(u32) ^ (1 << 31) }, [_]u5{ 4, 0, 31, 1 }, .Left);
try doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 0, 63 }, .Left);
}
};
switch (builtin.target.cpu.arch) {
.x86,
.aarch64,
.aarch64_be,
.aarch64_32,
.arm,
.armeb,
.thumb,
.thumbeb,
.mips,
.mipsel,
.mips64,
.mips64el,
.riscv64,
.sparc64,
=> {
// LLVM miscompiles on this architecture
// https://github.com/ziglang/zig/issues/4951
return error.SkipZigTest;
},
else => {},
}
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector reduce operation" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
const S = struct {
fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
const N = @typeInfo(@TypeOf(x)).Array.len;
const TX = @typeInfo(@TypeOf(x)).Array.child;
var r = @reduce(op, @as(@Vector(N, TX), x));
switch (@typeInfo(TX)) {
.Int, .Bool => try expect(expected == r),
.Float => {
const expected_nan = math.isNan(expected);
const got_nan = math.isNan(r);
if (expected_nan and got_nan) {
// Do this check explicitly as two NaN values are never
// equal.
} else {
const F = @TypeOf(expected);
const tolerance = @sqrt(math.floatEps(TX));
try expect(std.math.approxEqRel(F, expected, r, tolerance));
}
},
else => unreachable,
}
}
fn doTheTest() !void {
try testReduce(.Add, [4]i16{ -9, -99, -999, -9999 }, @as(i32, -11106));
try testReduce(.Add, [4]u16{ 9, 99, 999, 9999 }, @as(u32, 11106));
try testReduce(.Add, [4]i32{ -9, -99, -999, -9999 }, @as(i32, -11106));
try testReduce(.Add, [4]u32{ 9, 99, 999, 9999 }, @as(u32, 11106));
try testReduce(.Add, [4]i64{ -9, -99, -999, -9999 }, @as(i64, -11106));
try testReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106));
try testReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106));
try testReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106));
try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9));
try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9));
try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9));
try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));
try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));
try testReduce(.And, [4]u16{ 0xffff, 0xff55, 0xaaff, 0x1010 }, @as(u16, 0x10));
try testReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010));
try testReduce(.And, [4]u64{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u64, 0x1010));
try testReduce(.Min, [4]i16{ -1, 2, 3, 4 }, @as(i16, -1));
try testReduce(.Min, [4]u16{ 1, 2, 3, 4 }, @as(u16, 1));
try testReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386));
try testReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9));
// LLVM 11 ERROR: Cannot select type
// https://github.com/ziglang/zig/issues/7138
if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) {
try testReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386));
try testReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9));
}
try testReduce(.Min, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, -386));
try testReduce(.Min, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 9));
try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0));
try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));
try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));
try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4));
try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4));
try testReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567));
try testReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999));
// LLVM 11 ERROR: Cannot select type
// https://github.com/ziglang/zig/issues/7138
if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) {
try testReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567));
try testReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999));
}
try testReduce(.Max, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, 1234567));
try testReduce(.Max, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 99999));
try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9));
try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));
try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));
try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24));
try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24));
try testReduce(.Mul, [4]i32{ -9, -99, -999, 999 }, @as(i32, -889218891));
try testReduce(.Mul, [4]u32{ 1, 2, 3, 4 }, @as(u32, 24));
try testReduce(.Mul, [4]i64{ 9, 99, 999, 9999 }, @as(i64, 8900199891));
try testReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891));
try testReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891));
try testReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891));
try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7));
try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7));
try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7));
try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));
try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));
try testReduce(.Or, [4]u16{ 0xff00, 0xff00, 0xf0, 0xf }, ~@as(u16, 0));
try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));
try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff));
try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff));
try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));
try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));
try testReduce(.Xor, [4]u16{ 0x0000, 0x3333, 0x8888, 0x4444 }, ~@as(u16, 0));
try testReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0));
try testReduce(.Xor, [4]u64{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u64, 0xffffffff));
try testReduce(.Xor, [4]u128{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u128, 0xffffffff));
// Test the reduction on vectors containing NaNs.
const f16_nan = math.nan(f16);
const f32_nan = math.nan(f32);
const f64_nan = math.nan(f64);
try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
// LLVM 11 ERROR: Cannot select type
// https://github.com/ziglang/zig/issues/7138
if (builtin.zig_backend != .stage2_llvm) {
try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9));
try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9));
try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9));
try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0));
try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0));
try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0));
}
try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "vector @reduce comptime" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const V = @Vector(4, i32);
const value = V{ 1, -1, 1, -1 };
const result = value > @as(V, @splat(0));
// result is { true, false, true, false };
try comptime expect(@TypeOf(result) == @Vector(4, bool));
const is_all_true = @reduce(.And, result);
try comptime expect(@TypeOf(is_all_true) == bool);
try expect(is_all_true == false);
}
test "mask parameter of @shuffle is comptime scope" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const __v4hi = @Vector(4, i16);
var v4_a = __v4hi{ 0, 0, 0, 0 };
var v4_b = __v4hi{ 0, 0, 0, 0 };
var shuffled: __v4hi = @shuffle(i16, v4_a, v4_b, @Vector(4, i32){
std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
std.zig.c_translation.shuffleVectorIndex(0, @typeInfo(@TypeOf(v4_a)).Vector.len),
});
_ = shuffled;
}
test "saturating add" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{ // Broken out to avoid https://github.com/ziglang/zig/issues/11251
const u8x3 = @Vector(3, u8);
var lhs = u8x3{ 255, 254, 1 };
var rhs = u8x3{ 1, 2, 255 };
var result = lhs +| rhs;
const expected = u8x3{ 255, 255, 255 };
try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
}
{ // Broken out to avoid https://github.com/ziglang/zig/issues/11251
const i8x3 = @Vector(3, i8);
var lhs = i8x3{ 127, 126, 1 };
var rhs = i8x3{ 1, 2, 127 };
var result = lhs +| rhs;
const expected = i8x3{ 127, 127, 127 };
try expect(mem.eql(i8, &@as([3]i8, expected), &@as([3]i8, result)));
}
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "saturating subtraction" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
// Broken out to avoid https://github.com/ziglang/zig/issues/11251
const u8x3 = @Vector(3, u8);
var lhs = u8x3{ 0, 0, 0 };
var rhs = u8x3{ 255, 255, 255 };
var result = lhs -| rhs;
const expected = u8x3{ 0, 0, 0 };
try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "saturating multiplication" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
// TODO: once #9660 has been solved, remove this line
if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
// Broken out to avoid https://github.com/ziglang/zig/issues/11251
const u8x3 = @Vector(3, u8);
var lhs = u8x3{ 2, 2, 2 };
var rhs = u8x3{ 255, 255, 255 };
var result = lhs *| rhs;
const expected = u8x3{ 255, 255, 255 };
try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "saturating shift-left" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
// Broken out to avoid https://github.com/ziglang/zig/issues/11251
const u8x3 = @Vector(3, u8);
var lhs = u8x3{ 1, 1, 1 };
var rhs = u8x3{ 255, 255, 255 };
var result = lhs <<| rhs;
const expected = u8x3{ 255, 255, 255 };
try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "multiplication-assignment operator with an array operand" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var x: @Vector(3, i32) = .{ 1, 2, 3 };
x *= [_]i32{ 4, 5, 6 };
try expect(x[0] == 4);
try expect(x[1] == 10);
try expect(x[2] == 18);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "@addWithOverflow" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{
var lhs = @Vector(4, u8){ 250, 250, 250, 250 };
var rhs = @Vector(4, u8){ 0, 5, 6, 10 };
var overflow = @addWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
try expectEqual(expected, overflow);
}
{
var lhs = @Vector(4, i8){ -125, -125, 125, 125 };
var rhs = @Vector(4, i8){ -3, -4, 2, 3 };
var overflow = @addWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
try expectEqual(expected, overflow);
}
{
var lhs = @Vector(4, u1){ 0, 0, 1, 1 };
var rhs = @Vector(4, u1){ 0, 1, 0, 1 };
var overflow = @addWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 0, 0, 1 };
try expectEqual(expected, overflow);
}
{
var lhs = @Vector(4, u0){ 0, 0, 0, 0 };
var rhs = @Vector(4, u0){ 0, 0, 0, 0 };
var overflow = @addWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 0, 0, 0 };
try expectEqual(expected, overflow);
}
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "@subWithOverflow" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{
var lhs = @Vector(2, u8){ 5, 5 };
var rhs = @Vector(2, u8){ 5, 6 };
var overflow = @subWithOverflow(lhs, rhs)[1];
var expected: @Vector(2, u1) = .{ 0, 1 };
try expectEqual(expected, overflow);
}
{
var lhs = @Vector(4, i8){ -120, -120, 120, 120 };
var rhs = @Vector(4, i8){ 8, 9, -7, -8 };
var overflow = @subWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
try expectEqual(expected, overflow);
}
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "@mulWithOverflow" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var lhs = @Vector(4, u8){ 10, 10, 10, 10 };
var rhs = @Vector(4, u8){ 25, 26, 0, 30 };
var overflow = @mulWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 1, 0, 1 };
try expectEqual(expected, overflow);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "@shlWithOverflow" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
var lhs = @Vector(4, u8){ 0, 1, 8, 255 };
var rhs = @Vector(4, u3){ 7, 7, 7, 7 };
var overflow = @shlWithOverflow(lhs, rhs)[1];
var expected: @Vector(4, u1) = .{ 0, 0, 1, 1 };
try expectEqual(expected, overflow);
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
test "alignment of vectors" {
try expect(@alignOf(@Vector(2, u8)) == 2);
try expect(@alignOf(@Vector(2, u1)) == 1);
try expect(@alignOf(@Vector(1, u1)) == 1);
try expect(@alignOf(@Vector(2, u16)) == 4);
}
test "loading the second vector from a slice of vectors" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
@setRuntimeSafety(false);
var small_bases = [2]@Vector(2, u8){
@Vector(2, u8){ 0, 1 },
@Vector(2, u8){ 2, 3 },
};
var a: []const @Vector(2, u8) = &small_bases;
var a4 = a[1][1];
try expect(a4 == 3);
}
test "array of vectors is copied" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const Vec3 = @Vector(3, i32);
var points = [_]Vec3{
Vec3{ 404, -588, -901 },
Vec3{ 528, -643, 409 },
Vec3{ -838, 591, 734 },
Vec3{ 390, -675, -793 },
Vec3{ -537, -823, -458 },
Vec3{ -485, -357, 347 },
Vec3{ -345, -311, 381 },
Vec3{ -661, -816, -575 },
};
var points2: [20]Vec3 = undefined;
points2[0..points.len].* = points;
try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });
}
test "byte vector initialized in inline function" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and
builtin.cpu.features.isEnabled(@intFromEnum(std.Target.x86.Feature.avx512f)))
{
// TODO https://github.com/ziglang/zig/issues/13279
return error.SkipZigTest;
}
const S = struct {
fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
return .{ e0, e1, e2, e3 };
}
fn all(vb: @Vector(4, bool)) bool {
return @reduce(.And, vb);
}
};
try expect(S.all(S.boolx4(true, true, true, true)));
}
test "zero divisor" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const zeros = @Vector(2, f32){ 0.0, 0.0 };
const ones = @Vector(2, f32){ 1.0, 1.0 };
const v1 = zeros / ones;
const v2 = @divExact(zeros, ones);
const v3 = @divTrunc(zeros, ones);
const v4 = @divFloor(zeros, ones);
_ = v1[0];
_ = v2[0];
_ = v3[0];
_ = v4[0];
}
test "zero multiplicand" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const zeros = @Vector(2, u32){ 0.0, 0.0 };
var ones = @Vector(2, u32){ 1.0, 1.0 };
_ = (ones * zeros)[0];
_ = (zeros * zeros)[0];
_ = (zeros * ones)[0];
_ = (ones *| zeros)[0];
_ = (zeros *| zeros)[0];
_ = (zeros *| ones)[0];
_ = (ones *% zeros)[0];
_ = (zeros *% zeros)[0];
_ = (zeros *% ones)[0];
}
test "@intCast to u0" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
var zeros = @Vector(2, u32){ 0, 0 };
const casted = @as(@Vector(2, u0), @intCast(zeros));
_ = casted[0];
}
test "modRem with zero divisor" {
comptime {
var zeros = @Vector(2, u32){ 0, 0 };
const ones = @Vector(2, u32){ 1, 1 };
zeros %= ones;
_ = zeros[0];
}
}
test "array operands to shuffle are coerced to vectors" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const mask = [5]i32{ -1, 0, 1, 2, 3 };
var a = [5]u32{ 3, 5, 7, 9, 0 };
var b = @shuffle(u32, a, @as(@Vector(5, u24), @splat(0)), mask);
try expectEqual([_]u32{ 0, 3, 5, 7, 9 }, b);
}
test "load packed vector element" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
var x: @Vector(2, u15) = .{ 1, 4 };
try expect((&x[0]).* == 1);
try expect((&x[1]).* == 4);
}
test "store packed vector element" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
var v = @Vector(4, u1){ 1, 1, 1, 1 };
try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v);
var index: usize = 0;
v[index] = 0;
try expectEqual(@Vector(4, u1){ 0, 1, 1, 1 }, v);
}
test "store to vector in slice" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
var v = [_]@Vector(3, f32){
.{ 1, 1, 1 },
.{ 0, 0, 0 },
};
var s: []@Vector(3, f32) = &v;
var i: usize = 1;
s[i] = s[0];
try expectEqual(v[1], v[0]);
}
test "store vector with memset" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm) {
switch (builtin.target.cpu.arch) {
.wasm32,
.mips,
.mipsel,
.mips64,
.mips64el,
.riscv64,
.powerpc,
=> {
// LLVM 16 ERROR: "Converting bits to bytes lost precision"
// https://github.com/ziglang/zig/issues/16177
return error.SkipZigTest;
},
else => {},
}
}
var a: [5]@Vector(2, i1) = undefined;
var b: [5]@Vector(2, u2) = undefined;
var c: [5]@Vector(2, i4) = undefined;
var d: [5]@Vector(2, u8) = undefined;
var e: [5]@Vector(2, i9) = undefined;
var ka = @Vector(2, i1){ -1, 0 };
var kb = @Vector(2, u2){ 0, 1 };
var kc = @Vector(2, i4){ 2, 3 };
var kd = @Vector(2, u8){ 4, 5 };
var ke = @Vector(2, i9){ 6, 7 };
@memset(&a, ka);
@memset(&b, kb);
@memset(&c, kc);
@memset(&d, kd);
@memset(&e, ke);
try std.testing.expectEqual(ka, a[0]);
try std.testing.expectEqual(kb, b[1]);
try std.testing.expectEqual(kc, c[2]);
try std.testing.expectEqual(kd, d[3]);
try std.testing.expectEqual(ke, e[4]);
}
test "addition of vectors represented as strings" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const V = @Vector(3, u8);
const foo: V = "foo".*;
const bar: V = @typeName(u32).*;
try expectEqual(V{ 219, 162, 161 }, foo + bar);
}
test "compare vectors with different element types" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
var a: @Vector(2, u8) = .{ 1, 2 };
var b: @Vector(2, u9) = .{ 3, 0 };
try expectEqual(@Vector(2, bool){ true, false }, a < b);
}
test "vector pointer is indexable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
const V = @Vector(2, u32);
const x: V = .{ 123, 456 };
comptime assert(@TypeOf(&(&x)[0]) == *const u32); // validate constness
try expectEqual(@as(u32, 123), (&x)[0]);
try expectEqual(@as(u32, 456), (&x)[1]);
var y: V = .{ 123, 456 };
comptime assert(@TypeOf(&(&y)[0]) == *u32); // validate constness
try expectEqual(@as(u32, 123), (&y)[0]);
try expectEqual(@as(u32, 456), (&y)[1]);
(&y)[0] = 100;
(&y)[1] = 200;
try expectEqual(@as(u32, 100), (&y)[0]);
try expectEqual(@as(u32, 200), (&y)[1]);
}
test "boolean vector with 2 or more booleans" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
// TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>:
if (!(builtin.os.tag == .linux and builtin.cpu.arch == .x86_64)) return;
const vec1 = @Vector(2, bool){ true, true };
_ = vec1;
const vec2 = @Vector(3, bool){ true, true, true };
_ = vec2;
}
test "bitcast to vector with different child type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {
const VecA = @Vector(8, u16);
const VecB = @Vector(4, u32);
var vec_a = VecA{ 1, 1, 1, 1, 1, 1, 1, 1 };
var vec_b: VecB = @bitCast(vec_a);
var vec_c: VecA = @bitCast(vec_b);
try expectEqual(vec_a, vec_c);
}
};
// Originally reported at https://github.com/ziglang/zig/issues/8184
try S.doTheTest();
try comptime S.doTheTest();
}