| author | |
| committer | |
| log | e05c242cd89d03ae67fa7b8d5fc33fb5dc42dbe3 |
| tree | a9224a9d47bfda3873284718515cccda78ec32ba |
| parent | d78517f4f0f540f0d0254a78e47a7b4a30e98c74 |
| parent | 47d5bf26164b4ddb3228d17ae2158d1c29b8d040 |
| signature |
Apply RLS to @splat builtin, eliminating its length parameter24 files changed, 174 insertions(+), 156 deletions(-)
doc/langref.html.in+7-7| ... | @@ -9239,10 +9239,10 @@ test "vector @shuffle" { | ... | @@ -9239,10 +9239,10 @@ test "vector @shuffle" { |
| 9239 | {#header_close#} | 9239 | {#header_close#} |
| 9240 | 9240 | ||
| 9241 | {#header_open|@splat#} | 9241 | {#header_open|@splat#} |
| 9242 | <pre>{#syntax#}@splat(comptime len: u32, scalar: anytype) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre> | 9242 | <pre>{#syntax#}@splat(scalar: anytype) anytype{#endsyntax#}</pre> |
| 9243 | <p> | 9243 | <p> |
| 9244 | Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value | 9244 | Produces a vector where each element is the value {#syntax#}scalar{#endsyntax#}. |
| 9245 | {#syntax#}scalar{#endsyntax#}: | 9245 | The return type and thus the length of the vector is inferred. |
| 9246 | </p> | 9246 | </p> |
| 9247 | {#code_begin|test|test_splat_builtin#} | 9247 | {#code_begin|test|test_splat_builtin#} |
| 9248 | const std = @import("std"); | 9248 | const std = @import("std"); |
| ... | @@ -9250,8 +9250,7 @@ const expect = std.testing.expect; | ... | @@ -9250,8 +9250,7 @@ const expect = std.testing.expect; |
| 9250 | 9250 | ||
| 9251 | test "vector @splat" { | 9251 | test "vector @splat" { |
| 9252 | const scalar: u32 = 5; | 9252 | const scalar: u32 = 5; |
| 9253 | const result = @splat(4, scalar); | 9253 | const result: @Vector(4, u32) = @splat(scalar); |
| 9254 | try comptime expect(@TypeOf(result) == @Vector(4, u32)); | ||
| 9255 | try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); | 9254 | try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); |
| 9256 | } | 9255 | } |
| 9257 | {#code_end#} | 9256 | {#code_end#} |
| ... | @@ -9292,8 +9291,9 @@ const std = @import("std"); | ... | @@ -9292,8 +9291,9 @@ const std = @import("std"); |
| 9292 | const expect = std.testing.expect; | 9291 | const expect = std.testing.expect; |
| 9293 | 9292 | ||
| 9294 | test "vector @reduce" { | 9293 | test "vector @reduce" { |
| 9295 | const value = @Vector(4, i32){ 1, -1, 1, -1 }; | 9294 | const V = @Vector(4, i32); |
| 9296 | const result = value > @splat(4, @as(i32, 0)); | 9295 | const value = V{ 1, -1, 1, -1 }; |
| 9296 | const result = value > @as(V, @splat(0)); | ||
| 9297 | // result is { true, false, true, false }; | 9297 | // result is { true, false, true, false }; |
| 9298 | try comptime expect(@TypeOf(result) == @Vector(4, bool)); | 9298 | try comptime expect(@TypeOf(result) == @Vector(4, bool)); |
| 9299 | const is_all_true = @reduce(.And, result); | 9299 | const is_all_true = @reduce(.And, result); |
lib/std/http/protocol.zig+2-2| ... | @@ -182,8 +182,8 @@ pub const HeadersParser = struct { | ... | @@ -182,8 +182,8 @@ pub const HeadersParser = struct { |
| 182 | 182 | ||
| 183 | const chunk = bytes[index..][0..vector_len]; | 183 | const chunk = bytes[index..][0..vector_len]; |
| 184 | const v: Vector = chunk.*; | 184 | const v: Vector = chunk.*; |
| 185 | const matches_r = @as(BitVector, @bitCast(v == @splat(vector_len, @as(u8, '\r')))); | 185 | const matches_r = @as(BitVector, @bitCast(v == @as(Vector, @splat('\r')))); |
| 186 | const matches_n = @as(BitVector, @bitCast(v == @splat(vector_len, @as(u8, '\n')))); | 186 | const matches_n = @as(BitVector, @bitCast(v == @as(Vector, @splat('\n')))); |
| 187 | const matches_or: SizeVector = matches_r | matches_n; | 187 | const matches_or: SizeVector = matches_r | matches_n; |
| 188 | 188 | ||
| 189 | const matches = @reduce(.Add, matches_or); | 189 | const matches = @reduce(.Add, matches_or); |
lib/std/json/stringify_test.zig+1-1| ... | @@ -197,7 +197,7 @@ test "stringify struct with custom stringifier" { | ... | @@ -197,7 +197,7 @@ test "stringify struct with custom stringifier" { |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | test "stringify vector" { | 199 | test "stringify vector" { |
| 200 | try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); | 200 | try teststringify("[1,1]", @as(@Vector(2, u32), @splat(1)), StringifyOptions{}); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | test "stringify tuple" { | 203 | test "stringify tuple" { |
lib/std/math.zig+31-21| ... | @@ -507,8 +507,8 @@ pub fn shl(comptime T: type, a: T, shift_amt: anytype) T { | ... | @@ -507,8 +507,8 @@ pub fn shl(comptime T: type, a: T, shift_amt: anytype) T { |
| 507 | if (@typeInfo(T) == .Vector) { | 507 | if (@typeInfo(T) == .Vector) { |
| 508 | const C = @typeInfo(T).Vector.child; | 508 | const C = @typeInfo(T).Vector.child; |
| 509 | const len = @typeInfo(T).Vector.len; | 509 | const len = @typeInfo(T).Vector.len; |
| 510 | if (abs_shift_amt >= @typeInfo(C).Int.bits) return @splat(len, @as(C, 0)); | 510 | if (abs_shift_amt >= @typeInfo(C).Int.bits) return @splat(0); |
| 511 | break :blk @splat(len, @as(Log2Int(C), @intCast(abs_shift_amt))); | 511 | break :blk @as(@Vector(len, Log2Int(C)), @splat(@as(Log2Int(C), @intCast(abs_shift_amt)))); |
| 512 | } else { | 512 | } else { |
| 513 | if (abs_shift_amt >= @typeInfo(T).Int.bits) return 0; | 513 | if (abs_shift_amt >= @typeInfo(T).Int.bits) return 0; |
| 514 | break :blk @as(Log2Int(T), @intCast(abs_shift_amt)); | 514 | break :blk @as(Log2Int(T), @intCast(abs_shift_amt)); |
| ... | @@ -551,8 +551,8 @@ pub fn shr(comptime T: type, a: T, shift_amt: anytype) T { | ... | @@ -551,8 +551,8 @@ pub fn shr(comptime T: type, a: T, shift_amt: anytype) T { |
| 551 | if (@typeInfo(T) == .Vector) { | 551 | if (@typeInfo(T) == .Vector) { |
| 552 | const C = @typeInfo(T).Vector.child; | 552 | const C = @typeInfo(T).Vector.child; |
| 553 | const len = @typeInfo(T).Vector.len; | 553 | const len = @typeInfo(T).Vector.len; |
| 554 | if (abs_shift_amt >= @typeInfo(C).Int.bits) return @splat(len, @as(C, 0)); | 554 | if (abs_shift_amt >= @typeInfo(C).Int.bits) return @splat(0); |
| 555 | break :blk @splat(len, @as(Log2Int(C), @intCast(abs_shift_amt))); | 555 | break :blk @as(@Vector(len, Log2Int(C)), @splat(@as(Log2Int(C), @intCast(abs_shift_amt)))); |
| 556 | } else { | 556 | } else { |
| 557 | if (abs_shift_amt >= @typeInfo(T).Int.bits) return 0; | 557 | if (abs_shift_amt >= @typeInfo(T).Int.bits) return 0; |
| 558 | break :blk @as(Log2Int(T), @intCast(abs_shift_amt)); | 558 | break :blk @as(Log2Int(T), @intCast(abs_shift_amt)); |
| ... | @@ -597,7 +597,7 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T { | ... | @@ -597,7 +597,7 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T { |
| 597 | @compileError("cannot rotate signed integers"); | 597 | @compileError("cannot rotate signed integers"); |
| 598 | } | 598 | } |
| 599 | const ar = @as(Log2Int(C), @intCast(@mod(r, @typeInfo(C).Int.bits))); | 599 | const ar = @as(Log2Int(C), @intCast(@mod(r, @typeInfo(C).Int.bits))); |
| 600 | return (x >> @splat(@typeInfo(T).Vector.len, ar)) | (x << @splat(@typeInfo(T).Vector.len, 1 + ~ar)); | 600 | return (x >> @splat(ar)) | (x << @splat(1 + ~ar)); |
| 601 | } else if (@typeInfo(T).Int.signedness == .signed) { | 601 | } else if (@typeInfo(T).Int.signedness == .signed) { |
| 602 | @compileError("cannot rotate signed integer"); | 602 | @compileError("cannot rotate signed integer"); |
| 603 | } else { | 603 | } else { |
| ... | @@ -641,7 +641,7 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T { | ... | @@ -641,7 +641,7 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T { |
| 641 | @compileError("cannot rotate signed integers"); | 641 | @compileError("cannot rotate signed integers"); |
| 642 | } | 642 | } |
| 643 | const ar = @as(Log2Int(C), @intCast(@mod(r, @typeInfo(C).Int.bits))); | 643 | const ar = @as(Log2Int(C), @intCast(@mod(r, @typeInfo(C).Int.bits))); |
| 644 | return (x << @splat(@typeInfo(T).Vector.len, ar)) | (x >> @splat(@typeInfo(T).Vector.len, 1 +% ~ar)); | 644 | return (x << @splat(ar)) | (x >> @splat(1 +% ~ar)); |
| 645 | } else if (@typeInfo(T).Int.signedness == .signed) { | 645 | } else if (@typeInfo(T).Int.signedness == .signed) { |
| 646 | @compileError("cannot rotate signed integer"); | 646 | @compileError("cannot rotate signed integer"); |
| 647 | } else { | 647 | } else { |
| ... | @@ -794,10 +794,10 @@ pub fn absInt(x: anytype) !@TypeOf(x) { | ... | @@ -794,10 +794,10 @@ pub fn absInt(x: anytype) !@TypeOf(x) { |
| 794 | switch (@typeInfo(vinfo.child)) { | 794 | switch (@typeInfo(vinfo.child)) { |
| 795 | .Int => |info| { | 795 | .Int => |info| { |
| 796 | comptime assert(info.signedness == .signed); // must pass a signed integer to absInt | 796 | comptime assert(info.signedness == .signed); // must pass a signed integer to absInt |
| 797 | if (@reduce(.Or, x == @splat(vinfo.len, @as(vinfo.child, minInt(vinfo.child))))) { | 797 | if (@reduce(.Or, x == @as(T, @splat(minInt(vinfo.child))))) { |
| 798 | return error.Overflow; | 798 | return error.Overflow; |
| 799 | } | 799 | } |
| 800 | const zero = @splat(vinfo.len, @as(vinfo.child, 0)); | 800 | const zero: T = @splat(0); |
| 801 | break :blk @select(vinfo.child, x > zero, x, -x); | 801 | break :blk @select(vinfo.child, x > zero, x, -x); |
| 802 | }, | 802 | }, |
| 803 | else => @compileError("Expected vector of ints, found " ++ @typeName(T)), | 803 | else => @compileError("Expected vector of ints, found " ++ @typeName(T)), |
| ... | @@ -1368,9 +1368,9 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) { | ... | @@ -1368,9 +1368,9 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) { |
| 1368 | 1368 | ||
| 1369 | switch (@typeInfo(Type)) { | 1369 | switch (@typeInfo(Type)) { |
| 1370 | .Float, .ComptimeFloat => assert(t >= 0 and t <= 1), | 1370 | .Float, .ComptimeFloat => assert(t >= 0 and t <= 1), |
| 1371 | .Vector => |vector| { | 1371 | .Vector => { |
| 1372 | const lower_bound = @reduce(.And, t >= @splat(vector.len, @as(vector.child, 0))); | 1372 | const lower_bound = @reduce(.And, t >= @as(Type, @splat(0))); |
| 1373 | const upper_bound = @reduce(.And, t <= @splat(vector.len, @as(vector.child, 1))); | 1373 | const upper_bound = @reduce(.And, t <= @as(Type, @splat(1))); |
| 1374 | assert(lower_bound and upper_bound); | 1374 | assert(lower_bound and upper_bound); |
| 1375 | }, | 1375 | }, |
| 1376 | else => comptime unreachable, | 1376 | else => comptime unreachable, |
| ... | @@ -1392,14 +1392,24 @@ test "lerp" { | ... | @@ -1392,14 +1392,24 @@ test "lerp" { |
| 1392 | try testing.expectEqual(@as(f32, 1.0), lerp(@as(f32, 1.0e7), 1.0, 1.0)); | 1392 | try testing.expectEqual(@as(f32, 1.0), lerp(@as(f32, 1.0e7), 1.0, 1.0)); |
| 1393 | try testing.expectEqual(@as(f64, 1.0), lerp(@as(f64, 1.0e15), 1.0, 1.0)); | 1393 | try testing.expectEqual(@as(f64, 1.0), lerp(@as(f64, 1.0e15), 1.0, 1.0)); |
| 1394 | 1394 | ||
| 1395 | try testing.expectEqual( | 1395 | { |
| 1396 | lerp(@splat(3, @as(f32, 0)), @splat(3, @as(f32, 50)), @splat(3, @as(f32, 0.5))), | 1396 | const a: @Vector(3, f32) = @splat(0); |
| 1397 | @Vector(3, f32){ 25, 25, 25 }, | 1397 | const b: @Vector(3, f32) = @splat(50); |
| 1398 | ); | 1398 | const t: @Vector(3, f32) = @splat(0.5); |
| 1399 | try testing.expectEqual( | 1399 | try testing.expectEqual( |
| 1400 | lerp(@splat(3, @as(f64, 50)), @splat(3, @as(f64, 100)), @splat(3, @as(f64, 0.5))), | 1400 | lerp(a, b, t), |
| 1401 | @Vector(3, f64){ 75, 75, 75 }, | 1401 | @Vector(3, f32){ 25, 25, 25 }, |
| 1402 | ); | 1402 | ); |
| 1403 | } | ||
| 1404 | { | ||
| 1405 | const a: @Vector(3, f64) = @splat(50); | ||
| 1406 | const b: @Vector(3, f64) = @splat(100); | ||
| 1407 | const t: @Vector(3, f64) = @splat(0.5); | ||
| 1408 | try testing.expectEqual( | ||
| 1409 | lerp(a, b, t), | ||
| 1410 | @Vector(3, f64){ 75, 75, 75 }, | ||
| 1411 | ); | ||
| 1412 | } | ||
| 1403 | } | 1413 | } |
| 1404 | 1414 | ||
| 1405 | /// Returns the maximum value of integer type T. | 1415 | /// Returns the maximum value of integer type T. |
| ... | @@ -1719,8 +1729,8 @@ pub inline fn sign(i: anytype) @TypeOf(i) { | ... | @@ -1719,8 +1729,8 @@ pub inline fn sign(i: anytype) @TypeOf(i) { |
| 1719 | .Vector => |vinfo| blk: { | 1729 | .Vector => |vinfo| blk: { |
| 1720 | switch (@typeInfo(vinfo.child)) { | 1730 | switch (@typeInfo(vinfo.child)) { |
| 1721 | .Int, .Float => { | 1731 | .Int, .Float => { |
| 1722 | const zero = @splat(vinfo.len, @as(vinfo.child, 0)); | 1732 | const zero: T = @splat(0); |
| 1723 | const one = @splat(vinfo.len, @as(vinfo.child, 1)); | 1733 | const one: T = @splat(1); |
| 1724 | break :blk @select(vinfo.child, i > zero, one, zero) - @select(vinfo.child, i < zero, one, zero); | 1734 | break :blk @select(vinfo.child, i > zero, one, zero) - @select(vinfo.child, i < zero, one, zero); |
| 1725 | }, | 1735 | }, |
| 1726 | else => @compileError("Expected vector of ints or floats, found " ++ @typeName(T)), | 1736 | else => @compileError("Expected vector of ints or floats, found " ++ @typeName(T)), |
lib/std/mem.zig+4-4| ... | @@ -289,7 +289,7 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -289,7 +289,7 @@ pub fn zeroes(comptime T: type) T { |
| 289 | return [_]info.child{zeroes(info.child)} ** info.len; | 289 | return [_]info.child{zeroes(info.child)} ** info.len; |
| 290 | }, | 290 | }, |
| 291 | .Vector => |info| { | 291 | .Vector => |info| { |
| 292 | return @splat(info.len, zeroes(info.child)); | 292 | return @splat(zeroes(info.child)); |
| 293 | }, | 293 | }, |
| 294 | .Union => |info| { | 294 | .Union => |info| { |
| 295 | if (comptime meta.containerLayout(T) == .Extern) { | 295 | if (comptime meta.containerLayout(T) == .Extern) { |
| ... | @@ -393,9 +393,9 @@ test "zeroes" { | ... | @@ -393,9 +393,9 @@ test "zeroes" { |
| 393 | for (b.array) |e| { | 393 | for (b.array) |e| { |
| 394 | try testing.expectEqual(@as(u32, 0), e); | 394 | try testing.expectEqual(@as(u32, 0), e); |
| 395 | } | 395 | } |
| 396 | try testing.expectEqual(@splat(2, @as(u32, 0)), b.vector_u32); | 396 | try testing.expectEqual(@as(@TypeOf(b.vector_u32), @splat(0)), b.vector_u32); |
| 397 | try testing.expectEqual(@splat(2, @as(f32, 0.0)), b.vector_f32); | 397 | try testing.expectEqual(@as(@TypeOf(b.vector_f32), @splat(0.0)), b.vector_f32); |
| 398 | try testing.expectEqual(@splat(2, @as(bool, false)), b.vector_bool); | 398 | try testing.expectEqual(@as(@TypeOf(b.vector_bool), @splat(false)), b.vector_bool); |
| 399 | try testing.expectEqual(@as(?u8, null), b.optional_int); | 399 | try testing.expectEqual(@as(?u8, null), b.optional_int); |
| 400 | for (b.sentinel) |e| { | 400 | for (b.sentinel) |e| { |
| 401 | try testing.expectEqual(@as(u8, 0), e); | 401 | try testing.expectEqual(@as(u8, 0), e); |
lib/std/meta.zig+4-3| ... | @@ -860,9 +860,10 @@ test "std.meta.eql" { | ... | @@ -860,9 +860,10 @@ test "std.meta.eql" { |
| 860 | try testing.expect(eql(EU.tst(false), EU.tst(false))); | 860 | try testing.expect(eql(EU.tst(false), EU.tst(false))); |
| 861 | try testing.expect(!eql(EU.tst(false), EU.tst(true))); | 861 | try testing.expect(!eql(EU.tst(false), EU.tst(true))); |
| 862 | 862 | ||
| 863 | var v1 = @splat(4, @as(u32, 1)); | 863 | const V = @Vector(4, u32); |
| 864 | var v2 = @splat(4, @as(u32, 1)); | 864 | var v1: V = @splat(1); |
| 865 | var v3 = @splat(4, @as(u32, 2)); | 865 | var v2: V = @splat(1); |
| 866 | var v3: V = @splat(2); | ||
| 866 | 867 | ||
| 867 | try testing.expect(eql(v1, v2)); | 868 | try testing.expect(eql(v1, v2)); |
| 868 | try testing.expect(!eql(v1, v3)); | 869 | try testing.expect(!eql(v1, v3)); |
lib/std/simd.zig+34-25| ... | @@ -107,7 +107,7 @@ pub inline fn iota(comptime T: type, comptime len: usize) @Vector(len, T) { | ... | @@ -107,7 +107,7 @@ pub inline fn iota(comptime T: type, comptime len: usize) @Vector(len, T) { |
| 107 | pub fn repeat(comptime len: usize, vec: anytype) @Vector(len, std.meta.Child(@TypeOf(vec))) { | 107 | pub fn repeat(comptime len: usize, vec: anytype) @Vector(len, std.meta.Child(@TypeOf(vec))) { |
| 108 | const Child = std.meta.Child(@TypeOf(vec)); | 108 | const Child = std.meta.Child(@TypeOf(vec)); |
| 109 | 109 | ||
| 110 | return @shuffle(Child, vec, undefined, iota(i32, len) % @splat(len, @as(i32, @intCast(vectorLength(@TypeOf(vec)))))); | 110 | return @shuffle(Child, vec, undefined, iota(i32, len) % @as(@Vector(len, i32), @splat(@intCast(vectorLength(@TypeOf(vec)))))); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | /// Returns a vector containing all elements of the first vector at the lower indices followed by all elements of the second vector | 113 | /// Returns a vector containing all elements of the first vector at the lower indices followed by all elements of the second vector |
| ... | @@ -147,11 +147,12 @@ pub fn interlace(vecs: anytype) @Vector(vectorLength(@TypeOf(vecs[0])) * vecs.le | ... | @@ -147,11 +147,12 @@ pub fn interlace(vecs: anytype) @Vector(vectorLength(@TypeOf(vecs[0])) * vecs.le |
| 147 | const len = a_len + b_len; | 147 | const len = a_len + b_len; |
| 148 | 148 | ||
| 149 | const indices = comptime blk: { | 149 | const indices = comptime blk: { |
| 150 | const Vi32 = @Vector(len, i32); | ||
| 150 | const count_up = iota(i32, len); | 151 | const count_up = iota(i32, len); |
| 151 | const cycle = @divFloor(count_up, @splat(len, @as(i32, @intCast(vecs_arr.len)))); | 152 | const cycle = @divFloor(count_up, @as(Vi32, @splat(@intCast(vecs_arr.len)))); |
| 152 | const select_mask = repeat(len, join(@splat(a_vec_count, true), @splat(b_vec_count, false))); | 153 | const select_mask = repeat(len, join(@as(@Vector(a_vec_count, bool), @splat(true)), @as(@Vector(b_vec_count, bool), @splat(false)))); |
| 153 | const a_indices = count_up - cycle * @splat(len, @as(i32, @intCast(b_vec_count))); | 154 | const a_indices = count_up - cycle * @as(Vi32, @splat(@intCast(b_vec_count))); |
| 154 | const b_indices = shiftElementsRight(count_up - cycle * @splat(len, @as(i32, @intCast(a_vec_count))), a_vec_count, 0); | 155 | const b_indices = shiftElementsRight(count_up - cycle * @as(Vi32, @splat(@intCast(a_vec_count))), a_vec_count, 0); |
| 155 | break :blk @select(i32, select_mask, a_indices, ~b_indices); | 156 | break :blk @select(i32, select_mask, a_indices, ~b_indices); |
| 156 | }; | 157 | }; |
| 157 | 158 | ||
| ... | @@ -174,7 +175,7 @@ pub fn deinterlace( | ... | @@ -174,7 +175,7 @@ pub fn deinterlace( |
| 174 | 175 | ||
| 175 | comptime var i: usize = 0; // for-loops don't work for this, apparently. | 176 | comptime var i: usize = 0; // for-loops don't work for this, apparently. |
| 176 | inline while (i < out.len) : (i += 1) { | 177 | inline while (i < out.len) : (i += 1) { |
| 177 | const indices = comptime iota(i32, vec_len) * @splat(vec_len, @as(i32, @intCast(vec_count))) + @splat(vec_len, @as(i32, @intCast(i))); | 178 | const indices = comptime iota(i32, vec_len) * @as(@Vector(vec_len, i32), @splat(@intCast(vec_count))) + @as(@Vector(vec_len, i32), @splat(@intCast(i))); |
| 178 | out[i] = @shuffle(Child, interlaced, undefined, indices); | 179 | out[i] = @shuffle(Child, interlaced, undefined, indices); |
| 179 | } | 180 | } |
| 180 | 181 | ||
| ... | @@ -191,7 +192,7 @@ pub fn extract( | ... | @@ -191,7 +192,7 @@ pub fn extract( |
| 191 | 192 | ||
| 192 | std.debug.assert(@as(comptime_int, @intCast(first)) + @as(comptime_int, @intCast(count)) <= len); | 193 | std.debug.assert(@as(comptime_int, @intCast(first)) + @as(comptime_int, @intCast(count)) <= len); |
| 193 | 194 | ||
| 194 | return @shuffle(Child, vec, undefined, iota(i32, count) + @splat(count, @as(i32, @intCast(first)))); | 195 | return @shuffle(Child, vec, undefined, iota(i32, count) + @as(@Vector(count, i32), @splat(@intCast(first)))); |
| 195 | } | 196 | } |
| 196 | 197 | ||
| 197 | test "vector patterns" { | 198 | test "vector patterns" { |
| ... | @@ -236,17 +237,18 @@ pub fn shiftElementsRight(vec: anytype, comptime amount: VectorCount(@TypeOf(vec | ... | @@ -236,17 +237,18 @@ pub fn shiftElementsRight(vec: anytype, comptime amount: VectorCount(@TypeOf(vec |
| 236 | // It may be possible to implement shifts and rotates with a runtime-friendly slice of two joined vectors, as the length of the | 237 | // It may be possible to implement shifts and rotates with a runtime-friendly slice of two joined vectors, as the length of the |
| 237 | // slice would be comptime-known. This would permit vector shifts and rotates by a non-comptime-known amount. | 238 | // slice would be comptime-known. This would permit vector shifts and rotates by a non-comptime-known amount. |
| 238 | // However, I am unsure whether compiler optimizations would handle that well enough on all platforms. | 239 | // However, I am unsure whether compiler optimizations would handle that well enough on all platforms. |
| 239 | const len = vectorLength(@TypeOf(vec)); | 240 | const V = @TypeOf(vec); |
| 241 | const len = vectorLength(V); | ||
| 240 | 242 | ||
| 241 | return mergeShift(@splat(len, shift_in), vec, len - amount); | 243 | return mergeShift(@as(V, @splat(shift_in)), vec, len - amount); |
| 242 | } | 244 | } |
| 243 | 245 | ||
| 244 | /// Elements are shifted leftwards (towards lower indices). New elements are added to the right, and the leftmost elements are cut off | 246 | /// Elements are shifted leftwards (towards lower indices). New elements are added to the right, and the leftmost elements are cut off |
| 245 | /// so that no elements with indices below 0 remain. | 247 | /// so that no elements with indices below 0 remain. |
| 246 | pub fn shiftElementsLeft(vec: anytype, comptime amount: VectorCount(@TypeOf(vec)), shift_in: std.meta.Child(@TypeOf(vec))) @TypeOf(vec) { | 248 | pub fn shiftElementsLeft(vec: anytype, comptime amount: VectorCount(@TypeOf(vec)), shift_in: std.meta.Child(@TypeOf(vec))) @TypeOf(vec) { |
| 247 | const len = vectorLength(@TypeOf(vec)); | 249 | const V = @TypeOf(vec); |
| 248 | 250 | ||
| 249 | return mergeShift(vec, @splat(len, shift_in), amount); | 251 | return mergeShift(vec, @as(V, @splat(shift_in)), amount); |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | /// Elements are shifted leftwards (towards lower indices). Elements that leave to the left will reappear to the right in the same order. | 254 | /// Elements are shifted leftwards (towards lower indices). Elements that leave to the left will reappear to the right in the same order. |
| ... | @@ -263,7 +265,7 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) { | ... | @@ -263,7 +265,7 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) { |
| 263 | const Child = std.meta.Child(@TypeOf(vec)); | 265 | const Child = std.meta.Child(@TypeOf(vec)); |
| 264 | const len = vectorLength(@TypeOf(vec)); | 266 | const len = vectorLength(@TypeOf(vec)); |
| 265 | 267 | ||
| 266 | return @shuffle(Child, vec, undefined, @splat(len, @as(i32, @intCast(len)) - 1) - iota(i32, len)); | 268 | return @shuffle(Child, vec, undefined, @as(@Vector(len, i32), @splat(@as(i32, @intCast(len)) - 1)) - iota(i32, len)); |
| 267 | } | 269 | } |
| 268 | 270 | ||
| 269 | test "vector shifting" { | 271 | test "vector shifting" { |
| ... | @@ -283,7 +285,8 @@ pub fn firstTrue(vec: anytype) ?VectorIndex(@TypeOf(vec)) { | ... | @@ -283,7 +285,8 @@ pub fn firstTrue(vec: anytype) ?VectorIndex(@TypeOf(vec)) { |
| 283 | if (!@reduce(.Or, vec)) { | 285 | if (!@reduce(.Or, vec)) { |
| 284 | return null; | 286 | return null; |
| 285 | } | 287 | } |
| 286 | const indices = @select(IndexInt, vec, iota(IndexInt, len), @splat(len, ~@as(IndexInt, 0))); | 288 | const all_max: @Vector(len, IndexInt) = @splat(~@as(IndexInt, 0)); |
| 289 | const indices = @select(IndexInt, vec, iota(IndexInt, len), all_max); | ||
| 287 | return @reduce(.Min, indices); | 290 | return @reduce(.Min, indices); |
| 288 | } | 291 | } |
| 289 | 292 | ||
| ... | @@ -294,7 +297,9 @@ pub fn lastTrue(vec: anytype) ?VectorIndex(@TypeOf(vec)) { | ... | @@ -294,7 +297,9 @@ pub fn lastTrue(vec: anytype) ?VectorIndex(@TypeOf(vec)) { |
| 294 | if (!@reduce(.Or, vec)) { | 297 | if (!@reduce(.Or, vec)) { |
| 295 | return null; | 298 | return null; |
| 296 | } | 299 | } |
| 297 | const indices = @select(IndexInt, vec, iota(IndexInt, len), @splat(len, @as(IndexInt, 0))); | 300 | |
| 301 | const all_zeroes: @Vector(len, IndexInt) = @splat(0); | ||
| 302 | const indices = @select(IndexInt, vec, iota(IndexInt, len), all_zeroes); | ||
| 298 | return @reduce(.Max, indices); | 303 | return @reduce(.Max, indices); |
| 299 | } | 304 | } |
| 300 | 305 | ||
| ... | @@ -302,26 +307,29 @@ pub fn countTrues(vec: anytype) VectorCount(@TypeOf(vec)) { | ... | @@ -302,26 +307,29 @@ pub fn countTrues(vec: anytype) VectorCount(@TypeOf(vec)) { |
| 302 | const len = vectorLength(@TypeOf(vec)); | 307 | const len = vectorLength(@TypeOf(vec)); |
| 303 | const CountIntType = VectorCount(@TypeOf(vec)); | 308 | const CountIntType = VectorCount(@TypeOf(vec)); |
| 304 | 309 | ||
| 305 | const one_if_true = @select(CountIntType, vec, @splat(len, @as(CountIntType, 1)), @splat(len, @as(CountIntType, 0))); | 310 | const all_ones: @Vector(len, CountIntType) = @splat(1); |
| 311 | const all_zeroes: @Vector(len, CountIntType) = @splat(0); | ||
| 312 | |||
| 313 | const one_if_true = @select(CountIntType, vec, all_ones, all_zeroes); | ||
| 306 | return @reduce(.Add, one_if_true); | 314 | return @reduce(.Add, one_if_true); |
| 307 | } | 315 | } |
| 308 | 316 | ||
| 309 | pub fn firstIndexOfValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) ?VectorIndex(@TypeOf(vec)) { | 317 | pub fn firstIndexOfValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) ?VectorIndex(@TypeOf(vec)) { |
| 310 | const len = vectorLength(@TypeOf(vec)); | 318 | const V = @TypeOf(vec); |
| 311 | 319 | ||
| 312 | return firstTrue(vec == @splat(len, value)); | 320 | return firstTrue(vec == @as(V, @splat(value))); |
| 313 | } | 321 | } |
| 314 | 322 | ||
| 315 | pub fn lastIndexOfValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) ?VectorIndex(@TypeOf(vec)) { | 323 | pub fn lastIndexOfValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) ?VectorIndex(@TypeOf(vec)) { |
| 316 | const len = vectorLength(@TypeOf(vec)); | 324 | const V = @TypeOf(vec); |
| 317 | 325 | ||
| 318 | return lastTrue(vec == @splat(len, value)); | 326 | return lastTrue(vec == @as(V, @splat(value))); |
| 319 | } | 327 | } |
| 320 | 328 | ||
| 321 | pub fn countElementsWithValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) VectorCount(@TypeOf(vec)) { | 329 | pub fn countElementsWithValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) VectorCount(@TypeOf(vec)) { |
| 322 | const len = vectorLength(@TypeOf(vec)); | 330 | const V = @TypeOf(vec); |
| 323 | 331 | ||
| 324 | return countTrues(vec == @splat(len, value)); | 332 | return countTrues(vec == @as(V, @splat(value))); |
| 325 | } | 333 | } |
| 326 | 334 | ||
| 327 | test "vector searching" { | 335 | test "vector searching" { |
| ... | @@ -370,7 +378,6 @@ pub fn prefixScanWithFunc( | ... | @@ -370,7 +378,6 @@ pub fn prefixScanWithFunc( |
| 370 | pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: anytype) @TypeOf(vec) { | 378 | pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: anytype) @TypeOf(vec) { |
| 371 | const VecType = @TypeOf(vec); | 379 | const VecType = @TypeOf(vec); |
| 372 | const Child = std.meta.Child(VecType); | 380 | const Child = std.meta.Child(VecType); |
| 373 | const len = vectorLength(VecType); | ||
| 374 | 381 | ||
| 375 | const identity = comptime switch (@typeInfo(Child)) { | 382 | const identity = comptime switch (@typeInfo(Child)) { |
| 376 | .Bool => switch (op) { | 383 | .Bool => switch (op) { |
| ... | @@ -397,8 +404,8 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a | ... | @@ -397,8 +404,8 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a |
| 397 | const fn_container = struct { | 404 | const fn_container = struct { |
| 398 | fn opFn(a: VecType, b: VecType) VecType { | 405 | fn opFn(a: VecType, b: VecType) VecType { |
| 399 | return if (Child == bool) switch (op) { | 406 | return if (Child == bool) switch (op) { |
| 400 | .And => @select(bool, a, b, @splat(len, false)), | 407 | .And => @select(bool, a, b, @as(VecType, @splat(false))), |
| 401 | .Or => @select(bool, a, @splat(len, true), b), | 408 | .Or => @select(bool, a, @as(VecType, @splat(true)), b), |
| 402 | .Xor => a != b, | 409 | .Xor => a != b, |
| 403 | else => unreachable, | 410 | else => unreachable, |
| 404 | } else switch (op) { | 411 | } else switch (op) { |
| ... | @@ -431,7 +438,9 @@ test "vector prefix scan" { | ... | @@ -431,7 +438,9 @@ test "vector prefix scan" { |
| 431 | const float_base = @Vector(4, f32){ 2, 0.5, -10, 6.54321 }; | 438 | const float_base = @Vector(4, f32){ 2, 0.5, -10, 6.54321 }; |
| 432 | const bool_base = @Vector(4, bool){ true, false, true, false }; | 439 | const bool_base = @Vector(4, bool){ true, false, true, false }; |
| 433 | 440 | ||
| 434 | try std.testing.expectEqual(iota(u8, 32) + @splat(32, @as(u8, 1)), prefixScan(.Add, 1, @splat(32, @as(u8, 1)))); | 441 | const ones: @Vector(32, u8) = @splat(1); |
| 442 | |||
| 443 | try std.testing.expectEqual(iota(u8, 32) + ones, prefixScan(.Add, 1, ones)); | ||
| 435 | try std.testing.expectEqual(@Vector(4, i32){ 11, 3, 1, 1 }, prefixScan(.And, 1, int_base)); | 444 | try std.testing.expectEqual(@Vector(4, i32){ 11, 3, 1, 1 }, prefixScan(.And, 1, int_base)); |
| 436 | try std.testing.expectEqual(@Vector(4, i32){ 11, 31, 31, -1 }, prefixScan(.Or, 1, int_base)); | 445 | try std.testing.expectEqual(@Vector(4, i32){ 11, 31, 31, -1 }, prefixScan(.Or, 1, int_base)); |
| 437 | try std.testing.expectEqual(@Vector(4, i32){ 11, 28, 21, -2 }, prefixScan(.Xor, 1, int_base)); | 446 | try std.testing.expectEqual(@Vector(4, i32){ 11, 28, 21, -2 }, prefixScan(.Xor, 1, int_base)); |
lib/std/testing.zig+3-3| ... | @@ -606,8 +606,8 @@ test "expectEqual nested array" { | ... | @@ -606,8 +606,8 @@ test "expectEqual nested array" { |
| 606 | } | 606 | } |
| 607 | 607 | ||
| 608 | test "expectEqual vector" { | 608 | test "expectEqual vector" { |
| 609 | var a = @splat(4, @as(u32, 4)); | 609 | var a: @Vector(4, u32) = @splat(4); |
| 610 | var b = @splat(4, @as(u32, 4)); | 610 | var b: @Vector(4, u32) = @splat(4); |
| 611 | 611 | ||
| 612 | try expectEqual(a, b); | 612 | try expectEqual(a, b); |
| 613 | } | 613 | } |
| ... | @@ -903,7 +903,7 @@ test "expectEqualDeep composite type" { | ... | @@ -903,7 +903,7 @@ test "expectEqualDeep composite type" { |
| 903 | try expectEqualDeep([_][]const u8{ "a", "b", "c" }, [_][]const u8{ "a", "b", "c" }); | 903 | try expectEqualDeep([_][]const u8{ "a", "b", "c" }, [_][]const u8{ "a", "b", "c" }); |
| 904 | 904 | ||
| 905 | // vector | 905 | // vector |
| 906 | try expectEqualDeep(@splat(4, @as(u32, 4)), @splat(4, @as(u32, 4))); | 906 | try expectEqualDeep(@as(@Vector(4, u32), @splat(4)), @as(@Vector(4, u32), @splat(4))); |
| 907 | 907 | ||
| 908 | // nested array | 908 | // nested array |
| 909 | { | 909 | { |
src/AstGen.zig+10-3| ... | @@ -8591,10 +8591,17 @@ fn builtinCall( | ... | @@ -8591,10 +8591,17 @@ fn builtinCall( |
| 8591 | }, | 8591 | }, |
| 8592 | 8592 | ||
| 8593 | .splat => { | 8593 | .splat => { |
| 8594 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); | 8594 | const result_type = try ri.rl.resultType(gz, node, "@splat"); |
| 8595 | const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); | 8595 | const elem_type = try gz.add(.{ |
| 8596 | .tag = .elem_type_index, | ||
| 8597 | .data = .{ .bin = .{ | ||
| 8598 | .lhs = result_type, | ||
| 8599 | .rhs = @as(Zir.Inst.Ref, @enumFromInt(0)), | ||
| 8600 | } }, | ||
| 8601 | }); | ||
| 8602 | const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]); | ||
| 8596 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ | 8603 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ |
| 8597 | .lhs = len, | 8604 | .lhs = result_type, |
| 8598 | .rhs = scalar, | 8605 | .rhs = scalar, |
| 8599 | }); | 8606 | }); |
| 8600 | return rvalue(gz, ri, result, node); | 8607 | return rvalue(gz, ri, result, node); |
src/BuiltinFn.zig+1-1| ... | @@ -792,7 +792,7 @@ pub const list = list: { | ... | @@ -792,7 +792,7 @@ pub const list = list: { |
| 792 | "@splat", | 792 | "@splat", |
| 793 | .{ | 793 | .{ |
| 794 | .tag = .splat, | 794 | .tag = .splat, |
| 795 | .param_count = 2, | 795 | .param_count = 1, |
| 796 | }, | 796 | }, |
| 797 | }, | 797 | }, |
| 798 | .{ | 798 | .{ |
src/Sema.zig+24-25| ... | @@ -1820,7 +1820,7 @@ pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Ins | ... | @@ -1820,7 +1820,7 @@ pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Ins |
| 1820 | return ty; | 1820 | return ty; |
| 1821 | } | 1821 | } |
| 1822 | 1822 | ||
| 1823 | fn resolveCastDestType( | 1823 | fn resolveDestType( |
| 1824 | sema: *Sema, | 1824 | sema: *Sema, |
| 1825 | block: *Block, | 1825 | block: *Block, |
| 1826 | src: LazySrcLoc, | 1826 | src: LazySrcLoc, |
| ... | @@ -8337,7 +8337,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8337,7 +8337,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8337 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8337 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8338 | const src = inst_data.src(); | 8338 | const src = inst_data.src(); |
| 8339 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 8339 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 8340 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt"); | 8340 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt"); |
| 8341 | const operand = try sema.resolveInst(extra.rhs); | 8341 | const operand = try sema.resolveInst(extra.rhs); |
| 8342 | 8342 | ||
| 8343 | if (dest_ty.zigTypeTag(mod) != .Enum) { | 8343 | if (dest_ty.zigTypeTag(mod) != .Enum) { |
| ... | @@ -9666,7 +9666,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -9666,7 +9666,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 9666 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 9666 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9667 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 9667 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 9668 | 9668 | ||
| 9669 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast"); | 9669 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast"); |
| 9670 | const operand = try sema.resolveInst(extra.rhs); | 9670 | const operand = try sema.resolveInst(extra.rhs); |
| 9671 | 9671 | ||
| 9672 | return sema.intCast(block, inst_data.src(), dest_ty, src, operand, operand_src, true); | 9672 | return sema.intCast(block, inst_data.src(), dest_ty, src, operand, operand_src, true); |
| ... | @@ -9827,7 +9827,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -9827,7 +9827,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 9827 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 9827 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9828 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 9828 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 9829 | 9829 | ||
| 9830 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast"); | 9830 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast"); |
| 9831 | const operand = try sema.resolveInst(extra.rhs); | 9831 | const operand = try sema.resolveInst(extra.rhs); |
| 9832 | const operand_ty = sema.typeOf(operand); | 9832 | const operand_ty = sema.typeOf(operand); |
| 9833 | switch (dest_ty.zigTypeTag(mod)) { | 9833 | switch (dest_ty.zigTypeTag(mod)) { |
| ... | @@ -9970,7 +9970,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -9970,7 +9970,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 9970 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 9970 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9971 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 9971 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 9972 | 9972 | ||
| 9973 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast"); | 9973 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast"); |
| 9974 | const operand = try sema.resolveInst(extra.rhs); | 9974 | const operand = try sema.resolveInst(extra.rhs); |
| 9975 | 9975 | ||
| 9976 | const target = mod.getTarget(); | 9976 | const target = mod.getTarget(); |
| ... | @@ -20783,7 +20783,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -20783,7 +20783,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 20783 | const src = inst_data.src(); | 20783 | const src = inst_data.src(); |
| 20784 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 20784 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 20785 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 20785 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 20786 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat"); | 20786 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat"); |
| 20787 | const operand = try sema.resolveInst(extra.rhs); | 20787 | const operand = try sema.resolveInst(extra.rhs); |
| 20788 | const operand_ty = sema.typeOf(operand); | 20788 | const operand_ty = sema.typeOf(operand); |
| 20789 | 20789 | ||
| ... | @@ -20823,7 +20823,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -20823,7 +20823,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 20823 | const src = inst_data.src(); | 20823 | const src = inst_data.src(); |
| 20824 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 20824 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 20825 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 20825 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 20826 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt"); | 20826 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt"); |
| 20827 | const operand = try sema.resolveInst(extra.rhs); | 20827 | const operand = try sema.resolveInst(extra.rhs); |
| 20828 | const operand_ty = sema.typeOf(operand); | 20828 | const operand_ty = sema.typeOf(operand); |
| 20829 | 20829 | ||
| ... | @@ -20852,7 +20852,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -20852,7 +20852,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 20852 | const operand_res = try sema.resolveInst(extra.rhs); | 20852 | const operand_res = try sema.resolveInst(extra.rhs); |
| 20853 | const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src); | 20853 | const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src); |
| 20854 | 20854 | ||
| 20855 | const ptr_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt"); | 20855 | const ptr_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt"); |
| 20856 | try sema.checkPtrType(block, src, ptr_ty); | 20856 | try sema.checkPtrType(block, src, ptr_ty); |
| 20857 | const elem_ty = ptr_ty.elemType2(mod); | 20857 | const elem_ty = ptr_ty.elemType2(mod); |
| 20858 | const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema); | 20858 | const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema); |
| ... | @@ -20910,7 +20910,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -20910,7 +20910,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 20910 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 20910 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 20911 | const src = LazySrcLoc.nodeOffset(extra.node); | 20911 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 20912 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; | 20912 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 20913 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@errSetCast"); | 20913 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@errSetCast"); |
| 20914 | const operand = try sema.resolveInst(extra.rhs); | 20914 | const operand = try sema.resolveInst(extra.rhs); |
| 20915 | const operand_ty = sema.typeOf(operand); | 20915 | const operand_ty = sema.typeOf(operand); |
| 20916 | try sema.checkErrorSetType(block, src, dest_ty); | 20916 | try sema.checkErrorSetType(block, src, dest_ty); |
| ... | @@ -20997,7 +20997,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa | ... | @@ -20997,7 +20997,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa |
| 20997 | const src = LazySrcLoc.nodeOffset(extra.node); | 20997 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 20998 | const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node }; | 20998 | const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node }; |
| 20999 | const operand = try sema.resolveInst(extra.rhs); | 20999 | const operand = try sema.resolveInst(extra.rhs); |
| 21000 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName()); | 21000 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName()); |
| 21001 | return sema.ptrCastFull( | 21001 | return sema.ptrCastFull( |
| 21002 | block, | 21002 | block, |
| 21003 | flags, | 21003 | flags, |
| ... | @@ -21013,7 +21013,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21013,7 +21013,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21013 | const src = inst_data.src(); | 21013 | const src = inst_data.src(); |
| 21014 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 21014 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 21015 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 21015 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 21016 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, "@ptrCast"); | 21016 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrCast"); |
| 21017 | const operand = try sema.resolveInst(extra.rhs); | 21017 | const operand = try sema.resolveInst(extra.rhs); |
| 21018 | 21018 | ||
| 21019 | return sema.ptrCastFull( | 21019 | return sema.ptrCastFull( |
| ... | @@ -21426,7 +21426,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -21426,7 +21426,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 21426 | const src = inst_data.src(); | 21426 | const src = inst_data.src(); |
| 21427 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 21427 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 21428 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 21428 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 21429 | const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate"); | 21429 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate"); |
| 21430 | const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src); | 21430 | const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src); |
| 21431 | const operand = try sema.resolveInst(extra.rhs); | 21431 | const operand = try sema.resolveInst(extra.rhs); |
| 21432 | const operand_ty = sema.typeOf(operand); | 21432 | const operand_ty = sema.typeOf(operand); |
| ... | @@ -22358,23 +22358,22 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -22358,23 +22358,22 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 22358 | const mod = sema.mod; | 22358 | const mod = sema.mod; |
| 22359 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 22359 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 22360 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 22360 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 22361 | const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 22361 | const src = inst_data.src(); |
| 22362 | const scalar_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 22362 | const scalar_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 22363 | const len = @as(u32, @intCast(try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector splat destination length must be comptime-known"))); | 22363 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat"); |
| 22364 | const scalar = try sema.resolveInst(extra.rhs); | 22364 | |
| 22365 | const scalar_ty = sema.typeOf(scalar); | 22365 | if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(mod)}); |
| 22366 | try sema.checkVectorElemType(block, scalar_src, scalar_ty); | 22366 | |
| 22367 | const vector_ty = try mod.vectorType(.{ | 22367 | const operand = try sema.resolveInst(extra.rhs); |
| 22368 | .len = len, | 22368 | const scalar_ty = dest_ty.childType(mod); |
| 22369 | .child = scalar_ty.toIntern(), | 22369 | const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src); |
| 22370 | }); | ||
| 22371 | if (try sema.resolveMaybeUndefVal(scalar)) |scalar_val| { | 22370 | if (try sema.resolveMaybeUndefVal(scalar)) |scalar_val| { |
| 22372 | if (scalar_val.isUndef(mod)) return sema.addConstUndef(vector_ty); | 22371 | if (scalar_val.isUndef(mod)) return sema.addConstUndef(dest_ty); |
| 22373 | return sema.addConstant(try sema.splat(vector_ty, scalar_val)); | 22372 | return sema.addConstant(try sema.splat(dest_ty, scalar_val)); |
| 22374 | } | 22373 | } |
| 22375 | 22374 | ||
| 22376 | try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src); | 22375 | try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src); |
| 22377 | return block.addTyOp(.splat, vector_ty, scalar); | 22376 | return block.addTyOp(.splat, dest_ty, scalar); |
| 22378 | } | 22377 | } |
| 22379 | 22378 | ||
| 22380 | fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22379 | fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
src/translate_c.zig+6-6| ... | @@ -2799,14 +2799,14 @@ fn transInitListExprVector( | ... | @@ -2799,14 +2799,14 @@ fn transInitListExprVector( |
| 2799 | const element_qt = vector_ty.getElementType(); | 2799 | const element_qt = vector_ty.getElementType(); |
| 2800 | 2800 | ||
| 2801 | if (init_count == 0) { | 2801 | if (init_count == 0) { |
| 2802 | const zero_node = try Tag.as.create(c.arena, .{ | 2802 | const vec_node = try Tag.vector.create(c.arena, .{ |
| 2803 | .lhs = try transQualType(c, scope, element_qt, loc), | 2803 | .lhs = try transCreateNodeNumber(c, num_elements, .int), |
| 2804 | .rhs = Tag.zero_literal.init(), | 2804 | .rhs = try transQualType(c, scope, element_qt, loc), |
| 2805 | }); | 2805 | }); |
| 2806 | 2806 | ||
| 2807 | return Tag.vector_zero_init.create(c.arena, .{ | 2807 | return Tag.as.create(c.arena, .{ |
| 2808 | .lhs = try transCreateNodeNumber(c, num_elements, .int), | 2808 | .lhs = vec_node, |
| 2809 | .rhs = zero_node, | 2809 | .rhs = try Tag.vector_zero_init.create(c.arena, Tag.zero_literal.init()), |
| 2810 | }); | 2810 | }); |
| 2811 | } | 2811 | } |
| 2812 | 2812 |
src/translate_c/ast.zig+3-3| ... | @@ -153,7 +153,7 @@ pub const Node = extern union { | ... | @@ -153,7 +153,7 @@ pub const Node = extern union { |
| 153 | div_exact, | 153 | div_exact, |
| 154 | /// @offsetOf(lhs, rhs) | 154 | /// @offsetOf(lhs, rhs) |
| 155 | offset_of, | 155 | offset_of, |
| 156 | /// @splat(lhs, rhs) | 156 | /// @splat(operand) |
| 157 | vector_zero_init, | 157 | vector_zero_init, |
| 158 | /// @shuffle(type, a, b, mask) | 158 | /// @shuffle(type, a, b, mask) |
| 159 | shuffle, | 159 | shuffle, |
| ... | @@ -284,6 +284,7 @@ pub const Node = extern union { | ... | @@ -284,6 +284,7 @@ pub const Node = extern union { |
| 284 | .int_cast, | 284 | .int_cast, |
| 285 | .const_cast, | 285 | .const_cast, |
| 286 | .volatile_cast, | 286 | .volatile_cast, |
| 287 | .vector_zero_init, | ||
| 287 | => Payload.UnOp, | 288 | => Payload.UnOp, |
| 288 | 289 | ||
| 289 | .add, | 290 | .add, |
| ... | @@ -334,7 +335,6 @@ pub const Node = extern union { | ... | @@ -334,7 +335,6 @@ pub const Node = extern union { |
| 334 | .div_exact, | 335 | .div_exact, |
| 335 | .offset_of, | 336 | .offset_of, |
| 336 | .helpers_cast, | 337 | .helpers_cast, |
| 337 | .vector_zero_init, | ||
| 338 | => Payload.BinOp, | 338 | => Payload.BinOp, |
| 339 | 339 | ||
| 340 | .integer_literal, | 340 | .integer_literal, |
| ... | @@ -1918,7 +1918,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1918,7 +1918,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1918 | }, | 1918 | }, |
| 1919 | .vector_zero_init => { | 1919 | .vector_zero_init => { |
| 1920 | const payload = node.castTag(.vector_zero_init).?.data; | 1920 | const payload = node.castTag(.vector_zero_init).?.data; |
| 1921 | return renderBuiltinCall(c, "@splat", &.{ payload.lhs, payload.rhs }); | 1921 | return renderBuiltinCall(c, "@splat", &.{payload}); |
| 1922 | }, | 1922 | }, |
| 1923 | .field_access => { | 1923 | .field_access => { |
| 1924 | const payload = node.castTag(.field_access).?.data; | 1924 | const payload = node.castTag(.field_access).?.data; |
stage1/zig.h-6| ... | @@ -3178,12 +3178,6 @@ zig_bitCast_float(f64, uint64_t) | ... | @@ -3178,12 +3178,6 @@ zig_bitCast_float(f64, uint64_t) |
| 3178 | zig_bitCast_float(f80, zig_u128) | 3178 | zig_bitCast_float(f80, zig_u128) |
| 3179 | zig_bitCast_float(f128, zig_u128) | 3179 | zig_bitCast_float(f128, zig_u128) |
| 3180 | 3180 | ||
| 3181 | #define zig_cast_f16 | ||
| 3182 | #define zig_cast_f32 | ||
| 3183 | #define zig_cast_f64 | ||
| 3184 | #define zig_cast_f80 | ||
| 3185 | #define zig_cast_f128 | ||
| 3186 | |||
| 3187 | #define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \ | 3181 | #define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \ |
| 3188 | zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | 3182 | zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3189 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \ | 3183 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \ |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ | |||
test/behavior/bitcast.zig+1-1| ... | @@ -396,7 +396,7 @@ test "bitcast vector to integer and back" { | ... | @@ -396,7 +396,7 @@ test "bitcast vector to integer and back" { |
| 396 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 396 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 397 | 397 | ||
| 398 | const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14; | 398 | const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14; |
| 399 | var x = @splat(16, true); | 399 | var x: @Vector(16, bool) = @splat(true); |
| 400 | x[1] = false; | 400 | x[1] = false; |
| 401 | try expect(@as(u16, @bitCast(x)) == comptime @as(u16, @bitCast(@as(@Vector(16, bool), arr)))); | 401 | try expect(@as(u16, @bitCast(x)) == comptime @as(u16, @bitCast(@as(@Vector(16, bool), arr)))); |
| 402 | } | 402 | } |
test/behavior/cast.zig+1-1| ... | @@ -639,7 +639,7 @@ test "vector casts" { | ... | @@ -639,7 +639,7 @@ test "vector casts" { |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | fn doTheTestFloat() !void { | 641 | fn doTheTestFloat() !void { |
| 642 | var vec = @splat(2, @as(f32, 1234.0)); | 642 | var vec: @Vector(2, f32) = @splat(1234.0); |
| 643 | var wider: @Vector(2, f64) = vec; | 643 | var wider: @Vector(2, f64) = vec; |
| 644 | try expect(wider[0] == 1234.0); | 644 | try expect(wider[0] == 1234.0); |
| 645 | try expect(wider[1] == 1234.0); | 645 | try expect(wider[1] == 1234.0); |
test/behavior/math.zig+16-10| ... | @@ -111,13 +111,17 @@ test "@clz vectors" { | ... | @@ -111,13 +111,17 @@ test "@clz vectors" { |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | fn testClzVectors() !void { | 113 | fn testClzVectors() !void { |
| 114 | const Vu4 = @Vector(64, u4); | ||
| 115 | const Vu8 = @Vector(64, u8); | ||
| 116 | const Vu128 = @Vector(64, u128); | ||
| 117 | |||
| 114 | @setEvalBranchQuota(10_000); | 118 | @setEvalBranchQuota(10_000); |
| 115 | try testOneClzVector(u8, 64, @splat(64, @as(u8, 0b10001010)), @splat(64, @as(u4, 0))); | 119 | try testOneClzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(0))); |
| 116 | try testOneClzVector(u8, 64, @splat(64, @as(u8, 0b00001010)), @splat(64, @as(u4, 4))); | 120 | try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00001010)), @as(Vu4, @splat(4))); |
| 117 | try testOneClzVector(u8, 64, @splat(64, @as(u8, 0b00011010)), @splat(64, @as(u4, 3))); | 121 | try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00011010)), @as(Vu4, @splat(3))); |
| 118 | try testOneClzVector(u8, 64, @splat(64, @as(u8, 0b00000000)), @splat(64, @as(u4, 8))); | 122 | try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8))); |
| 119 | try testOneClzVector(u128, 64, @splat(64, @as(u128, 0xffffffffffffffff)), @splat(64, @as(u8, 64))); | 123 | try testOneClzVector(u128, 64, @as(Vu128, @splat(0xffffffffffffffff)), @as(Vu8, @splat(64))); |
| 120 | try testOneClzVector(u128, 64, @splat(64, @as(u128, 0x10000000000000000)), @splat(64, @as(u8, 63))); | 124 | try testOneClzVector(u128, 64, @as(Vu128, @splat(0x10000000000000000)), @as(Vu8, @splat(63))); |
| 121 | } | 125 | } |
| 122 | 126 | ||
| 123 | fn testOneClzVector( | 127 | fn testOneClzVector( |
| ... | @@ -180,11 +184,13 @@ test "@ctz vectors" { | ... | @@ -180,11 +184,13 @@ test "@ctz vectors" { |
| 180 | } | 184 | } |
| 181 | 185 | ||
| 182 | fn testCtzVectors() !void { | 186 | fn testCtzVectors() !void { |
| 187 | const Vu4 = @Vector(64, u4); | ||
| 188 | const Vu8 = @Vector(64, u8); | ||
| 183 | @setEvalBranchQuota(10_000); | 189 | @setEvalBranchQuota(10_000); |
| 184 | try testOneCtzVector(u8, 64, @splat(64, @as(u8, 0b10100000)), @splat(64, @as(u4, 5))); | 190 | try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10100000)), @as(Vu4, @splat(5))); |
| 185 | try testOneCtzVector(u8, 64, @splat(64, @as(u8, 0b10001010)), @splat(64, @as(u4, 1))); | 191 | try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(1))); |
| 186 | try testOneCtzVector(u8, 64, @splat(64, @as(u8, 0b00000000)), @splat(64, @as(u4, 8))); | 192 | try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8))); |
| 187 | try testOneCtzVector(u16, 64, @splat(64, @as(u16, 0b00000000)), @splat(64, @as(u5, 16))); | 193 | try testOneCtzVector(u16, 64, @as(@Vector(64, u16), @splat(0b00000000)), @as(@Vector(64, u5), @splat(16))); |
| 188 | } | 194 | } |
| 189 | 195 | ||
| 190 | fn testOneCtzVector( | 196 | fn testOneCtzVector( |
test/behavior/vector.zig+21-18| ... | @@ -299,8 +299,7 @@ test "vector @splat" { | ... | @@ -299,8 +299,7 @@ test "vector @splat" { |
| 299 | const S = struct { | 299 | const S = struct { |
| 300 | fn testForT(comptime N: comptime_int, v: anytype) !void { | 300 | fn testForT(comptime N: comptime_int, v: anytype) !void { |
| 301 | const T = @TypeOf(v); | 301 | const T = @TypeOf(v); |
| 302 | var vec = @splat(N, v); | 302 | var vec: @Vector(N, T) = @splat(v); |
| 303 | try expect(@Vector(N, T) == @TypeOf(vec)); | ||
| 304 | var as_array = @as([N]T, vec); | 303 | var as_array = @as([N]T, vec); |
| 305 | for (as_array) |elem| try expect(v == elem); | 304 | for (as_array) |elem| try expect(v == elem); |
| 306 | } | 305 | } |
| ... | @@ -458,26 +457,28 @@ test "vector comparison operators" { | ... | @@ -458,26 +457,28 @@ test "vector comparison operators" { |
| 458 | const S = struct { | 457 | const S = struct { |
| 459 | fn doTheTest() !void { | 458 | fn doTheTest() !void { |
| 460 | { | 459 | { |
| 461 | var v1: @Vector(4, bool) = [_]bool{ true, false, true, false }; | 460 | const V = @Vector(4, bool); |
| 462 | var v2: @Vector(4, bool) = [_]bool{ false, true, false, true }; | 461 | var v1: V = [_]bool{ true, false, true, false }; |
| 463 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 == v1))); | 462 | var v2: V = [_]bool{ false, true, false, true }; |
| 464 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 == v2))); | 463 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v1))); |
| 465 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 != v2))); | 464 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v2))); |
| 466 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v2 != v2))); | 465 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v2))); |
| 466 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v2 != v2))); | ||
| 467 | } | 467 | } |
| 468 | { | 468 | { |
| 469 | var v1 = @splat(4, @as(u32, 0xc0ffeeee)); | 469 | const V = @Vector(4, bool); |
| 470 | var v1: @Vector(4, u32) = @splat(0xc0ffeeee); | ||
| 470 | var v2: @Vector(4, c_uint) = v1; | 471 | var v2: @Vector(4, c_uint) = v1; |
| 471 | var v3 = @splat(4, @as(u32, 0xdeadbeef)); | 472 | var v3: @Vector(4, u32) = @splat(0xdeadbeef); |
| 472 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 == v2))); | 473 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 == v2))); |
| 473 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 == v3))); | 474 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 == v3))); |
| 474 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, true)), &@as([4]bool, v1 != v3))); | 475 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(true))), &@as([4]bool, v1 != v3))); |
| 475 | try expect(mem.eql(bool, &@as([4]bool, @splat(4, false)), &@as([4]bool, v1 != v2))); | 476 | try expect(mem.eql(bool, &@as([4]bool, @as(V, @splat(false))), &@as([4]bool, v1 != v2))); |
| 476 | } | 477 | } |
| 477 | { | 478 | { |
| 478 | // Comptime-known LHS/RHS | 479 | // Comptime-known LHS/RHS |
| 479 | var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 }; | 480 | var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 }; |
| 480 | const v2 = @splat(4, @as(u32, 2)); | 481 | const v2: @Vector(4, u32) = @splat(2); |
| 481 | const v3: @Vector(4, bool) = [_]bool{ true, false, true, false }; | 482 | const v3: @Vector(4, bool) = [_]bool{ true, false, true, false }; |
| 482 | try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v1 == v2))); | 483 | try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v1 == v2))); |
| 483 | try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v2 == v1))); | 484 | try expect(mem.eql(bool, &@as([4]bool, v3), &@as([4]bool, v2 == v1))); |
| ... | @@ -847,8 +848,10 @@ test "vector @reduce comptime" { | ... | @@ -847,8 +848,10 @@ test "vector @reduce comptime" { |
| 847 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 848 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 848 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 849 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 849 | 850 | ||
| 850 | const value = @Vector(4, i32){ 1, -1, 1, -1 }; | 851 | const V = @Vector(4, i32); |
| 851 | const result = value > @splat(4, @as(i32, 0)); | 852 | |
| 853 | const value = V{ 1, -1, 1, -1 }; | ||
| 854 | const result = value > @as(V, @splat(0)); | ||
| 852 | // result is { true, false, true, false }; | 855 | // result is { true, false, true, false }; |
| 853 | try comptime expect(@TypeOf(result) == @Vector(4, bool)); | 856 | try comptime expect(@TypeOf(result) == @Vector(4, bool)); |
| 854 | const is_all_true = @reduce(.And, result); | 857 | const is_all_true = @reduce(.And, result); |
| ... | @@ -1270,7 +1273,7 @@ test "array operands to shuffle are coerced to vectors" { | ... | @@ -1270,7 +1273,7 @@ test "array operands to shuffle are coerced to vectors" { |
| 1270 | const mask = [5]i32{ -1, 0, 1, 2, 3 }; | 1273 | const mask = [5]i32{ -1, 0, 1, 2, 3 }; |
| 1271 | 1274 | ||
| 1272 | var a = [5]u32{ 3, 5, 7, 9, 0 }; | 1275 | var a = [5]u32{ 3, 5, 7, 9, 0 }; |
| 1273 | var b = @shuffle(u32, a, @splat(5, @as(u24, 0)), mask); | 1276 | var b = @shuffle(u32, a, @as(@Vector(5, u24), @splat(0)), mask); |
| 1274 | try expectEqual([_]u32{ 0, 3, 5, 7, 9 }, b); | 1277 | try expectEqual([_]u32{ 0, 3, 5, 7, 9 }, b); |
| 1275 | } | 1278 | } |
| 1276 | 1279 |
test/cases/compile_errors/bad_splat_type.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | const c = 4; | ||
| 3 | var v = @splat(4, c); | ||
| 4 | _ = v; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage2 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // :3:23: error: expected integer, float, bool, or pointer for the vector element type; found 'comptime_int' | ||
test/cases/compile_errors/branch_in_comptime_only_scope_uses_condbr_inline.zig+2-2| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | pub export fn entry1() void { | 1 | pub export fn entry1() void { |
| 2 | var x: u32 = 3; | 2 | var x: u32 = 3; |
| 3 | _ = @shuffle(u32, [_]u32{0}, @splat(1, @as(u32, 0)), [_]i8{ | 3 | _ = @shuffle(u32, [_]u32{0}, @as(@Vector(1, u32), @splat(0)), [_]i8{ |
| 4 | if (x > 1) 1 else -1, | 4 | if (x > 1) 1 else -1, |
| 5 | }); | 5 | }); |
| 6 | } | 6 | } |
| 7 | 7 | ||
| 8 | pub export fn entry2() void { | 8 | pub export fn entry2() void { |
| 9 | var y: ?i8 = -1; | 9 | var y: ?i8 = -1; |
| 10 | _ = @shuffle(u32, [_]u32{0}, @splat(1, @as(u32, 0)), [_]i8{ | 10 | _ = @shuffle(u32, [_]u32{0}, @as(@Vector(1, u32), @splat(0)), [_]i8{ |
| 11 | y orelse 1, | 11 | y orelse 1, |
| 12 | }); | 12 | }); |
| 13 | } | 13 | } |
test/cases/safety/signed-unsigned vector cast.zig	+1-1| ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi | ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | pub fn main() !void { | 11 | pub fn main() !void { |
| 12 | var x = @splat(4, @as(i32, -2147483647)); | 12 | var x: @Vector(4, i32) = @splat(-2147483647); |
| 13 | var y: @Vector(4, u32) = @intCast(x); | 13 | var y: @Vector(4, u32) = @intCast(x); |
| 14 | _ = y; | 14 | _ = y; |
| 15 | return error.TestFailed; | 15 | return error.TestFailed; |
test/cases/safety/truncating vector cast.zig	+1-1| ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi | ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | pub fn main() !void { | 11 | pub fn main() !void { |
| 12 | var x = @splat(4, @as(u32, 0xdeadbeef)); | 12 | var x: @Vector(4, u32) = @splat(0xdeadbeef); |
| 13 | var y: @Vector(4, u16) = @intCast(x); | 13 | var y: @Vector(4, u16) = @intCast(x); |
| 14 | _ = y; | 14 | _ = y; |
| 15 | return error.TestFailed; | 15 | return error.TestFailed; |
test/cases/safety/unsigned-signed vector cast.zig	+1-1| ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi | ... | @@ -9,7 +9,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | pub fn main() !void { | 11 | pub fn main() !void { |
| 12 | var x = @splat(4, @as(u32, 0x80000000)); | 12 | var x: @Vector(4, u32) = @splat(0x80000000); |
| 13 | var y: @Vector(4, i32) = @intCast(x); | 13 | var y: @Vector(4, i32) = @intCast(x); |
| 14 | _ = y; | 14 | _ = y; |
| 15 | return error.TestFailed; | 15 | return error.TestFailed; |