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 }