| author | |
| committer | |
| log | 426af68b7d234bceba029d65f3388ad2376da649 |
| tree | f52425484ae66d4cbd636a60a86b1bf91478f0c2 |
| parent | 14bda4130a9a7f8b529b12bc74a1d6caa71b9545 |
13 files changed, 55 insertions(+), 104 deletions(-)
lib/std/Target.zig+1-1| ... | ... | @@ -1187,7 +1187,7 @@ pub const Cpu = struct { |
| 1187 | 1187 | pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize))); |
| 1188 | 1188 | pub const ShiftInt = std.math.Log2Int(usize); |
| 1189 | 1189 | |
| 1190 | pub const empty = Set{ .ints = [1]usize{0} ** usize_count }; | |
| 1190 | pub const empty: Set = .{ .ints = @splat(0) }; | |
| 1191 | 1191 | |
| 1192 | 1192 | pub fn isEmpty(set: Set) bool { |
| 1193 | 1193 | return for (set.ints) |x| { |
lib/std/crypto/chacha20.zig+1-1| ... | ... | @@ -216,7 +216,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | fn hashToBytes(comptime dm: usize, out: *[64 * dm]u8, x: BlockVec) void { |
| 219 | for (0..dm) |d| { | |
| 219 | inline for (0..dm) |d| { | |
| 220 | 220 | for (0..4) |i| { |
| 221 | 221 | mem.writeInt(u32, out[64 * d + 16 * i + 0 ..][0..4], x[i][0 + 4 * d], .little); |
| 222 | 222 | mem.writeInt(u32, out[64 * d + 16 * i + 4 ..][0..4], x[i][1 + 4 * d], .little); |
lib/std/json/static.zig+22-4| ... | ... | @@ -389,7 +389,7 @@ pub fn innerParse( |
| 389 | 389 | switch (try source.peekNextTokenType()) { |
| 390 | 390 | .array_begin => { |
| 391 | 391 | // Typical array. |
| 392 | return internalParseArray(T, arrayInfo.child, arrayInfo.len, allocator, source, options); | |
| 392 | return internalParseArray(T, arrayInfo.child, allocator, source, options); | |
| 393 | 393 | }, |
| 394 | 394 | .string => { |
| 395 | 395 | if (arrayInfo.child != u8) return error.UnexpectedToken; |
| ... | ... | @@ -443,7 +443,7 @@ pub fn innerParse( |
| 443 | 443 | .vector => |vecInfo| { |
| 444 | 444 | switch (try source.peekNextTokenType()) { |
| 445 | 445 | .array_begin => { |
| 446 | return internalParseArray(T, vecInfo.child, vecInfo.len, allocator, source, options); | |
| 446 | return internalParseVector(T, vecInfo.child, vecInfo.len, allocator, source, options); | |
| 447 | 447 | }, |
| 448 | 448 | else => return error.UnexpectedToken, |
| 449 | 449 | } |
| ... | ... | @@ -517,6 +517,25 @@ pub fn innerParse( |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | 519 | fn internalParseArray( |
| 520 | comptime T: type, | |
| 521 | comptime Child: type, | |
| 522 | allocator: Allocator, | |
| 523 | source: anytype, | |
| 524 | options: ParseOptions, | |
| 525 | ) !T { | |
| 526 | assert(.array_begin == try source.next()); | |
| 527 | ||
| 528 | var r: T = undefined; | |
| 529 | for (&r) |*elem| { | |
| 530 | elem.* = try innerParse(Child, allocator, source, options); | |
| 531 | } | |
| 532 | ||
| 533 | if (.array_end != try source.next()) return error.UnexpectedToken; | |
| 534 | ||
| 535 | return r; | |
| 536 | } | |
| 537 | ||
| 538 | fn internalParseVector( | |
| 520 | 539 | comptime T: type, |
| 521 | 540 | comptime Child: type, |
| 522 | 541 | comptime len: comptime_int, |
| ... | ... | @@ -527,8 +546,7 @@ fn internalParseArray( |
| 527 | 546 | assert(.array_begin == try source.next()); |
| 528 | 547 | |
| 529 | 548 | var r: T = undefined; |
| 530 | var i: usize = 0; | |
| 531 | while (i < len) : (i += 1) { | |
| 549 | inline for (0..len) |i| { | |
| 532 | 550 | r[i] = try innerParse(Child, allocator, source, options); |
| 533 | 551 | } |
| 534 | 552 |
lib/std/meta.zig+2-3| ... | ... | @@ -743,9 +743,8 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool { |
| 743 | 743 | return true; |
| 744 | 744 | }, |
| 745 | 745 | .vector => |info| { |
| 746 | var i: usize = 0; | |
| 747 | while (i < info.len) : (i += 1) { | |
| 748 | if (!eql(a[i], b[i])) return false; | |
| 746 | inline for (0..info.len) |i| { | |
| 747 | if (a[i] != b[i]) return false; | |
| 749 | 748 | } |
| 750 | 749 | return true; |
| 751 | 750 | }, |
lib/std/testing.zig+3-5| ... | ... | @@ -135,9 +135,8 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { |
| 135 | 135 | .array => |array| try expectEqualSlices(array.child, &expected, &actual), |
| 136 | 136 | |
| 137 | 137 | .vector => |info| { |
| 138 | var i: usize = 0; | |
| 139 | while (i < info.len) : (i += 1) { | |
| 140 | if (!std.meta.eql(expected[i], actual[i])) { | |
| 138 | inline for (0..info.len) |i| { | |
| 139 | if (expected[i] != actual[i]) { | |
| 141 | 140 | print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 142 | 141 | i, expected[i], actual[i], |
| 143 | 142 | }); |
| ... | ... | @@ -828,8 +827,7 @@ fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpe |
| 828 | 827 | print("Vector len not the same, expected {d}, found {d}\n", .{ info.len, @typeInfo(@TypeOf(actual)).vector.len }); |
| 829 | 828 | return error.TestExpectedEqual; |
| 830 | 829 | } |
| 831 | var i: usize = 0; | |
| 832 | while (i < info.len) : (i += 1) { | |
| 830 | inline for (0..info.len) |i| { | |
| 833 | 831 | expectEqualDeep(expected[i], actual[i]) catch |e| { |
| 834 | 832 | print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 835 | 833 | i, expected[i], actual[i], |
lib/std/zon/Serializer.zig+1-1| ... | ... | @@ -235,7 +235,7 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption |
| 235 | 235 | var container = try self.beginTuple( |
| 236 | 236 | .{ .whitespace_style = .{ .fields = vector.len } }, |
| 237 | 237 | ); |
| 238 | for (0..vector.len) |i| { | |
| 238 | inline for (0..vector.len) |i| { | |
| 239 | 239 | try container.fieldArbitraryDepth(val[i], options); |
| 240 | 240 | } |
| 241 | 241 | try container.end(); |
lib/std/zon/parse.zig+4-8| ... | ... | @@ -446,7 +446,7 @@ pub fn free(gpa: Allocator, value: anytype) void { |
| 446 | 446 | .optional => if (value) |some| { |
| 447 | 447 | free(gpa, some); |
| 448 | 448 | }, |
| 449 | .vector => |vector| for (0..vector.len) |i| free(gpa, value[i]), | |
| 449 | .vector => |vector| inline for (0..vector.len) |i| free(gpa, value[i]), | |
| 450 | 450 | .void => {}, |
| 451 | 451 | else => comptime unreachable, |
| 452 | 452 | } |
| ... | ... | @@ -998,11 +998,7 @@ const Parser = struct { |
| 998 | 998 | } |
| 999 | 999 | } |
| 1000 | 1000 | |
| 1001 | fn parseVector( | |
| 1002 | self: *@This(), | |
| 1003 | T: type, | |
| 1004 | node: Zoir.Node.Index, | |
| 1005 | ) !T { | |
| 1001 | fn parseVector(self: *@This(), T: type, node: Zoir.Node.Index) !T { | |
| 1006 | 1002 | const vector_info = @typeInfo(T).vector; |
| 1007 | 1003 | |
| 1008 | 1004 | const nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir)) { |
| ... | ... | @@ -1021,8 +1017,8 @@ const Parser = struct { |
| 1021 | 1017 | ); |
| 1022 | 1018 | } |
| 1023 | 1019 | |
| 1024 | for (0..vector_info.len) |i| { | |
| 1025 | errdefer for (0..i) |j| free(self.gpa, result[j]); | |
| 1020 | inline for (0..vector_info.len) |i| { | |
| 1021 | errdefer inline for (0..i) |j| free(self.gpa, result[j]); | |
| 1026 | 1022 | result[i] = try self.parseExpr(vector_info.child, nodes.at(@intCast(i))); |
| 1027 | 1023 | } |
| 1028 | 1024 |
src/Sema.zig+5-13| ... | ... | @@ -27972,6 +27972,7 @@ fn elemVal( |
| 27972 | 27972 | } |
| 27973 | 27973 | } |
| 27974 | 27974 | |
| 27975 | /// Called when the index or indexable is runtime known. | |
| 27975 | 27976 | fn validateRuntimeElemAccess( |
| 27976 | 27977 | sema: *Sema, |
| 27977 | 27978 | block: *Block, |
| ... | ... | @@ -28236,6 +28237,10 @@ fn elemPtrArray( |
| 28236 | 28237 | try sema.validateRuntimeValue(block, array_ptr_src, array_ptr); |
| 28237 | 28238 | } |
| 28238 | 28239 | |
| 28240 | if (offset == null and array_ty.zigTypeTag(zcu) == .vector) { | |
| 28241 | return sema.fail(block, elem_index_src, "vector index not comptime known", .{}); | |
| 28242 | } | |
| 28243 | ||
| 28239 | 28244 | // Runtime check is only needed if unable to comptime check. |
| 28240 | 28245 | if (oob_safety and block.wantSafety() and offset == null) { |
| 28241 | 28246 | const len_inst = try pt.intRef(.usize, array_len); |
| ... | ... | @@ -31425,19 +31430,6 @@ fn analyzeLoad( |
| 31425 | 31430 | } |
| 31426 | 31431 | } |
| 31427 | 31432 | |
| 31428 | if (ptr_ty.ptrInfo(zcu).flags.vector_index == .runtime) { | |
| 31429 | const ptr_inst = ptr.toIndex().?; | |
| 31430 | const air_tags = sema.air_instructions.items(.tag); | |
| 31431 | if (air_tags[@intFromEnum(ptr_inst)] == .ptr_elem_ptr) { | |
| 31432 | const ty_pl = sema.air_instructions.items(.data)[@intFromEnum(ptr_inst)].ty_pl; | |
| 31433 | const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data; | |
| 31434 | return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs); | |
| 31435 | } | |
| 31436 | return sema.fail(block, ptr_src, "unable to determine vector element index of type '{f}'", .{ | |
| 31437 | ptr_ty.fmt(pt), | |
| 31438 | }); | |
| 31439 | } | |
| 31440 | ||
| 31441 | 31433 | return block.addTyOp(.load, elem_ty, ptr); |
| 31442 | 31434 | } |
| 31443 | 31435 |
test/behavior/math.zig+1-2| ... | ... | @@ -140,8 +140,7 @@ fn expectVectorsEqual(a: anytype, b: anytype) !void { |
| 140 | 140 | const len_b = @typeInfo(@TypeOf(b)).vector.len; |
| 141 | 141 | try expect(len_a == len_b); |
| 142 | 142 | |
| 143 | var i: usize = 0; | |
| 144 | while (i < len_a) : (i += 1) { | |
| 143 | inline for (0..len_a) |i| { | |
| 145 | 144 | try expect(a[i] == b[i]); |
| 146 | 145 | } |
| 147 | 146 | } |
test/behavior/vector.zig+10-54| ... | ... | @@ -441,49 +441,6 @@ test "store vector elements via comptime index" { |
| 441 | 441 | try comptime S.doTheTest(); |
| 442 | 442 | } |
| 443 | 443 | |
| 444 | test "load vector elements via runtime index" { | |
| 445 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 446 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 447 | ||
| 448 | const S = struct { | |
| 449 | fn doTheTest() !void { | |
| 450 | var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined }; | |
| 451 | _ = &v; | |
| 452 | var i: u32 = 0; | |
| 453 | try expect(v[i] == 1); | |
| 454 | i += 1; | |
| 455 | try expect(v[i] == 2); | |
| 456 | i += 1; | |
| 457 | try expect(v[i] == 3); | |
| 458 | } | |
| 459 | }; | |
| 460 | ||
| 461 | try S.doTheTest(); | |
| 462 | try comptime S.doTheTest(); | |
| 463 | } | |
| 464 | ||
| 465 | test "store vector elements via runtime index" { | |
| 466 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 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 S = struct { | |
| 471 | fn doTheTest() !void { | |
| 472 | var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; | |
| 473 | var i: u32 = 2; | |
| 474 | v[i] = 1; | |
| 475 | try expect(v[1] == 5); | |
| 476 | try expect(v[2] == 1); | |
| 477 | i += 1; | |
| 478 | v[i] = -364; | |
| 479 | try expect(-364 == v[3]); | |
| 480 | } | |
| 481 | }; | |
| 482 | ||
| 483 | try S.doTheTest(); | |
| 484 | try comptime S.doTheTest(); | |
| 485 | } | |
| 486 | ||
| 487 | 444 | test "initialize vector which is a struct field" { |
| 488 | 445 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 489 | 446 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -567,20 +524,20 @@ test "vector division operators" { |
| 567 | 524 | }; |
| 568 | 525 | if (!is_signed_int) { |
| 569 | 526 | const d0 = x / y; |
| 570 | for (@as([4]T, d0), 0..) |v, i| { | |
| 527 | inline for (@as([4]T, d0), 0..) |v, i| { | |
| 571 | 528 | try expect(x[i] / y[i] == v); |
| 572 | 529 | } |
| 573 | 530 | } |
| 574 | 531 | const d1 = @divExact(x, y); |
| 575 | for (@as([4]T, d1), 0..) |v, i| { | |
| 532 | inline for (@as([4]T, d1), 0..) |v, i| { | |
| 576 | 533 | try expect(@divExact(x[i], y[i]) == v); |
| 577 | 534 | } |
| 578 | 535 | const d2 = @divFloor(x, y); |
| 579 | for (@as([4]T, d2), 0..) |v, i| { | |
| 536 | inline for (@as([4]T, d2), 0..) |v, i| { | |
| 580 | 537 | try expect(@divFloor(x[i], y[i]) == v); |
| 581 | 538 | } |
| 582 | 539 | const d3 = @divTrunc(x, y); |
| 583 | for (@as([4]T, d3), 0..) |v, i| { | |
| 540 | inline for (@as([4]T, d3), 0..) |v, i| { | |
| 584 | 541 | try expect(@divTrunc(x[i], y[i]) == v); |
| 585 | 542 | } |
| 586 | 543 | } |
| ... | ... | @@ -592,16 +549,16 @@ test "vector division operators" { |
| 592 | 549 | }; |
| 593 | 550 | if (!is_signed_int and @typeInfo(T) != .float) { |
| 594 | 551 | const r0 = x % y; |
| 595 | for (@as([4]T, r0), 0..) |v, i| { | |
| 552 | inline for (@as([4]T, r0), 0..) |v, i| { | |
| 596 | 553 | try expect(x[i] % y[i] == v); |
| 597 | 554 | } |
| 598 | 555 | } |
| 599 | 556 | const r1 = @mod(x, y); |
| 600 | for (@as([4]T, r1), 0..) |v, i| { | |
| 557 | inline for (@as([4]T, r1), 0..) |v, i| { | |
| 601 | 558 | try expect(@mod(x[i], y[i]) == v); |
| 602 | 559 | } |
| 603 | 560 | const r2 = @rem(x, y); |
| 604 | for (@as([4]T, r2), 0..) |v, i| { | |
| 561 | inline for (@as([4]T, r2), 0..) |v, i| { | |
| 605 | 562 | try expect(@rem(x[i], y[i]) == v); |
| 606 | 563 | } |
| 607 | 564 | } |
| ... | ... | @@ -654,7 +611,7 @@ test "vector bitwise not operator" { |
| 654 | 611 | const S = struct { |
| 655 | 612 | fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void { |
| 656 | 613 | const y = ~x; |
| 657 | for (@as([4]T, y), 0..) |v, i| { | |
| 614 | inline for (@as([4]T, y), 0..) |v, i| { | |
| 658 | 615 | try expect(~x[i] == v); |
| 659 | 616 | } |
| 660 | 617 | } |
| ... | ... | @@ -688,7 +645,7 @@ test "vector boolean not operator" { |
| 688 | 645 | const S = struct { |
| 689 | 646 | fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void { |
| 690 | 647 | const y = !x; |
| 691 | for (@as([4]T, y), 0..) |v, i| { | |
| 648 | inline for (@as([4]T, y), 0..) |v, i| { | |
| 692 | 649 | try expect(!x[i] == v); |
| 693 | 650 | } |
| 694 | 651 | } |
| ... | ... | @@ -1530,8 +1487,7 @@ test "store packed vector element" { |
| 1530 | 1487 | |
| 1531 | 1488 | var v = @Vector(4, u1){ 1, 1, 1, 1 }; |
| 1532 | 1489 | try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v); |
| 1533 | var index: usize = 0; | |
| 1534 | _ = &index; | |
| 1490 | const index: usize = 0; | |
| 1535 | 1491 | v[index] = 0; |
| 1536 | 1492 | try expectEqual(@Vector(4, u1){ 0, 1, 1, 1 }, v); |
| 1537 | 1493 | } |
test/behavior/x86_64/access.zig+3-10| ... | ... | @@ -52,22 +52,15 @@ fn accessVector(comptime init: anytype) !void { |
| 52 | 52 | var vector: Vector = undefined; |
| 53 | 53 | vector = init; |
| 54 | 54 | inline for (0..@typeInfo(Vector).vector.len) |ct_index| { |
| 55 | var rt_index: usize = undefined; | |
| 56 | rt_index = ct_index; | |
| 57 | if (&vector[rt_index] != &vector[ct_index]) return error.Unexpected; | |
| 58 | if (vector[rt_index] != init[ct_index]) return error.Unexpected; | |
| 55 | if (&vector[ct_index] != &vector[ct_index]) return error.Unexpected; | |
| 59 | 56 | if (vector[ct_index] != init[ct_index]) return error.Unexpected; |
| 60 | vector[rt_index] = rt_vals[0]; | |
| 61 | if (vector[rt_index] != ct_vals[0]) return error.Unexpected; | |
| 57 | vector[ct_index] = rt_vals[0]; | |
| 62 | 58 | if (vector[ct_index] != ct_vals[0]) return error.Unexpected; |
| 63 | vector[rt_index] = ct_vals[1]; | |
| 64 | if (vector[rt_index] != ct_vals[1]) return error.Unexpected; | |
| 59 | vector[ct_index] = ct_vals[1]; | |
| 65 | 60 | if (vector[ct_index] != ct_vals[1]) return error.Unexpected; |
| 66 | 61 | vector[ct_index] = ct_vals[0]; |
| 67 | if (vector[rt_index] != ct_vals[0]) return error.Unexpected; | |
| 68 | 62 | if (vector[ct_index] != ct_vals[0]) return error.Unexpected; |
| 69 | 63 | vector[ct_index] = rt_vals[1]; |
| 70 | if (vector[rt_index] != ct_vals[1]) return error.Unexpected; | |
| 71 | 64 | if (vector[ct_index] != ct_vals[1]) return error.Unexpected; |
| 72 | 65 | } |
| 73 | 66 | } |
test/cases/compile_errors/load_vector_pointer_with_unknown_runtime_index.zig+1-1| ... | ... | @@ -12,4 +12,4 @@ fn loadv(ptr: anytype) i31 { |
| 12 | 12 | |
| 13 | 13 | // error |
| 14 | 14 | // |
| 15 | // :10:15: error: unable to determine vector element index of type '*align(16:0:4:?) i31' | |
| 15 | // :5:22: error: vector index not comptime known |
test/cases/compile_errors/store_vector_pointer_with_unknown_runtime_index.zig+1-1| ... | ... | @@ -12,4 +12,4 @@ fn storev(ptr: anytype, val: i31) void { |
| 12 | 12 | |
| 13 | 13 | // error |
| 14 | 14 | // |
| 15 | // :10:8: error: unable to determine vector element index of type '*align(16:0:4:?) i31' | |
| 15 | // :6:15: error: vector index not comptime known |