| author | |
| committer | |
| log | 8dbd29cc4588cf118532a816d74b78f62999b636 |
| tree | 0fc19e694d1ad7366dd2b7153dd0d4647d3a9159 |
| parent | 0386730777da858908aaba4ef96fb5bd48faafc9 |
| parent | 6a63c8653ae9121f1cbcee49d32ec4f8deaf0b65 |
| signature |
Legalize: implement scalarization and safety check expansion92 files changed, 4020 insertions(+), 1681 deletions(-)
build.zig+2-2| ... | @@ -437,8 +437,8 @@ pub fn build(b: *std.Build) !void { | ... | @@ -437,8 +437,8 @@ pub fn build(b: *std.Build) !void { |
| 437 | .skip_non_native = skip_non_native, | 437 | .skip_non_native = skip_non_native, |
| 438 | .skip_libc = skip_libc, | 438 | .skip_libc = skip_libc, |
| 439 | .use_llvm = use_llvm, | 439 | .use_llvm = use_llvm, |
| 440 | // 2262585344 was observed on an x86_64-linux-gnu host. | 440 | // 2520100864 was observed on an x86_64-linux-gnu host. |
| 441 | .max_rss = 2488843878, | 441 | .max_rss = 2772110950, |
| 442 | })); | 442 | })); |
| 443 | 443 | ||
| 444 | test_modules_step.dependOn(tests.addModuleTests(b, .{ | 444 | test_modules_step.dependOn(tests.addModuleTests(b, .{ |
doc/langref/test_intCast_builtin.zig+1-1| ... | @@ -5,4 +5,4 @@ test "integer cast panic" { | ... | @@ -5,4 +5,4 @@ test "integer cast panic" { |
| 5 | _ = b; | 5 | _ = b; |
| 6 | } | 6 | } |
| 7 | 7 | ||
| 8 | // test_error=cast truncated bits | 8 | // test_error=integer does not fit in destination type |
lib/std/Target.zig+6-21| ... | @@ -1246,11 +1246,7 @@ pub const Cpu = struct { | ... | @@ -1246,11 +1246,7 @@ pub const Cpu = struct { |
| 1246 | 1246 | ||
| 1247 | /// Adds the specified feature set but not its dependencies. | 1247 | /// Adds the specified feature set but not its dependencies. |
| 1248 | pub fn addFeatureSet(set: *Set, other_set: Set) void { | 1248 | pub fn addFeatureSet(set: *Set, other_set: Set) void { |
| 1249 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { | 1249 | set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints); |
| 1250 | for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* |= other_set_int; | ||
| 1251 | } else { | ||
| 1252 | set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints); | ||
| 1253 | } | ||
| 1254 | } | 1250 | } |
| 1255 | 1251 | ||
| 1256 | /// Removes the specified feature but not its dependents. | 1252 | /// Removes the specified feature but not its dependents. |
| ... | @@ -1262,11 +1258,7 @@ pub const Cpu = struct { | ... | @@ -1262,11 +1258,7 @@ pub const Cpu = struct { |
| 1262 | 1258 | ||
| 1263 | /// Removes the specified feature but not its dependents. | 1259 | /// Removes the specified feature but not its dependents. |
| 1264 | pub fn removeFeatureSet(set: *Set, other_set: Set) void { | 1260 | pub fn removeFeatureSet(set: *Set, other_set: Set) void { |
| 1265 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { | 1261 | set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints); |
| 1266 | for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* &= ~other_set_int; | ||
| 1267 | } else { | ||
| 1268 | set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints); | ||
| 1269 | } | ||
| 1270 | } | 1262 | } |
| 1271 | 1263 | ||
| 1272 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { | 1264 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { |
| ... | @@ -1295,17 +1287,10 @@ pub const Cpu = struct { | ... | @@ -1295,17 +1287,10 @@ pub const Cpu = struct { |
| 1295 | } | 1287 | } |
| 1296 | 1288 | ||
| 1297 | pub fn isSuperSetOf(set: Set, other_set: Set) bool { | 1289 | pub fn isSuperSetOf(set: Set, other_set: Set) bool { |
| 1298 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { | 1290 | const V = @Vector(usize_count, usize); |
| 1299 | var result = true; | 1291 | const set_v: V = set.ints; |
| 1300 | for (&set.ints, other_set.ints) |*set_int, other_set_int| | 1292 | const other_v: V = other_set.ints; |
| 1301 | result = result and (set_int.* & other_set_int) == other_set_int; | 1293 | return @reduce(.And, (set_v & other_v) == other_v); |
| 1302 | return result; | ||
| 1303 | } else { | ||
| 1304 | const V = @Vector(usize_count, usize); | ||
| 1305 | const set_v: V = set.ints; | ||
| 1306 | const other_v: V = other_set.ints; | ||
| 1307 | return @reduce(.And, (set_v & other_v) == other_v); | ||
| 1308 | } | ||
| 1309 | } | 1294 | } |
| 1310 | }; | 1295 | }; |
| 1311 | 1296 |
lib/std/array_hash_map.zig+4-13| ... | @@ -889,19 +889,10 @@ pub fn ArrayHashMapUnmanaged( | ... | @@ -889,19 +889,10 @@ pub fn ArrayHashMapUnmanaged( |
| 889 | self.pointer_stability.lock(); | 889 | self.pointer_stability.lock(); |
| 890 | defer self.pointer_stability.unlock(); | 890 | defer self.pointer_stability.unlock(); |
| 891 | 891 | ||
| 892 | if (new_capacity <= linear_scan_max) { | ||
| 893 | try self.entries.ensureTotalCapacity(gpa, new_capacity); | ||
| 894 | return; | ||
| 895 | } | ||
| 896 | |||
| 897 | if (self.index_header) |header| { | ||
| 898 | if (new_capacity <= header.capacity()) { | ||
| 899 | try self.entries.ensureTotalCapacity(gpa, new_capacity); | ||
| 900 | return; | ||
| 901 | } | ||
| 902 | } | ||
| 903 | |||
| 904 | try self.entries.ensureTotalCapacity(gpa, new_capacity); | 892 | try self.entries.ensureTotalCapacity(gpa, new_capacity); |
| 893 | if (new_capacity <= linear_scan_max) return; | ||
| 894 | if (self.index_header) |header| if (new_capacity <= header.capacity()) return; | ||
| 895 | |||
| 905 | const new_bit_index = try IndexHeader.findBitIndex(new_capacity); | 896 | const new_bit_index = try IndexHeader.findBitIndex(new_capacity); |
| 906 | const new_header = try IndexHeader.alloc(gpa, new_bit_index); | 897 | const new_header = try IndexHeader.alloc(gpa, new_bit_index); |
| 907 | 898 | ||
| ... | @@ -2116,7 +2107,7 @@ const IndexHeader = struct { | ... | @@ -2116,7 +2107,7 @@ const IndexHeader = struct { |
| 2116 | 2107 | ||
| 2117 | fn findBitIndex(desired_capacity: usize) Allocator.Error!u8 { | 2108 | fn findBitIndex(desired_capacity: usize) Allocator.Error!u8 { |
| 2118 | if (desired_capacity > max_capacity) return error.OutOfMemory; | 2109 | if (desired_capacity > max_capacity) return error.OutOfMemory; |
| 2119 | var new_bit_index = @as(u8, @intCast(std.math.log2_int_ceil(usize, desired_capacity))); | 2110 | var new_bit_index: u8 = @intCast(std.math.log2_int_ceil(usize, desired_capacity)); |
| 2120 | if (desired_capacity > index_capacities[new_bit_index]) new_bit_index += 1; | 2111 | if (desired_capacity > index_capacities[new_bit_index]) new_bit_index += 1; |
| 2121 | if (new_bit_index < min_bit_index) new_bit_index = min_bit_index; | 2112 | if (new_bit_index < min_bit_index) new_bit_index = min_bit_index; |
| 2122 | assert(desired_capacity <= index_capacities[new_bit_index]); | 2113 | assert(desired_capacity <= index_capacities[new_bit_index]); |
lib/std/crypto/chacha20.zig+3-6| ... | @@ -499,15 +499,12 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { | ... | @@ -499,15 +499,12 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 499 | fn ChaChaImpl(comptime rounds_nb: usize) type { | 499 | fn ChaChaImpl(comptime rounds_nb: usize) type { |
| 500 | switch (builtin.cpu.arch) { | 500 | switch (builtin.cpu.arch) { |
| 501 | .x86_64 => { | 501 | .x86_64 => { |
| 502 | const has_avx2 = std.Target.x86.featureSetHas(builtin.cpu.features, .avx2); | 502 | if (builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f)) return ChaChaVecImpl(rounds_nb, 4); |
| 503 | const has_avx512f = std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f); | 503 | if (std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return ChaChaVecImpl(rounds_nb, 2); |
| 504 | if (builtin.zig_backend != .stage2_x86_64 and has_avx512f) return ChaChaVecImpl(rounds_nb, 4); | ||
| 505 | if (has_avx2) return ChaChaVecImpl(rounds_nb, 2); | ||
| 506 | return ChaChaVecImpl(rounds_nb, 1); | 504 | return ChaChaVecImpl(rounds_nb, 1); |
| 507 | }, | 505 | }, |
| 508 | .aarch64 => { | 506 | .aarch64 => { |
| 509 | const has_neon = std.Target.aarch64.featureSetHas(builtin.cpu.features, .neon); | 507 | if (builtin.zig_backend != .stage2_aarch64 and std.Target.aarch64.featureSetHas(builtin.cpu.features, .neon)) return ChaChaVecImpl(rounds_nb, 4); |
| 510 | if (has_neon) return ChaChaVecImpl(rounds_nb, 4); | ||
| 511 | return ChaChaNonVecImpl(rounds_nb); | 508 | return ChaChaNonVecImpl(rounds_nb); |
| 512 | }, | 509 | }, |
| 513 | else => return ChaChaNonVecImpl(rounds_nb), | 510 | else => return ChaChaNonVecImpl(rounds_nb), |
lib/std/debug.zig+2-8| ... | @@ -78,13 +78,9 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { | ... | @@ -78,13 +78,9 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 78 | @branchHint(.cold); | 78 | @branchHint(.cold); |
| 79 | call("invalid error code", @returnAddress()); | 79 | call("invalid error code", @returnAddress()); |
| 80 | } | 80 | } |
| 81 | pub fn castTruncatedData() noreturn { | 81 | pub fn integerOutOfBounds() noreturn { |
| 82 | @branchHint(.cold); | 82 | @branchHint(.cold); |
| 83 | call("integer cast truncated bits", @returnAddress()); | 83 | call("integer does not fit in destination type", @returnAddress()); |
| 84 | } | ||
| 85 | pub fn negativeToUnsigned() noreturn { | ||
| 86 | @branchHint(.cold); | ||
| 87 | call("attempt to cast negative value to unsigned integer", @returnAddress()); | ||
| 88 | } | 84 | } |
| 89 | pub fn integerOverflow() noreturn { | 85 | pub fn integerOverflow() noreturn { |
| 90 | @branchHint(.cold); | 86 | @branchHint(.cold); |
| ... | @@ -126,8 +122,6 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { | ... | @@ -126,8 +122,6 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 126 | @branchHint(.cold); | 122 | @branchHint(.cold); |
| 127 | call("for loop over objects with non-equal lengths", @returnAddress()); | 123 | call("for loop over objects with non-equal lengths", @returnAddress()); |
| 128 | } | 124 | } |
| 129 | /// Delete after next zig1.wasm update | ||
| 130 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 131 | pub fn copyLenMismatch() noreturn { | 125 | pub fn copyLenMismatch() noreturn { |
| 132 | @branchHint(.cold); | 126 | @branchHint(.cold); |
| 133 | call("source and destination arguments have non-equal lengths", @returnAddress()); | 127 | call("source and destination arguments have non-equal lengths", @returnAddress()); |
lib/std/debug/no_panic.zig+1-9| ... | @@ -65,12 +65,7 @@ pub fn invalidErrorCode() noreturn { | ... | @@ -65,12 +65,7 @@ pub fn invalidErrorCode() noreturn { |
| 65 | @trap(); | 65 | @trap(); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | pub fn castTruncatedData() noreturn { | 68 | pub fn integerOutOfBounds() noreturn { |
| 69 | @branchHint(.cold); | ||
| 70 | @trap(); | ||
| 71 | } | ||
| 72 | |||
| 73 | pub fn negativeToUnsigned() noreturn { | ||
| 74 | @branchHint(.cold); | 69 | @branchHint(.cold); |
| 75 | @trap(); | 70 | @trap(); |
| 76 | } | 71 | } |
| ... | @@ -125,9 +120,6 @@ pub fn forLenMismatch() noreturn { | ... | @@ -125,9 +120,6 @@ pub fn forLenMismatch() noreturn { |
| 125 | @trap(); | 120 | @trap(); |
| 126 | } | 121 | } |
| 127 | 122 | ||
| 128 | /// Delete after next zig1.wasm update | ||
| 129 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 130 | |||
| 131 | pub fn copyLenMismatch() noreturn { | 123 | pub fn copyLenMismatch() noreturn { |
| 132 | @branchHint(.cold); | 124 | @branchHint(.cold); |
| 133 | @trap(); | 125 | @trap(); |
lib/std/debug/simple_panic.zig+2-9| ... | @@ -72,12 +72,8 @@ pub fn invalidErrorCode() noreturn { | ... | @@ -72,12 +72,8 @@ pub fn invalidErrorCode() noreturn { |
| 72 | call("invalid error code", null); | 72 | call("invalid error code", null); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | pub fn castTruncatedData() noreturn { | 75 | pub fn integerOutOfBounds() noreturn { |
| 76 | call("integer cast truncated bits", null); | 76 | call("integer does not fit in destination type", null); |
| 77 | } | ||
| 78 | |||
| 79 | pub fn negativeToUnsigned() noreturn { | ||
| 80 | call("attempt to cast negative value to unsigned integer", null); | ||
| 81 | } | 77 | } |
| 82 | 78 | ||
| 83 | pub fn integerOverflow() noreturn { | 79 | pub fn integerOverflow() noreturn { |
| ... | @@ -120,9 +116,6 @@ pub fn forLenMismatch() noreturn { | ... | @@ -120,9 +116,6 @@ pub fn forLenMismatch() noreturn { |
| 120 | call("for loop over objects with non-equal lengths", null); | 116 | call("for loop over objects with non-equal lengths", null); |
| 121 | } | 117 | } |
| 122 | 118 | ||
| 123 | /// Delete after next zig1.wasm update | ||
| 124 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 125 | |||
| 126 | pub fn copyLenMismatch() noreturn { | 119 | pub fn copyLenMismatch() noreturn { |
| 127 | call("source and destination have non-equal lengths", null); | 120 | call("source and destination have non-equal lengths", null); |
| 128 | } | 121 | } |
lib/std/hash/xxhash.zig-3| ... | @@ -780,7 +780,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64) | ... | @@ -780,7 +780,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64) |
| 780 | } | 780 | } |
| 781 | 781 | ||
| 782 | test "xxhash3" { | 782 | test "xxhash3" { |
| 783 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 784 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 | 783 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 |
| 785 | 784 | ||
| 786 | const H = XxHash3; | 785 | const H = XxHash3; |
| ... | @@ -814,7 +813,6 @@ test "xxhash3" { | ... | @@ -814,7 +813,6 @@ test "xxhash3" { |
| 814 | } | 813 | } |
| 815 | 814 | ||
| 816 | test "xxhash3 smhasher" { | 815 | test "xxhash3 smhasher" { |
| 817 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 818 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 | 816 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 |
| 819 | 817 | ||
| 820 | const Test = struct { | 818 | const Test = struct { |
| ... | @@ -828,7 +826,6 @@ test "xxhash3 smhasher" { | ... | @@ -828,7 +826,6 @@ test "xxhash3 smhasher" { |
| 828 | } | 826 | } |
| 829 | 827 | ||
| 830 | test "xxhash3 iterative api" { | 828 | test "xxhash3 iterative api" { |
| 831 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 832 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 | 829 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807 |
| 833 | 830 | ||
| 834 | const Test = struct { | 831 | const Test = struct { |
lib/std/simd.zig-8| ... | @@ -231,8 +231,6 @@ pub fn extract( | ... | @@ -231,8 +231,6 @@ pub fn extract( |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | test "vector patterns" { | 233 | test "vector patterns" { |
| 234 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 235 | |||
| 236 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; | 234 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; |
| 237 | const other_base = @Vector(4, u32){ 55, 66, 77, 88 }; | 235 | const other_base = @Vector(4, u32){ 55, 66, 77, 88 }; |
| 238 | 236 | ||
| ... | @@ -302,8 +300,6 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) { | ... | @@ -302,8 +300,6 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) { |
| 302 | } | 300 | } |
| 303 | 301 | ||
| 304 | test "vector shifting" { | 302 | test "vector shifting" { |
| 305 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 306 | |||
| 307 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; | 303 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; |
| 308 | 304 | ||
| 309 | try std.testing.expectEqual([4]u32{ 30, 40, 999, 999 }, shiftElementsLeft(base, 2, 999)); | 305 | try std.testing.expectEqual([4]u32{ 30, 40, 999, 999 }, shiftElementsLeft(base, 2, 999)); |
| ... | @@ -368,9 +364,6 @@ pub fn countElementsWithValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) | ... | @@ -368,9 +364,6 @@ pub fn countElementsWithValue(vec: anytype, value: std.meta.Child(@TypeOf(vec))) |
| 368 | } | 364 | } |
| 369 | 365 | ||
| 370 | test "vector searching" { | 366 | test "vector searching" { |
| 371 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 372 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .ssse3)) return error.SkipZigTest; | ||
| 373 | |||
| 374 | const base = @Vector(8, u32){ 6, 4, 7, 4, 4, 2, 3, 7 }; | 367 | const base = @Vector(8, u32){ 6, 4, 7, 4, 4, 2, 3, 7 }; |
| 375 | 368 | ||
| 376 | try std.testing.expectEqual(@as(?u3, 1), firstIndexOfValue(base, 4)); | 369 | try std.testing.expectEqual(@as(?u3, 1), firstIndexOfValue(base, 4)); |
| ... | @@ -462,7 +455,6 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a | ... | @@ -462,7 +455,6 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a |
| 462 | } | 455 | } |
| 463 | 456 | ||
| 464 | test "vector prefix scan" { | 457 | test "vector prefix scan" { |
| 465 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 466 | if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060 | 458 | if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060 |
| 467 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893 | 459 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893 |
| 468 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 460 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
lib/std/zig/AstGen.zig+21-1| ... | @@ -11194,6 +11194,7 @@ fn rvalueInner( | ... | @@ -11194,6 +11194,7 @@ fn rvalueInner( |
| 11194 | const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32; | 11194 | const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32; |
| 11195 | const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32; | 11195 | const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32; |
| 11196 | const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32; | 11196 | const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32; |
| 11197 | const as_u1 = @as(u64, @intFromEnum(Zir.Inst.Ref.u1_type)) << 32; | ||
| 11197 | const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32; | 11198 | const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32; |
| 11198 | switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) { | 11199 | switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) { |
| 11199 | as_ty | @intFromEnum(Zir.Inst.Ref.u1_type), | 11200 | as_ty | @intFromEnum(Zir.Inst.Ref.u1_type), |
| ... | @@ -11237,10 +11238,11 @@ fn rvalueInner( | ... | @@ -11237,10 +11238,11 @@ fn rvalueInner( |
| 11237 | as_ty | @intFromEnum(Zir.Inst.Ref.null_type), | 11238 | as_ty | @intFromEnum(Zir.Inst.Ref.null_type), |
| 11238 | as_ty | @intFromEnum(Zir.Inst.Ref.undefined_type), | 11239 | as_ty | @intFromEnum(Zir.Inst.Ref.undefined_type), |
| 11239 | as_ty | @intFromEnum(Zir.Inst.Ref.enum_literal_type), | 11240 | as_ty | @intFromEnum(Zir.Inst.Ref.enum_literal_type), |
| 11241 | as_ty | @intFromEnum(Zir.Inst.Ref.ptr_usize_type), | ||
| 11242 | as_ty | @intFromEnum(Zir.Inst.Ref.ptr_const_comptime_int_type), | ||
| 11240 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_u8_type), | 11243 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_u8_type), |
| 11241 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_type), | 11244 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_type), |
| 11242 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_sentinel_0_type), | 11245 | as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_sentinel_0_type), |
| 11243 | as_ty | @intFromEnum(Zir.Inst.Ref.single_const_pointer_to_comptime_int_type), | ||
| 11244 | as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_type), | 11246 | as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_type), |
| 11245 | as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type), | 11247 | as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type), |
| 11246 | as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type), | 11248 | as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type), |
| ... | @@ -11249,27 +11251,45 @@ fn rvalueInner( | ... | @@ -11249,27 +11251,45 @@ fn rvalueInner( |
| 11249 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero), | 11251 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero), |
| 11250 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one), | 11252 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one), |
| 11251 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one), | 11253 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one), |
| 11254 | as_usize | @intFromEnum(Zir.Inst.Ref.undef_usize), | ||
| 11252 | as_usize | @intFromEnum(Zir.Inst.Ref.zero_usize), | 11255 | as_usize | @intFromEnum(Zir.Inst.Ref.zero_usize), |
| 11253 | as_usize | @intFromEnum(Zir.Inst.Ref.one_usize), | 11256 | as_usize | @intFromEnum(Zir.Inst.Ref.one_usize), |
| 11257 | as_u1 | @intFromEnum(Zir.Inst.Ref.undef_u1), | ||
| 11258 | as_u1 | @intFromEnum(Zir.Inst.Ref.zero_u1), | ||
| 11259 | as_u1 | @intFromEnum(Zir.Inst.Ref.one_u1), | ||
| 11254 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero_u8), | 11260 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero_u8), |
| 11255 | as_u8 | @intFromEnum(Zir.Inst.Ref.one_u8), | 11261 | as_u8 | @intFromEnum(Zir.Inst.Ref.one_u8), |
| 11256 | as_u8 | @intFromEnum(Zir.Inst.Ref.four_u8), | 11262 | as_u8 | @intFromEnum(Zir.Inst.Ref.four_u8), |
| 11263 | as_bool | @intFromEnum(Zir.Inst.Ref.undef_bool), | ||
| 11257 | as_bool | @intFromEnum(Zir.Inst.Ref.bool_true), | 11264 | as_bool | @intFromEnum(Zir.Inst.Ref.bool_true), |
| 11258 | as_bool | @intFromEnum(Zir.Inst.Ref.bool_false), | 11265 | as_bool | @intFromEnum(Zir.Inst.Ref.bool_false), |
| 11259 | as_void | @intFromEnum(Zir.Inst.Ref.void_value), | 11266 | as_void | @intFromEnum(Zir.Inst.Ref.void_value), |
| 11260 | => return result, // type of result is already correct | 11267 | => return result, // type of result is already correct |
| 11261 | 11268 | ||
| 11269 | as_bool | @intFromEnum(Zir.Inst.Ref.undef) => return .undef_bool, | ||
| 11270 | as_usize | @intFromEnum(Zir.Inst.Ref.undef) => return .undef_usize, | ||
| 11271 | as_usize | @intFromEnum(Zir.Inst.Ref.undef_u1) => return .undef_usize, | ||
| 11272 | as_u1 | @intFromEnum(Zir.Inst.Ref.undef) => return .undef_u1, | ||
| 11273 | |||
| 11262 | as_usize | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_usize, | 11274 | as_usize | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_usize, |
| 11275 | as_u1 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u1, | ||
| 11263 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u8, | 11276 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u8, |
| 11264 | as_usize | @intFromEnum(Zir.Inst.Ref.one) => return .one_usize, | 11277 | as_usize | @intFromEnum(Zir.Inst.Ref.one) => return .one_usize, |
| 11278 | as_u1 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u1, | ||
| 11265 | as_u8 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u8, | 11279 | as_u8 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u8, |
| 11266 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero, | 11280 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero, |
| 11281 | as_u1 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u1, | ||
| 11267 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u8, | 11282 | as_u8 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u8, |
| 11268 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one, | 11283 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one, |
| 11284 | as_u1 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u1, | ||
| 11269 | as_u8 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u8, | 11285 | as_u8 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u8, |
| 11286 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u1) => return .zero, | ||
| 11270 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero, | 11287 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero, |
| 11288 | as_usize | @intFromEnum(Zir.Inst.Ref.zero_u1) => return .zero_usize, | ||
| 11271 | as_usize | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero_usize, | 11289 | as_usize | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero_usize, |
| 11290 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u1) => return .one, | ||
| 11272 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one, | 11291 | as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one, |
| 11292 | as_usize | @intFromEnum(Zir.Inst.Ref.one_u1) => return .one_usize, | ||
| 11273 | as_usize | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one_usize, | 11293 | as_usize | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one_usize, |
| 11274 | 11294 | ||
| 11275 | // Need an explicit type coercion instruction. | 11295 | // Need an explicit type coercion instruction. |
lib/std/zig/Zir.zig+8-2| ... | @@ -2142,7 +2142,7 @@ pub const Inst = struct { | ... | @@ -2142,7 +2142,7 @@ pub const Inst = struct { |
| 2142 | ref_start_index = static_len, | 2142 | ref_start_index = static_len, |
| 2143 | _, | 2143 | _, |
| 2144 | 2144 | ||
| 2145 | pub const static_len = 118; | 2145 | pub const static_len = 124; |
| 2146 | 2146 | ||
| 2147 | pub fn toRef(i: Index) Inst.Ref { | 2147 | pub fn toRef(i: Index) Inst.Ref { |
| 2148 | return @enumFromInt(@intFromEnum(Index.ref_start_index) + @intFromEnum(i)); | 2148 | return @enumFromInt(@intFromEnum(Index.ref_start_index) + @intFromEnum(i)); |
| ... | @@ -2220,10 +2220,11 @@ pub const Inst = struct { | ... | @@ -2220,10 +2220,11 @@ pub const Inst = struct { |
| 2220 | null_type, | 2220 | null_type, |
| 2221 | undefined_type, | 2221 | undefined_type, |
| 2222 | enum_literal_type, | 2222 | enum_literal_type, |
| 2223 | ptr_usize_type, | ||
| 2224 | ptr_const_comptime_int_type, | ||
| 2223 | manyptr_u8_type, | 2225 | manyptr_u8_type, |
| 2224 | manyptr_const_u8_type, | 2226 | manyptr_const_u8_type, |
| 2225 | manyptr_const_u8_sentinel_0_type, | 2227 | manyptr_const_u8_sentinel_0_type, |
| 2226 | single_const_pointer_to_comptime_int_type, | ||
| 2227 | slice_const_u8_type, | 2228 | slice_const_u8_type, |
| 2228 | slice_const_u8_sentinel_0_type, | 2229 | slice_const_u8_sentinel_0_type, |
| 2229 | vector_8_i8_type, | 2230 | vector_8_i8_type, |
| ... | @@ -2279,11 +2280,16 @@ pub const Inst = struct { | ... | @@ -2279,11 +2280,16 @@ pub const Inst = struct { |
| 2279 | generic_poison_type, | 2280 | generic_poison_type, |
| 2280 | empty_tuple_type, | 2281 | empty_tuple_type, |
| 2281 | undef, | 2282 | undef, |
| 2283 | undef_bool, | ||
| 2284 | undef_usize, | ||
| 2285 | undef_u1, | ||
| 2282 | zero, | 2286 | zero, |
| 2283 | zero_usize, | 2287 | zero_usize, |
| 2288 | zero_u1, | ||
| 2284 | zero_u8, | 2289 | zero_u8, |
| 2285 | one, | 2290 | one, |
| 2286 | one_usize, | 2291 | one_usize, |
| 2292 | one_u1, | ||
| 2287 | one_u8, | 2293 | one_u8, |
| 2288 | four_u8, | 2294 | four_u8, |
| 2289 | negative_one, | 2295 | negative_one, |
src/Air.zig+144-37| ... | @@ -50,8 +50,6 @@ pub const Inst = struct { | ... | @@ -50,8 +50,6 @@ pub const Inst = struct { |
| 50 | /// is the same as both operands. | 50 | /// is the same as both operands. |
| 51 | /// The panic handler function must be populated before lowering AIR | 51 | /// The panic handler function must be populated before lowering AIR |
| 52 | /// that contains this instruction. | 52 | /// that contains this instruction. |
| 53 | /// This instruction will only be emitted if the backend has the | ||
| 54 | /// feature `safety_checked_instructions`. | ||
| 55 | /// Uses the `bin_op` field. | 53 | /// Uses the `bin_op` field. |
| 56 | add_safe, | 54 | add_safe, |
| 57 | /// Float addition. The instruction is allowed to have equal or more | 55 | /// Float addition. The instruction is allowed to have equal or more |
| ... | @@ -79,8 +77,6 @@ pub const Inst = struct { | ... | @@ -79,8 +77,6 @@ pub const Inst = struct { |
| 79 | /// is the same as both operands. | 77 | /// is the same as both operands. |
| 80 | /// The panic handler function must be populated before lowering AIR | 78 | /// The panic handler function must be populated before lowering AIR |
| 81 | /// that contains this instruction. | 79 | /// that contains this instruction. |
| 82 | /// This instruction will only be emitted if the backend has the | ||
| 83 | /// feature `safety_checked_instructions`. | ||
| 84 | /// Uses the `bin_op` field. | 80 | /// Uses the `bin_op` field. |
| 85 | sub_safe, | 81 | sub_safe, |
| 86 | /// Float subtraction. The instruction is allowed to have equal or more | 82 | /// Float subtraction. The instruction is allowed to have equal or more |
| ... | @@ -108,8 +104,6 @@ pub const Inst = struct { | ... | @@ -108,8 +104,6 @@ pub const Inst = struct { |
| 108 | /// is the same as both operands. | 104 | /// is the same as both operands. |
| 109 | /// The panic handler function must be populated before lowering AIR | 105 | /// The panic handler function must be populated before lowering AIR |
| 110 | /// that contains this instruction. | 106 | /// that contains this instruction. |
| 111 | /// This instruction will only be emitted if the backend has the | ||
| 112 | /// feature `safety_checked_instructions`. | ||
| 113 | /// Uses the `bin_op` field. | 107 | /// Uses the `bin_op` field. |
| 114 | mul_safe, | 108 | mul_safe, |
| 115 | /// Float multiplication. The instruction is allowed to have equal or more | 109 | /// Float multiplication. The instruction is allowed to have equal or more |
| ... | @@ -705,9 +699,21 @@ pub const Inst = struct { | ... | @@ -705,9 +699,21 @@ pub const Inst = struct { |
| 705 | /// equal to the scalar value. | 699 | /// equal to the scalar value. |
| 706 | /// Uses the `ty_op` field. | 700 | /// Uses the `ty_op` field. |
| 707 | splat, | 701 | splat, |
| 708 | /// Constructs a vector by selecting elements from `a` and `b` based on `mask`. | 702 | /// Constructs a vector by selecting elements from a single vector based on a mask. Each |
| 709 | /// Uses the `ty_pl` field with payload `Shuffle`. | 703 | /// mask element is either an index into the vector, or a comptime-known value, or "undef". |
| 710 | shuffle, | 704 | /// Uses the `ty_pl` field, where the payload index points to: |
| 705 | /// 1. mask_elem: ShuffleOneMask // for each `mask_len`, which comes from `ty_pl.ty` | ||
| 706 | /// 2. operand: Ref // guaranteed not to be an interned value | ||
| 707 | /// See `unwrapShuffleOne`. | ||
| 708 | shuffle_one, | ||
| 709 | /// Constructs a vector by selecting elements from two vectors based on a mask. Each mask | ||
| 710 | /// element is either an index into one of the vectors, or "undef". | ||
| 711 | /// Uses the `ty_pl` field, where the payload index points to: | ||
| 712 | /// 1. mask_elem: ShuffleOneMask // for each `mask_len`, which comes from `ty_pl.ty` | ||
| 713 | /// 2. operand_a: Ref // guaranteed not to be an interned value | ||
| 714 | /// 3. operand_b: Ref // guaranteed not to be an interned value | ||
| 715 | /// See `unwrapShuffleTwo`. | ||
| 716 | shuffle_two, | ||
| 711 | /// Constructs a vector element-wise from `a` or `b` based on `pred`. | 717 | /// Constructs a vector element-wise from `a` or `b` based on `pred`. |
| 712 | /// Uses the `pl_op` field with `pred` as operand, and payload `Bin`. | 718 | /// Uses the `pl_op` field with `pred` as operand, and payload `Bin`. |
| 713 | select, | 719 | select, |
| ... | @@ -1011,10 +1017,11 @@ pub const Inst = struct { | ... | @@ -1011,10 +1017,11 @@ pub const Inst = struct { |
| 1011 | null_type = @intFromEnum(InternPool.Index.null_type), | 1017 | null_type = @intFromEnum(InternPool.Index.null_type), |
| 1012 | undefined_type = @intFromEnum(InternPool.Index.undefined_type), | 1018 | undefined_type = @intFromEnum(InternPool.Index.undefined_type), |
| 1013 | enum_literal_type = @intFromEnum(InternPool.Index.enum_literal_type), | 1019 | enum_literal_type = @intFromEnum(InternPool.Index.enum_literal_type), |
| 1020 | ptr_usize_type = @intFromEnum(InternPool.Index.ptr_usize_type), | ||
| 1021 | ptr_const_comptime_int_type = @intFromEnum(InternPool.Index.ptr_const_comptime_int_type), | ||
| 1014 | manyptr_u8_type = @intFromEnum(InternPool.Index.manyptr_u8_type), | 1022 | manyptr_u8_type = @intFromEnum(InternPool.Index.manyptr_u8_type), |
| 1015 | manyptr_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_u8_type), | 1023 | manyptr_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_u8_type), |
| 1016 | manyptr_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.manyptr_const_u8_sentinel_0_type), | 1024 | manyptr_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.manyptr_const_u8_sentinel_0_type), |
| 1017 | single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type), | ||
| 1018 | slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type), | 1025 | slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type), |
| 1019 | slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type), | 1026 | slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type), |
| 1020 | vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type), | 1027 | vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type), |
| ... | @@ -1070,11 +1077,16 @@ pub const Inst = struct { | ... | @@ -1070,11 +1077,16 @@ pub const Inst = struct { |
| 1070 | generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type), | 1077 | generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type), |
| 1071 | empty_tuple_type = @intFromEnum(InternPool.Index.empty_tuple_type), | 1078 | empty_tuple_type = @intFromEnum(InternPool.Index.empty_tuple_type), |
| 1072 | undef = @intFromEnum(InternPool.Index.undef), | 1079 | undef = @intFromEnum(InternPool.Index.undef), |
| 1080 | undef_bool = @intFromEnum(InternPool.Index.undef_bool), | ||
| 1081 | undef_usize = @intFromEnum(InternPool.Index.undef_usize), | ||
| 1082 | undef_u1 = @intFromEnum(InternPool.Index.undef_u1), | ||
| 1073 | zero = @intFromEnum(InternPool.Index.zero), | 1083 | zero = @intFromEnum(InternPool.Index.zero), |
| 1074 | zero_usize = @intFromEnum(InternPool.Index.zero_usize), | 1084 | zero_usize = @intFromEnum(InternPool.Index.zero_usize), |
| 1085 | zero_u1 = @intFromEnum(InternPool.Index.zero_u1), | ||
| 1075 | zero_u8 = @intFromEnum(InternPool.Index.zero_u8), | 1086 | zero_u8 = @intFromEnum(InternPool.Index.zero_u8), |
| 1076 | one = @intFromEnum(InternPool.Index.one), | 1087 | one = @intFromEnum(InternPool.Index.one), |
| 1077 | one_usize = @intFromEnum(InternPool.Index.one_usize), | 1088 | one_usize = @intFromEnum(InternPool.Index.one_usize), |
| 1089 | one_u1 = @intFromEnum(InternPool.Index.one_u1), | ||
| 1078 | one_u8 = @intFromEnum(InternPool.Index.one_u8), | 1090 | one_u8 = @intFromEnum(InternPool.Index.one_u8), |
| 1079 | four_u8 = @intFromEnum(InternPool.Index.four_u8), | 1091 | four_u8 = @intFromEnum(InternPool.Index.four_u8), |
| 1080 | negative_one = @intFromEnum(InternPool.Index.negative_one), | 1092 | negative_one = @intFromEnum(InternPool.Index.negative_one), |
| ... | @@ -1121,7 +1133,7 @@ pub const Inst = struct { | ... | @@ -1121,7 +1133,7 @@ pub const Inst = struct { |
| 1121 | } | 1133 | } |
| 1122 | 1134 | ||
| 1123 | pub fn toType(ref: Ref) Type { | 1135 | pub fn toType(ref: Ref) Type { |
| 1124 | return Type.fromInterned(ref.toInterned().?); | 1136 | return .fromInterned(ref.toInterned().?); |
| 1125 | } | 1137 | } |
| 1126 | }; | 1138 | }; |
| 1127 | 1139 | ||
| ... | @@ -1241,10 +1253,10 @@ pub const CondBr = struct { | ... | @@ -1241,10 +1253,10 @@ pub const CondBr = struct { |
| 1241 | else_body_len: u32, | 1253 | else_body_len: u32, |
| 1242 | branch_hints: BranchHints, | 1254 | branch_hints: BranchHints, |
| 1243 | pub const BranchHints = packed struct(u32) { | 1255 | pub const BranchHints = packed struct(u32) { |
| 1244 | true: std.builtin.BranchHint, | 1256 | true: std.builtin.BranchHint = .none, |
| 1245 | false: std.builtin.BranchHint, | 1257 | false: std.builtin.BranchHint = .none, |
| 1246 | then_cov: CoveragePoint, | 1258 | then_cov: CoveragePoint = .none, |
| 1247 | else_cov: CoveragePoint, | 1259 | else_cov: CoveragePoint = .none, |
| 1248 | _: u24 = 0, | 1260 | _: u24 = 0, |
| 1249 | }; | 1261 | }; |
| 1250 | }; | 1262 | }; |
| ... | @@ -1299,13 +1311,6 @@ pub const FieldParentPtr = struct { | ... | @@ -1299,13 +1311,6 @@ pub const FieldParentPtr = struct { |
| 1299 | field_index: u32, | 1311 | field_index: u32, |
| 1300 | }; | 1312 | }; |
| 1301 | 1313 | ||
| 1302 | pub const Shuffle = struct { | ||
| 1303 | a: Inst.Ref, | ||
| 1304 | b: Inst.Ref, | ||
| 1305 | mask: InternPool.Index, | ||
| 1306 | mask_len: u32, | ||
| 1307 | }; | ||
| 1308 | |||
| 1309 | pub const VectorCmp = struct { | 1314 | pub const VectorCmp = struct { |
| 1310 | lhs: Inst.Ref, | 1315 | lhs: Inst.Ref, |
| 1311 | rhs: Inst.Ref, | 1316 | rhs: Inst.Ref, |
| ... | @@ -1320,6 +1325,64 @@ pub const VectorCmp = struct { | ... | @@ -1320,6 +1325,64 @@ pub const VectorCmp = struct { |
| 1320 | } | 1325 | } |
| 1321 | }; | 1326 | }; |
| 1322 | 1327 | ||
| 1328 | /// Used by `Inst.Tag.shuffle_one`. Represents a mask element which either indexes into a | ||
| 1329 | /// runtime-known vector, or is a comptime-known value. | ||
| 1330 | pub const ShuffleOneMask = packed struct(u32) { | ||
| 1331 | index: u31, | ||
| 1332 | kind: enum(u1) { elem, value }, | ||
| 1333 | pub fn elem(idx: u32) ShuffleOneMask { | ||
| 1334 | return .{ .index = @intCast(idx), .kind = .elem }; | ||
| 1335 | } | ||
| 1336 | pub fn value(val: Value) ShuffleOneMask { | ||
| 1337 | return .{ .index = @intCast(@intFromEnum(val.toIntern())), .kind = .value }; | ||
| 1338 | } | ||
| 1339 | pub const Unwrapped = union(enum) { | ||
| 1340 | /// The resulting element is this index into the runtime vector. | ||
| 1341 | elem: u32, | ||
| 1342 | /// The resulting element is this comptime-known value. | ||
| 1343 | /// It is correctly typed. It might be `undefined`. | ||
| 1344 | value: InternPool.Index, | ||
| 1345 | }; | ||
| 1346 | pub fn unwrap(raw: ShuffleOneMask) Unwrapped { | ||
| 1347 | return switch (raw.kind) { | ||
| 1348 | .elem => .{ .elem = raw.index }, | ||
| 1349 | .value => .{ .value = @enumFromInt(raw.index) }, | ||
| 1350 | }; | ||
| 1351 | } | ||
| 1352 | }; | ||
| 1353 | |||
| 1354 | /// Used by `Inst.Tag.shuffle_two`. Represents a mask element which either indexes into one | ||
| 1355 | /// of two runtime-known vectors, or is undefined. | ||
| 1356 | pub const ShuffleTwoMask = enum(u32) { | ||
| 1357 | undef = std.math.maxInt(u32), | ||
| 1358 | _, | ||
| 1359 | pub fn aElem(idx: u32) ShuffleTwoMask { | ||
| 1360 | return @enumFromInt(idx << 1); | ||
| 1361 | } | ||
| 1362 | pub fn bElem(idx: u32) ShuffleTwoMask { | ||
| 1363 | return @enumFromInt(idx << 1 | 1); | ||
| 1364 | } | ||
| 1365 | pub const Unwrapped = union(enum) { | ||
| 1366 | /// The resulting element is this index into the first runtime vector. | ||
| 1367 | a_elem: u32, | ||
| 1368 | /// The resulting element is this index into the second runtime vector. | ||
| 1369 | b_elem: u32, | ||
| 1370 | /// The resulting element is `undefined`. | ||
| 1371 | undef, | ||
| 1372 | }; | ||
| 1373 | pub fn unwrap(raw: ShuffleTwoMask) Unwrapped { | ||
| 1374 | switch (raw) { | ||
| 1375 | .undef => return .undef, | ||
| 1376 | _ => {}, | ||
| 1377 | } | ||
| 1378 | const x = @intFromEnum(raw); | ||
| 1379 | return switch (@as(u1, @truncate(x))) { | ||
| 1380 | 0 => .{ .a_elem = x >> 1 }, | ||
| 1381 | 1 => .{ .b_elem = x >> 1 }, | ||
| 1382 | }; | ||
| 1383 | } | ||
| 1384 | }; | ||
| 1385 | |||
| 1323 | /// Trailing: | 1386 | /// Trailing: |
| 1324 | /// 0. `Inst.Ref` for every outputs_len | 1387 | /// 0. `Inst.Ref` for every outputs_len |
| 1325 | /// 1. `Inst.Ref` for every inputs_len | 1388 | /// 1. `Inst.Ref` for every inputs_len |
| ... | @@ -1393,7 +1456,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index { | ... | @@ -1393,7 +1456,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index { |
| 1393 | 1456 | ||
| 1394 | pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type { | 1457 | pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type { |
| 1395 | if (inst.toInterned()) |ip_index| { | 1458 | if (inst.toInterned()) |ip_index| { |
| 1396 | return Type.fromInterned(ip.typeOf(ip_index)); | 1459 | return .fromInterned(ip.typeOf(ip_index)); |
| 1397 | } else { | 1460 | } else { |
| 1398 | return air.typeOfIndex(inst.toIndex().?, ip); | 1461 | return air.typeOfIndex(inst.toIndex().?, ip); |
| 1399 | } | 1462 | } |
| ... | @@ -1483,7 +1546,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1483,7 +1546,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1483 | .is_non_err_ptr, | 1546 | .is_non_err_ptr, |
| 1484 | .is_named_enum_value, | 1547 | .is_named_enum_value, |
| 1485 | .error_set_has_value, | 1548 | .error_set_has_value, |
| 1486 | => return Type.bool, | 1549 | => return .bool, |
| 1487 | 1550 | ||
| 1488 | .alloc, | 1551 | .alloc, |
| 1489 | .ret_ptr, | 1552 | .ret_ptr, |
| ... | @@ -1503,7 +1566,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1503,7 +1566,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1503 | .cmpxchg_weak, | 1566 | .cmpxchg_weak, |
| 1504 | .cmpxchg_strong, | 1567 | .cmpxchg_strong, |
| 1505 | .slice, | 1568 | .slice, |
| 1506 | .shuffle, | ||
| 1507 | .aggregate_init, | 1569 | .aggregate_init, |
| 1508 | .union_init, | 1570 | .union_init, |
| 1509 | .field_parent_ptr, | 1571 | .field_parent_ptr, |
| ... | @@ -1517,6 +1579,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1517,6 +1579,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1517 | .ptr_sub, | 1579 | .ptr_sub, |
| 1518 | .try_ptr, | 1580 | .try_ptr, |
| 1519 | .try_ptr_cold, | 1581 | .try_ptr_cold, |
| 1582 | .shuffle_one, | ||
| 1583 | .shuffle_two, | ||
| 1520 | => return datas[@intFromEnum(inst)].ty_pl.ty.toType(), | 1584 | => return datas[@intFromEnum(inst)].ty_pl.ty.toType(), |
| 1521 | 1585 | ||
| 1522 | .not, | 1586 | .not, |
| ... | @@ -1574,7 +1638,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1574,7 +1638,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1574 | .ret_load, | 1638 | .ret_load, |
| 1575 | .unreach, | 1639 | .unreach, |
| 1576 | .trap, | 1640 | .trap, |
| 1577 | => return Type.noreturn, | 1641 | => return .noreturn, |
| 1578 | 1642 | ||
| 1579 | .breakpoint, | 1643 | .breakpoint, |
| 1580 | .dbg_stmt, | 1644 | .dbg_stmt, |
| ... | @@ -1597,22 +1661,22 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1597,22 +1661,22 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1597 | .set_err_return_trace, | 1661 | .set_err_return_trace, |
| 1598 | .vector_store_elem, | 1662 | .vector_store_elem, |
| 1599 | .c_va_end, | 1663 | .c_va_end, |
| 1600 | => return Type.void, | 1664 | => return .void, |
| 1601 | 1665 | ||
| 1602 | .slice_len, | 1666 | .slice_len, |
| 1603 | .ret_addr, | 1667 | .ret_addr, |
| 1604 | .frame_addr, | 1668 | .frame_addr, |
| 1605 | .save_err_return_trace_index, | 1669 | .save_err_return_trace_index, |
| 1606 | => return Type.usize, | 1670 | => return .usize, |
| 1607 | 1671 | ||
| 1608 | .wasm_memory_grow => return Type.isize, | 1672 | .wasm_memory_grow => return .isize, |
| 1609 | .wasm_memory_size => return Type.usize, | 1673 | .wasm_memory_size => return .usize, |
| 1610 | 1674 | ||
| 1611 | .tag_name, .error_name => return Type.slice_const_u8_sentinel_0, | 1675 | .tag_name, .error_name => return .slice_const_u8_sentinel_0, |
| 1612 | 1676 | ||
| 1613 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { | 1677 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { |
| 1614 | const callee_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip); | 1678 | const callee_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip); |
| 1615 | return Type.fromInterned(ip.funcTypeReturnType(callee_ty.toIntern())); | 1679 | return .fromInterned(ip.funcTypeReturnType(callee_ty.toIntern())); |
| 1616 | }, | 1680 | }, |
| 1617 | 1681 | ||
| 1618 | .slice_elem_val, .ptr_elem_val, .array_elem_val => { | 1682 | .slice_elem_val, .ptr_elem_val, .array_elem_val => { |
| ... | @@ -1630,7 +1694,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1630,7 +1694,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1630 | 1694 | ||
| 1631 | .reduce, .reduce_optimized => { | 1695 | .reduce, .reduce_optimized => { |
| 1632 | const operand_ty = air.typeOf(datas[@intFromEnum(inst)].reduce.operand, ip); | 1696 | const operand_ty = air.typeOf(datas[@intFromEnum(inst)].reduce.operand, ip); |
| 1633 | return Type.fromInterned(ip.indexToKey(operand_ty.ip_index).vector_type.child); | 1697 | return .fromInterned(ip.indexToKey(operand_ty.ip_index).vector_type.child); |
| 1634 | }, | 1698 | }, |
| 1635 | 1699 | ||
| 1636 | .mul_add => return air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip), | 1700 | .mul_add => return air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip), |
| ... | @@ -1641,7 +1705,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1641,7 +1705,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1641 | 1705 | ||
| 1642 | .@"try", .try_cold => { | 1706 | .@"try", .try_cold => { |
| 1643 | const err_union_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip); | 1707 | const err_union_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip); |
| 1644 | return Type.fromInterned(ip.indexToKey(err_union_ty.ip_index).error_union_type.payload_type); | 1708 | return .fromInterned(ip.indexToKey(err_union_ty.ip_index).error_union_type.payload_type); |
| 1645 | }, | 1709 | }, |
| 1646 | 1710 | ||
| 1647 | .tlv_dllimport_ptr => return .fromInterned(datas[@intFromEnum(inst)].ty_nav.ty), | 1711 | .tlv_dllimport_ptr => return .fromInterned(datas[@intFromEnum(inst)].ty_nav.ty), |
| ... | @@ -1649,7 +1713,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1649,7 +1713,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1649 | .work_item_id, | 1713 | .work_item_id, |
| 1650 | .work_group_size, | 1714 | .work_group_size, |
| 1651 | .work_group_id, | 1715 | .work_group_id, |
| 1652 | => return Type.u32, | 1716 | => return .u32, |
| 1653 | 1717 | ||
| 1654 | .inferred_alloc => unreachable, | 1718 | .inferred_alloc => unreachable, |
| 1655 | .inferred_alloc_comptime => unreachable, | 1719 | .inferred_alloc_comptime => unreachable, |
| ... | @@ -1696,7 +1760,7 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref { | ... | @@ -1696,7 +1760,7 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref { |
| 1696 | /// Returns `null` if runtime-known. | 1760 | /// Returns `null` if runtime-known. |
| 1697 | pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value { | 1761 | pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value { |
| 1698 | if (inst.toInterned()) |ip_index| { | 1762 | if (inst.toInterned()) |ip_index| { |
| 1699 | return Value.fromInterned(ip_index); | 1763 | return .fromInterned(ip_index); |
| 1700 | } | 1764 | } |
| 1701 | const index = inst.toIndex().?; | 1765 | const index = inst.toIndex().?; |
| 1702 | return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt); | 1766 | return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt); |
| ... | @@ -1903,7 +1967,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1903,7 +1967,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1903 | .reduce, | 1967 | .reduce, |
| 1904 | .reduce_optimized, | 1968 | .reduce_optimized, |
| 1905 | .splat, | 1969 | .splat, |
| 1906 | .shuffle, | 1970 | .shuffle_one, |
| 1971 | .shuffle_two, | ||
| 1907 | .select, | 1972 | .select, |
| 1908 | .is_named_enum_value, | 1973 | .is_named_enum_value, |
| 1909 | .tag_name, | 1974 | .tag_name, |
| ... | @@ -2030,6 +2095,48 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch { | ... | @@ -2030,6 +2095,48 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch { |
| 2030 | }; | 2095 | }; |
| 2031 | } | 2096 | } |
| 2032 | 2097 | ||
| 2098 | pub fn unwrapShuffleOne(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index) struct { | ||
| 2099 | result_ty: Type, | ||
| 2100 | operand: Inst.Ref, | ||
| 2101 | mask: []const ShuffleOneMask, | ||
| 2102 | } { | ||
| 2103 | const inst = air.instructions.get(@intFromEnum(inst_index)); | ||
| 2104 | switch (inst.tag) { | ||
| 2105 | .shuffle_one => {}, | ||
| 2106 | else => unreachable, // assertion failure | ||
| 2107 | } | ||
| 2108 | const result_ty: Type = .fromInterned(inst.data.ty_pl.ty.toInterned().?); | ||
| 2109 | const mask_len: u32 = result_ty.vectorLen(zcu); | ||
| 2110 | const extra_idx = inst.data.ty_pl.payload; | ||
| 2111 | return .{ | ||
| 2112 | .result_ty = result_ty, | ||
| 2113 | .operand = @enumFromInt(air.extra.items[extra_idx + mask_len]), | ||
| 2114 | .mask = @ptrCast(air.extra.items[extra_idx..][0..mask_len]), | ||
| 2115 | }; | ||
| 2116 | } | ||
| 2117 | |||
| 2118 | pub fn unwrapShuffleTwo(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index) struct { | ||
| 2119 | result_ty: Type, | ||
| 2120 | operand_a: Inst.Ref, | ||
| 2121 | operand_b: Inst.Ref, | ||
| 2122 | mask: []const ShuffleTwoMask, | ||
| 2123 | } { | ||
| 2124 | const inst = air.instructions.get(@intFromEnum(inst_index)); | ||
| 2125 | switch (inst.tag) { | ||
| 2126 | .shuffle_two => {}, | ||
| 2127 | else => unreachable, // assertion failure | ||
| 2128 | } | ||
| 2129 | const result_ty: Type = .fromInterned(inst.data.ty_pl.ty.toInterned().?); | ||
| 2130 | const mask_len: u32 = result_ty.vectorLen(zcu); | ||
| 2131 | const extra_idx = inst.data.ty_pl.payload; | ||
| 2132 | return .{ | ||
| 2133 | .result_ty = result_ty, | ||
| 2134 | .operand_a = @enumFromInt(air.extra.items[extra_idx + mask_len + 0]), | ||
| 2135 | .operand_b = @enumFromInt(air.extra.items[extra_idx + mask_len + 1]), | ||
| 2136 | .mask = @ptrCast(air.extra.items[extra_idx..][0..mask_len]), | ||
| 2137 | }; | ||
| 2138 | } | ||
| 2139 | |||
| 2033 | pub const typesFullyResolved = types_resolved.typesFullyResolved; | 2140 | pub const typesFullyResolved = types_resolved.typesFullyResolved; |
| 2034 | pub const typeFullyResolved = types_resolved.checkType; | 2141 | pub const typeFullyResolved = types_resolved.checkType; |
| 2035 | pub const valFullyResolved = types_resolved.checkVal; | 2142 | pub const valFullyResolved = types_resolved.checkVal; |
src/Air/Legalize.zig+1710-120| ... | @@ -1,147 +1,1737 @@ | ... | @@ -1,147 +1,1737 @@ |
| 1 | zcu: *const Zcu, | 1 | pt: Zcu.PerThread, |
| 2 | air: Air, | 2 | air_instructions: std.MultiArrayList(Air.Inst), |
| 3 | features: std.enums.EnumSet(Feature), | 3 | air_extra: std.ArrayListUnmanaged(u32), |
| 4 | features: *const Features, | ||
| 4 | 5 | ||
| 5 | pub const Feature = enum { | 6 | pub const Feature = enum { |
| 7 | scalarize_add, | ||
| 8 | scalarize_add_safe, | ||
| 9 | scalarize_add_optimized, | ||
| 10 | scalarize_add_wrap, | ||
| 11 | scalarize_add_sat, | ||
| 12 | scalarize_sub, | ||
| 13 | scalarize_sub_safe, | ||
| 14 | scalarize_sub_optimized, | ||
| 15 | scalarize_sub_wrap, | ||
| 16 | scalarize_sub_sat, | ||
| 17 | scalarize_mul, | ||
| 18 | scalarize_mul_safe, | ||
| 19 | scalarize_mul_optimized, | ||
| 20 | scalarize_mul_wrap, | ||
| 21 | scalarize_mul_sat, | ||
| 22 | scalarize_div_float, | ||
| 23 | scalarize_div_float_optimized, | ||
| 24 | scalarize_div_trunc, | ||
| 25 | scalarize_div_trunc_optimized, | ||
| 26 | scalarize_div_floor, | ||
| 27 | scalarize_div_floor_optimized, | ||
| 28 | scalarize_div_exact, | ||
| 29 | scalarize_div_exact_optimized, | ||
| 30 | scalarize_rem, | ||
| 31 | scalarize_rem_optimized, | ||
| 32 | scalarize_mod, | ||
| 33 | scalarize_mod_optimized, | ||
| 34 | scalarize_max, | ||
| 35 | scalarize_min, | ||
| 36 | scalarize_add_with_overflow, | ||
| 37 | scalarize_sub_with_overflow, | ||
| 38 | scalarize_mul_with_overflow, | ||
| 39 | scalarize_shl_with_overflow, | ||
| 40 | scalarize_bit_and, | ||
| 41 | scalarize_bit_or, | ||
| 42 | scalarize_shr, | ||
| 43 | scalarize_shr_exact, | ||
| 44 | scalarize_shl, | ||
| 45 | scalarize_shl_exact, | ||
| 46 | scalarize_shl_sat, | ||
| 47 | scalarize_xor, | ||
| 48 | scalarize_not, | ||
| 49 | scalarize_bitcast, | ||
| 50 | scalarize_clz, | ||
| 51 | scalarize_ctz, | ||
| 52 | scalarize_popcount, | ||
| 53 | scalarize_byte_swap, | ||
| 54 | scalarize_bit_reverse, | ||
| 55 | scalarize_sqrt, | ||
| 56 | scalarize_sin, | ||
| 57 | scalarize_cos, | ||
| 58 | scalarize_tan, | ||
| 59 | scalarize_exp, | ||
| 60 | scalarize_exp2, | ||
| 61 | scalarize_log, | ||
| 62 | scalarize_log2, | ||
| 63 | scalarize_log10, | ||
| 64 | scalarize_abs, | ||
| 65 | scalarize_floor, | ||
| 66 | scalarize_ceil, | ||
| 67 | scalarize_round, | ||
| 68 | scalarize_trunc_float, | ||
| 69 | scalarize_neg, | ||
| 70 | scalarize_neg_optimized, | ||
| 71 | scalarize_cmp_vector, | ||
| 72 | scalarize_cmp_vector_optimized, | ||
| 73 | scalarize_fptrunc, | ||
| 74 | scalarize_fpext, | ||
| 75 | scalarize_intcast, | ||
| 76 | scalarize_intcast_safe, | ||
| 77 | scalarize_trunc, | ||
| 78 | scalarize_int_from_float, | ||
| 79 | scalarize_int_from_float_optimized, | ||
| 80 | scalarize_float_from_int, | ||
| 81 | scalarize_shuffle_one, | ||
| 82 | scalarize_shuffle_two, | ||
| 83 | scalarize_select, | ||
| 84 | scalarize_mul_add, | ||
| 85 | |||
| 6 | /// Legalize (shift lhs, (splat rhs)) -> (shift lhs, rhs) | 86 | /// Legalize (shift lhs, (splat rhs)) -> (shift lhs, rhs) |
| 7 | remove_shift_vector_rhs_splat, | 87 | unsplat_shift_rhs, |
| 8 | /// Legalize reduce of a one element vector to a bitcast | 88 | /// Legalize reduce of a one element vector to a bitcast |
| 9 | reduce_one_elem_to_bitcast, | 89 | reduce_one_elem_to_bitcast, |
| 90 | |||
| 91 | /// Replace `intcast_safe` with an explicit safety check which `call`s the panic function on failure. | ||
| 92 | /// Not compatible with `scalarize_intcast_safe`. | ||
| 93 | expand_intcast_safe, | ||
| 94 | /// Replace `add_safe` with an explicit safety check which `call`s the panic function on failure. | ||
| 95 | /// Not compatible with `scalarize_add_safe`. | ||
| 96 | expand_add_safe, | ||
| 97 | /// Replace `sub_safe` with an explicit safety check which `call`s the panic function on failure. | ||
| 98 | /// Not compatible with `scalarize_sub_safe`. | ||
| 99 | expand_sub_safe, | ||
| 100 | /// Replace `mul_safe` with an explicit safety check which `call`s the panic function on failure. | ||
| 101 | /// Not compatible with `scalarize_mul_safe`. | ||
| 102 | expand_mul_safe, | ||
| 103 | |||
| 104 | fn scalarize(tag: Air.Inst.Tag) Feature { | ||
| 105 | return switch (tag) { | ||
| 106 | else => unreachable, | ||
| 107 | .add => .scalarize_add, | ||
| 108 | .add_safe => .scalarize_add_safe, | ||
| 109 | .add_optimized => .scalarize_add_optimized, | ||
| 110 | .add_wrap => .scalarize_add_wrap, | ||
| 111 | .add_sat => .scalarize_add_sat, | ||
| 112 | .sub => .scalarize_sub, | ||
| 113 | .sub_safe => .scalarize_sub_safe, | ||
| 114 | .sub_optimized => .scalarize_sub_optimized, | ||
| 115 | .sub_wrap => .scalarize_sub_wrap, | ||
| 116 | .sub_sat => .scalarize_sub_sat, | ||
| 117 | .mul => .scalarize_mul, | ||
| 118 | .mul_safe => .scalarize_mul_safe, | ||
| 119 | .mul_optimized => .scalarize_mul_optimized, | ||
| 120 | .mul_wrap => .scalarize_mul_wrap, | ||
| 121 | .mul_sat => .scalarize_mul_sat, | ||
| 122 | .div_float => .scalarize_div_float, | ||
| 123 | .div_float_optimized => .scalarize_div_float_optimized, | ||
| 124 | .div_trunc => .scalarize_div_trunc, | ||
| 125 | .div_trunc_optimized => .scalarize_div_trunc_optimized, | ||
| 126 | .div_floor => .scalarize_div_floor, | ||
| 127 | .div_floor_optimized => .scalarize_div_floor_optimized, | ||
| 128 | .div_exact => .scalarize_div_exact, | ||
| 129 | .div_exact_optimized => .scalarize_div_exact_optimized, | ||
| 130 | .rem => .scalarize_rem, | ||
| 131 | .rem_optimized => .scalarize_rem_optimized, | ||
| 132 | .mod => .scalarize_mod, | ||
| 133 | .mod_optimized => .scalarize_mod_optimized, | ||
| 134 | .max => .scalarize_max, | ||
| 135 | .min => .scalarize_min, | ||
| 136 | .add_with_overflow => .scalarize_add_with_overflow, | ||
| 137 | .sub_with_overflow => .scalarize_sub_with_overflow, | ||
| 138 | .mul_with_overflow => .scalarize_mul_with_overflow, | ||
| 139 | .shl_with_overflow => .scalarize_shl_with_overflow, | ||
| 140 | .bit_and => .scalarize_bit_and, | ||
| 141 | .bit_or => .scalarize_bit_or, | ||
| 142 | .shr => .scalarize_shr, | ||
| 143 | .shr_exact => .scalarize_shr_exact, | ||
| 144 | .shl => .scalarize_shl, | ||
| 145 | .shl_exact => .scalarize_shl_exact, | ||
| 146 | .shl_sat => .scalarize_shl_sat, | ||
| 147 | .xor => .scalarize_xor, | ||
| 148 | .not => .scalarize_not, | ||
| 149 | .bitcast => .scalarize_bitcast, | ||
| 150 | .clz => .scalarize_clz, | ||
| 151 | .ctz => .scalarize_ctz, | ||
| 152 | .popcount => .scalarize_popcount, | ||
| 153 | .byte_swap => .scalarize_byte_swap, | ||
| 154 | .bit_reverse => .scalarize_bit_reverse, | ||
| 155 | .sqrt => .scalarize_sqrt, | ||
| 156 | .sin => .scalarize_sin, | ||
| 157 | .cos => .scalarize_cos, | ||
| 158 | .tan => .scalarize_tan, | ||
| 159 | .exp => .scalarize_exp, | ||
| 160 | .exp2 => .scalarize_exp2, | ||
| 161 | .log => .scalarize_log, | ||
| 162 | .log2 => .scalarize_log2, | ||
| 163 | .log10 => .scalarize_log10, | ||
| 164 | .abs => .scalarize_abs, | ||
| 165 | .floor => .scalarize_floor, | ||
| 166 | .ceil => .scalarize_ceil, | ||
| 167 | .round => .scalarize_round, | ||
| 168 | .trunc_float => .scalarize_trunc_float, | ||
| 169 | .neg => .scalarize_neg, | ||
| 170 | .neg_optimized => .scalarize_neg_optimized, | ||
| 171 | .cmp_vector => .scalarize_cmp_vector, | ||
| 172 | .cmp_vector_optimized => .scalarize_cmp_vector_optimized, | ||
| 173 | .fptrunc => .scalarize_fptrunc, | ||
| 174 | .fpext => .scalarize_fpext, | ||
| 175 | .intcast => .scalarize_intcast, | ||
| 176 | .intcast_safe => .scalarize_intcast_safe, | ||
| 177 | .trunc => .scalarize_trunc, | ||
| 178 | .int_from_float => .scalarize_int_from_float, | ||
| 179 | .int_from_float_optimized => .scalarize_int_from_float_optimized, | ||
| 180 | .float_from_int => .scalarize_float_from_int, | ||
| 181 | .shuffle_one => .scalarize_shuffle_one, | ||
| 182 | .shuffle_two => .scalarize_shuffle_two, | ||
| 183 | .select => .scalarize_selects, | ||
| 184 | .mul_add => .scalarize_mul_add, | ||
| 185 | }; | ||
| 186 | } | ||
| 10 | }; | 187 | }; |
| 11 | 188 | ||
| 12 | pub const Features = std.enums.EnumFieldStruct(Feature, bool, false); | 189 | pub const Features = std.enums.EnumSet(Feature); |
| 190 | |||
| 191 | pub const Error = std.mem.Allocator.Error; | ||
| 13 | 192 | ||
| 14 | pub fn legalize(air: *Air, backend: std.builtin.CompilerBackend, zcu: *const Zcu) std.mem.Allocator.Error!void { | 193 | pub fn legalize(air: *Air, pt: Zcu.PerThread, features: *const Features) Error!void { |
| 194 | dev.check(.legalize); | ||
| 195 | assert(!features.bits.eql(.initEmpty())); // backend asked to run legalize, but no features were enabled | ||
| 15 | var l: Legalize = .{ | 196 | var l: Legalize = .{ |
| 16 | .zcu = zcu, | 197 | .pt = pt, |
| 17 | .air = air.*, | 198 | .air_instructions = air.instructions.toMultiArrayList(), |
| 18 | .features = features: switch (backend) { | 199 | .air_extra = air.extra, |
| 19 | .other, .stage1 => unreachable, | 200 | .features = features, |
| 20 | inline .stage2_llvm, | 201 | }; |
| 21 | .stage2_c, | 202 | defer air.* = l.getTmpAir(); |
| 22 | .stage2_wasm, | 203 | const main_extra = l.extraData(Air.Block, l.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)]); |
| 23 | .stage2_arm, | 204 | try l.legalizeBody(main_extra.end, main_extra.data.body_len); |
| 24 | .stage2_x86_64, | 205 | } |
| 25 | .stage2_aarch64, | 206 | |
| 26 | .stage2_x86, | 207 | fn getTmpAir(l: *const Legalize) Air { |
| 27 | .stage2_riscv64, | 208 | return .{ |
| 28 | .stage2_sparc64, | 209 | .instructions = l.air_instructions.slice(), |
| 29 | .stage2_spirv64, | 210 | .extra = l.air_extra, |
| 30 | .stage2_powerpc, | ||
| 31 | => |ct_backend| { | ||
| 32 | const Backend = codegen.importBackend(ct_backend) orelse break :features .initEmpty(); | ||
| 33 | break :features if (@hasDecl(Backend, "legalize_features")) | ||
| 34 | .init(Backend.legalize_features) | ||
| 35 | else | ||
| 36 | .initEmpty(); | ||
| 37 | }, | ||
| 38 | _ => unreachable, | ||
| 39 | }, | ||
| 40 | }; | 211 | }; |
| 41 | defer air.* = l.air; | ||
| 42 | if (!l.features.bits.eql(.initEmpty())) try l.legalizeBody(l.air.getMainBody()); | ||
| 43 | } | 212 | } |
| 44 | 213 | ||
| 45 | fn legalizeBody(l: *Legalize, body: []const Air.Inst.Index) std.mem.Allocator.Error!void { | 214 | fn typeOf(l: *const Legalize, ref: Air.Inst.Ref) Type { |
| 46 | const zcu = l.zcu; | 215 | return l.getTmpAir().typeOf(ref, &l.pt.zcu.intern_pool); |
| 216 | } | ||
| 217 | |||
| 218 | fn typeOfIndex(l: *const Legalize, inst: Air.Inst.Index) Type { | ||
| 219 | return l.getTmpAir().typeOfIndex(inst, &l.pt.zcu.intern_pool); | ||
| 220 | } | ||
| 221 | |||
| 222 | fn extraData(l: *const Legalize, comptime T: type, index: usize) @TypeOf(Air.extraData(undefined, T, undefined)) { | ||
| 223 | return l.getTmpAir().extraData(T, index); | ||
| 224 | } | ||
| 225 | |||
| 226 | fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { | ||
| 227 | const zcu = l.pt.zcu; | ||
| 47 | const ip = &zcu.intern_pool; | 228 | const ip = &zcu.intern_pool; |
| 48 | const tags = l.air.instructions.items(.tag); | 229 | for (0..body_len) |body_index| { |
| 49 | const data = l.air.instructions.items(.data); | 230 | const inst: Air.Inst.Index = @enumFromInt(l.air_extra.items[body_start + body_index]); |
| 50 | for (body) |inst| inst: switch (tags[@intFromEnum(inst)]) { | 231 | inst: switch (l.air_instructions.items(.tag)[@intFromEnum(inst)]) { |
| 51 | else => {}, | 232 | .arg, |
| 52 | 233 | => {}, | |
| 53 | .shl, | 234 | inline .add, |
| 54 | .shl_exact, | 235 | .add_optimized, |
| 55 | .shl_sat, | 236 | .add_wrap, |
| 56 | .shr, | 237 | .add_sat, |
| 57 | .shr_exact, | 238 | .sub, |
| 58 | => |air_tag| if (l.features.contains(.remove_shift_vector_rhs_splat)) done: { | 239 | .sub_optimized, |
| 59 | const bin_op = data[@intFromEnum(inst)].bin_op; | 240 | .sub_wrap, |
| 60 | const ty = l.air.typeOf(bin_op.rhs, ip); | 241 | .sub_sat, |
| 61 | if (!ty.isVector(zcu)) break :done; | 242 | .mul, |
| 62 | if (bin_op.rhs.toInterned()) |rhs_ip_index| switch (ip.indexToKey(rhs_ip_index)) { | 243 | .mul_optimized, |
| 63 | else => {}, | 244 | .mul_wrap, |
| 64 | .aggregate => |aggregate| switch (aggregate.storage) { | 245 | .mul_sat, |
| 65 | else => {}, | 246 | .div_float, |
| 66 | .repeated_elem => |splat| continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{ | 247 | .div_float_optimized, |
| 67 | .lhs = bin_op.lhs, | 248 | .div_trunc, |
| 68 | .rhs = Air.internedToRef(splat), | 249 | .div_trunc_optimized, |
| 69 | } }), | 250 | .div_floor, |
| 70 | }, | 251 | .div_floor_optimized, |
| 71 | } else { | 252 | .div_exact, |
| 72 | const rhs_inst = bin_op.rhs.toIndex().?; | 253 | .div_exact_optimized, |
| 73 | switch (tags[@intFromEnum(rhs_inst)]) { | 254 | .rem, |
| 74 | else => {}, | 255 | .rem_optimized, |
| 75 | .splat => continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{ | 256 | .mod, |
| 76 | .lhs = bin_op.lhs, | 257 | .mod_optimized, |
| 77 | .rhs = data[@intFromEnum(rhs_inst)].ty_op.operand, | 258 | .max, |
| 259 | .min, | ||
| 260 | .bit_and, | ||
| 261 | .bit_or, | ||
| 262 | .xor, | ||
| 263 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 264 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 265 | if (l.typeOf(bin_op.lhs).isVector(zcu)) continue :inst try l.scalarize(inst, .bin_op); | ||
| 266 | }, | ||
| 267 | .add_safe => if (l.features.contains(.expand_add_safe)) { | ||
| 268 | assert(!l.features.contains(.scalarize_add_safe)); // it doesn't make sense to do both | ||
| 269 | continue :inst l.replaceInst(inst, .block, try l.safeArithmeticBlockPayload(inst, .add_with_overflow)); | ||
| 270 | } else if (l.features.contains(.scalarize_add_safe)) { | ||
| 271 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 272 | if (l.typeOf(bin_op.lhs).isVector(zcu)) continue :inst try l.scalarize(inst, .bin_op); | ||
| 273 | }, | ||
| 274 | .sub_safe => if (l.features.contains(.expand_sub_safe)) { | ||
| 275 | assert(!l.features.contains(.scalarize_sub_safe)); // it doesn't make sense to do both | ||
| 276 | continue :inst l.replaceInst(inst, .block, try l.safeArithmeticBlockPayload(inst, .sub_with_overflow)); | ||
| 277 | } else if (l.features.contains(.scalarize_sub_safe)) { | ||
| 278 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 279 | if (l.typeOf(bin_op.lhs).isVector(zcu)) continue :inst try l.scalarize(inst, .bin_op); | ||
| 280 | }, | ||
| 281 | .mul_safe => if (l.features.contains(.expand_mul_safe)) { | ||
| 282 | assert(!l.features.contains(.scalarize_mul_safe)); // it doesn't make sense to do both | ||
| 283 | continue :inst l.replaceInst(inst, .block, try l.safeArithmeticBlockPayload(inst, .mul_with_overflow)); | ||
| 284 | } else if (l.features.contains(.scalarize_mul_safe)) { | ||
| 285 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 286 | if (l.typeOf(bin_op.lhs).isVector(zcu)) continue :inst try l.scalarize(inst, .bin_op); | ||
| 287 | }, | ||
| 288 | .ptr_add, | ||
| 289 | .ptr_sub, | ||
| 290 | => {}, | ||
| 291 | inline .add_with_overflow, | ||
| 292 | .sub_with_overflow, | ||
| 293 | .mul_with_overflow, | ||
| 294 | .shl_with_overflow, | ||
| 295 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 296 | const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 297 | if (ty_pl.ty.toType().fieldType(0, zcu).isVector(zcu)) continue :inst l.replaceInst(inst, .block, try l.scalarizeOverflowBlockPayload(inst)); | ||
| 298 | }, | ||
| 299 | .alloc, | ||
| 300 | => {}, | ||
| 301 | .inferred_alloc, | ||
| 302 | .inferred_alloc_comptime, | ||
| 303 | => unreachable, | ||
| 304 | .ret_ptr, | ||
| 305 | .assembly, | ||
| 306 | => {}, | ||
| 307 | inline .shr, | ||
| 308 | .shr_exact, | ||
| 309 | .shl, | ||
| 310 | .shl_exact, | ||
| 311 | .shl_sat, | ||
| 312 | => |air_tag| done: { | ||
| 313 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 314 | if (!l.typeOf(bin_op.rhs).isVector(zcu)) break :done; | ||
| 315 | if (l.features.contains(.unsplat_shift_rhs)) { | ||
| 316 | if (bin_op.rhs.toInterned()) |rhs_ip_index| switch (ip.indexToKey(rhs_ip_index)) { | ||
| 317 | else => {}, | ||
| 318 | .aggregate => |aggregate| switch (aggregate.storage) { | ||
| 319 | else => {}, | ||
| 320 | .repeated_elem => |splat| continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{ | ||
| 321 | .lhs = bin_op.lhs, | ||
| 322 | .rhs = Air.internedToRef(splat), | ||
| 323 | } }), | ||
| 324 | }, | ||
| 325 | } else { | ||
| 326 | const rhs_inst = bin_op.rhs.toIndex().?; | ||
| 327 | switch (l.air_instructions.items(.tag)[@intFromEnum(rhs_inst)]) { | ||
| 328 | else => {}, | ||
| 329 | .splat => continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{ | ||
| 330 | .lhs = bin_op.lhs, | ||
| 331 | .rhs = l.air_instructions.items(.data)[@intFromEnum(rhs_inst)].ty_op.operand, | ||
| 332 | } }), | ||
| 333 | } | ||
| 334 | } | ||
| 335 | } | ||
| 336 | if (l.features.contains(comptime .scalarize(air_tag))) continue :inst try l.scalarize(inst, .bin_op); | ||
| 337 | }, | ||
| 338 | inline .not, | ||
| 339 | .clz, | ||
| 340 | .ctz, | ||
| 341 | .popcount, | ||
| 342 | .byte_swap, | ||
| 343 | .bit_reverse, | ||
| 344 | .abs, | ||
| 345 | .fptrunc, | ||
| 346 | .fpext, | ||
| 347 | .intcast, | ||
| 348 | .trunc, | ||
| 349 | .int_from_float, | ||
| 350 | .int_from_float_optimized, | ||
| 351 | .float_from_int, | ||
| 352 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 353 | const ty_op = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 354 | if (ty_op.ty.toType().isVector(zcu)) continue :inst try l.scalarize(inst, .ty_op); | ||
| 355 | }, | ||
| 356 | inline .bitcast, | ||
| 357 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 358 | const ty_op = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 359 | const to_ty = ty_op.ty.toType(); | ||
| 360 | const from_ty = l.typeOf(ty_op.operand); | ||
| 361 | if (to_ty.isVector(zcu) and from_ty.isVector(zcu) and to_ty.vectorLen(zcu) == from_ty.vectorLen(zcu)) | ||
| 362 | continue :inst try l.scalarize(inst, .ty_op); | ||
| 363 | }, | ||
| 364 | .intcast_safe => if (l.features.contains(.expand_intcast_safe)) { | ||
| 365 | assert(!l.features.contains(.scalarize_intcast_safe)); // it doesn't make sense to do both | ||
| 366 | continue :inst l.replaceInst(inst, .block, try l.safeIntcastBlockPayload(inst)); | ||
| 367 | } else if (l.features.contains(.scalarize_intcast_safe)) { | ||
| 368 | const ty_op = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 369 | if (ty_op.ty.toType().isVector(zcu)) continue :inst try l.scalarize(inst, .ty_op); | ||
| 370 | }, | ||
| 371 | .block, | ||
| 372 | .loop, | ||
| 373 | => { | ||
| 374 | const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 375 | const extra = l.extraData(Air.Block, ty_pl.payload); | ||
| 376 | try l.legalizeBody(extra.end, extra.data.body_len); | ||
| 377 | }, | ||
| 378 | .repeat, | ||
| 379 | .br, | ||
| 380 | .trap, | ||
| 381 | .breakpoint, | ||
| 382 | .ret_addr, | ||
| 383 | .frame_addr, | ||
| 384 | .call, | ||
| 385 | .call_always_tail, | ||
| 386 | .call_never_tail, | ||
| 387 | .call_never_inline, | ||
| 388 | => {}, | ||
| 389 | inline .sqrt, | ||
| 390 | .sin, | ||
| 391 | .cos, | ||
| 392 | .tan, | ||
| 393 | .exp, | ||
| 394 | .exp2, | ||
| 395 | .log, | ||
| 396 | .log2, | ||
| 397 | .log10, | ||
| 398 | .floor, | ||
| 399 | .ceil, | ||
| 400 | .round, | ||
| 401 | .trunc_float, | ||
| 402 | .neg, | ||
| 403 | .neg_optimized, | ||
| 404 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 405 | const un_op = l.air_instructions.items(.data)[@intFromEnum(inst)].un_op; | ||
| 406 | if (l.typeOf(un_op).isVector(zcu)) continue :inst try l.scalarize(inst, .un_op); | ||
| 407 | }, | ||
| 408 | .cmp_lt, | ||
| 409 | .cmp_lt_optimized, | ||
| 410 | .cmp_lte, | ||
| 411 | .cmp_lte_optimized, | ||
| 412 | .cmp_eq, | ||
| 413 | .cmp_eq_optimized, | ||
| 414 | .cmp_gte, | ||
| 415 | .cmp_gte_optimized, | ||
| 416 | .cmp_gt, | ||
| 417 | .cmp_gt_optimized, | ||
| 418 | .cmp_neq, | ||
| 419 | .cmp_neq_optimized, | ||
| 420 | => {}, | ||
| 421 | inline .cmp_vector, | ||
| 422 | .cmp_vector_optimized, | ||
| 423 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 424 | const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 425 | if (ty_pl.ty.toType().isVector(zcu)) continue :inst try l.scalarize(inst, .ty_pl_vector_cmp); | ||
| 426 | }, | ||
| 427 | .cond_br, | ||
| 428 | => { | ||
| 429 | const pl_op = l.air_instructions.items(.data)[@intFromEnum(inst)].pl_op; | ||
| 430 | const extra = l.extraData(Air.CondBr, pl_op.payload); | ||
| 431 | try l.legalizeBody(extra.end, extra.data.then_body_len); | ||
| 432 | try l.legalizeBody(extra.end + extra.data.then_body_len, extra.data.else_body_len); | ||
| 433 | }, | ||
| 434 | .switch_br, | ||
| 435 | .loop_switch_br, | ||
| 436 | => { | ||
| 437 | const pl_op = l.air_instructions.items(.data)[@intFromEnum(inst)].pl_op; | ||
| 438 | const extra = l.extraData(Air.SwitchBr, pl_op.payload); | ||
| 439 | const hint_bag_count = std.math.divCeil(usize, extra.data.cases_len + 1, 10) catch unreachable; | ||
| 440 | var extra_index = extra.end + hint_bag_count; | ||
| 441 | for (0..extra.data.cases_len) |_| { | ||
| 442 | const case_extra = l.extraData(Air.SwitchBr.Case, extra_index); | ||
| 443 | const case_body_start = case_extra.end + case_extra.data.items_len + case_extra.data.ranges_len * 2; | ||
| 444 | try l.legalizeBody(case_body_start, case_extra.data.body_len); | ||
| 445 | extra_index = case_body_start + case_extra.data.body_len; | ||
| 446 | } | ||
| 447 | try l.legalizeBody(extra_index, extra.data.else_body_len); | ||
| 448 | }, | ||
| 449 | .switch_dispatch, | ||
| 450 | => {}, | ||
| 451 | .@"try", | ||
| 452 | .try_cold, | ||
| 453 | => { | ||
| 454 | const pl_op = l.air_instructions.items(.data)[@intFromEnum(inst)].pl_op; | ||
| 455 | const extra = l.extraData(Air.Try, pl_op.payload); | ||
| 456 | try l.legalizeBody(extra.end, extra.data.body_len); | ||
| 457 | }, | ||
| 458 | .try_ptr, | ||
| 459 | .try_ptr_cold, | ||
| 460 | => { | ||
| 461 | const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 462 | const extra = l.extraData(Air.TryPtr, ty_pl.payload); | ||
| 463 | try l.legalizeBody(extra.end, extra.data.body_len); | ||
| 464 | }, | ||
| 465 | .dbg_stmt, | ||
| 466 | .dbg_empty_stmt, | ||
| 467 | => {}, | ||
| 468 | .dbg_inline_block, | ||
| 469 | => { | ||
| 470 | const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 471 | const extra = l.extraData(Air.DbgInlineBlock, ty_pl.payload); | ||
| 472 | try l.legalizeBody(extra.end, extra.data.body_len); | ||
| 473 | }, | ||
| 474 | .dbg_var_ptr, | ||
| 475 | .dbg_var_val, | ||
| 476 | .dbg_arg_inline, | ||
| 477 | .is_null, | ||
| 478 | .is_non_null, | ||
| 479 | .is_null_ptr, | ||
| 480 | .is_non_null_ptr, | ||
| 481 | .is_err, | ||
| 482 | .is_non_err, | ||
| 483 | .is_err_ptr, | ||
| 484 | .is_non_err_ptr, | ||
| 485 | .bool_and, | ||
| 486 | .bool_or, | ||
| 487 | .load, | ||
| 488 | .ret, | ||
| 489 | .ret_safe, | ||
| 490 | .ret_load, | ||
| 491 | .store, | ||
| 492 | .store_safe, | ||
| 493 | .unreach, | ||
| 494 | => {}, | ||
| 495 | .optional_payload, | ||
| 496 | .optional_payload_ptr, | ||
| 497 | .optional_payload_ptr_set, | ||
| 498 | .wrap_optional, | ||
| 499 | .unwrap_errunion_payload, | ||
| 500 | .unwrap_errunion_err, | ||
| 501 | .unwrap_errunion_payload_ptr, | ||
| 502 | .unwrap_errunion_err_ptr, | ||
| 503 | .errunion_payload_ptr_set, | ||
| 504 | .wrap_errunion_payload, | ||
| 505 | .wrap_errunion_err, | ||
| 506 | .struct_field_ptr, | ||
| 507 | .struct_field_ptr_index_0, | ||
| 508 | .struct_field_ptr_index_1, | ||
| 509 | .struct_field_ptr_index_2, | ||
| 510 | .struct_field_ptr_index_3, | ||
| 511 | .struct_field_val, | ||
| 512 | .set_union_tag, | ||
| 513 | .get_union_tag, | ||
| 514 | .slice, | ||
| 515 | .slice_len, | ||
| 516 | .slice_ptr, | ||
| 517 | .ptr_slice_len_ptr, | ||
| 518 | .ptr_slice_ptr_ptr, | ||
| 519 | .array_elem_val, | ||
| 520 | .slice_elem_val, | ||
| 521 | .slice_elem_ptr, | ||
| 522 | .ptr_elem_val, | ||
| 523 | .ptr_elem_ptr, | ||
| 524 | .array_to_slice, | ||
| 525 | => {}, | ||
| 526 | .reduce, | ||
| 527 | .reduce_optimized, | ||
| 528 | => if (l.features.contains(.reduce_one_elem_to_bitcast)) done: { | ||
| 529 | const reduce = l.air_instructions.items(.data)[@intFromEnum(inst)].reduce; | ||
| 530 | const vector_ty = l.typeOf(reduce.operand); | ||
| 531 | switch (vector_ty.vectorLen(zcu)) { | ||
| 532 | 0 => unreachable, | ||
| 533 | 1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{ | ||
| 534 | .ty = Air.internedToRef(vector_ty.childType(zcu).toIntern()), | ||
| 535 | .operand = reduce.operand, | ||
| 78 | } }), | 536 | } }), |
| 537 | else => break :done, | ||
| 79 | } | 538 | } |
| 539 | }, | ||
| 540 | .splat, | ||
| 541 | => {}, | ||
| 542 | .shuffle_one => if (l.features.contains(.scalarize_shuffle_one)) continue :inst try l.scalarize(inst, .shuffle_one), | ||
| 543 | .shuffle_two => if (l.features.contains(.scalarize_shuffle_two)) continue :inst try l.scalarize(inst, .shuffle_two), | ||
| 544 | .select => if (l.features.contains(.scalarize_select)) continue :inst try l.scalarize(inst, .select), | ||
| 545 | .memset, | ||
| 546 | .memset_safe, | ||
| 547 | .memcpy, | ||
| 548 | .memmove, | ||
| 549 | .cmpxchg_weak, | ||
| 550 | .cmpxchg_strong, | ||
| 551 | .atomic_load, | ||
| 552 | .atomic_store_unordered, | ||
| 553 | .atomic_store_monotonic, | ||
| 554 | .atomic_store_release, | ||
| 555 | .atomic_store_seq_cst, | ||
| 556 | .atomic_rmw, | ||
| 557 | .is_named_enum_value, | ||
| 558 | .tag_name, | ||
| 559 | .error_name, | ||
| 560 | .error_set_has_value, | ||
| 561 | .aggregate_init, | ||
| 562 | .union_init, | ||
| 563 | .prefetch, | ||
| 564 | => {}, | ||
| 565 | inline .mul_add, | ||
| 566 | => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) { | ||
| 567 | const pl_op = l.air_instructions.items(.data)[@intFromEnum(inst)].pl_op; | ||
| 568 | if (l.typeOf(pl_op.operand).isVector(zcu)) continue :inst try l.scalarize(inst, .pl_op_bin); | ||
| 569 | }, | ||
| 570 | .field_parent_ptr, | ||
| 571 | .wasm_memory_size, | ||
| 572 | .wasm_memory_grow, | ||
| 573 | .cmp_lt_errors_len, | ||
| 574 | .err_return_trace, | ||
| 575 | .set_err_return_trace, | ||
| 576 | .addrspace_cast, | ||
| 577 | .save_err_return_trace_index, | ||
| 578 | .vector_store_elem, | ||
| 579 | .tlv_dllimport_ptr, | ||
| 580 | .c_va_arg, | ||
| 581 | .c_va_copy, | ||
| 582 | .c_va_end, | ||
| 583 | .c_va_start, | ||
| 584 | .work_item_id, | ||
| 585 | .work_group_size, | ||
| 586 | .work_group_id, | ||
| 587 | => {}, | ||
| 588 | } | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | const ScalarizeForm = enum { un_op, ty_op, bin_op, ty_pl_vector_cmp, pl_op_bin, shuffle_one, shuffle_two, select }; | ||
| 593 | inline fn scalarize(l: *Legalize, orig_inst: Air.Inst.Index, comptime form: ScalarizeForm) Error!Air.Inst.Tag { | ||
| 594 | return l.replaceInst(orig_inst, .block, try l.scalarizeBlockPayload(orig_inst, form)); | ||
| 595 | } | ||
| 596 | fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form: ScalarizeForm) Error!Air.Inst.Data { | ||
| 597 | const pt = l.pt; | ||
| 598 | const zcu = pt.zcu; | ||
| 599 | |||
| 600 | const orig = l.air_instructions.get(@intFromEnum(orig_inst)); | ||
| 601 | const res_ty = l.typeOfIndex(orig_inst); | ||
| 602 | const res_len = res_ty.vectorLen(zcu); | ||
| 603 | |||
| 604 | const extra_insts = switch (form) { | ||
| 605 | .un_op, .ty_op => 1, | ||
| 606 | .bin_op, .ty_pl_vector_cmp => 2, | ||
| 607 | .pl_op_bin => 3, | ||
| 608 | .shuffle_one, .shuffle_two => 13, | ||
| 609 | .select => 6, | ||
| 610 | }; | ||
| 611 | var inst_buf: [5 + extra_insts + 9]Air.Inst.Index = undefined; | ||
| 612 | try l.air_instructions.ensureUnusedCapacity(zcu.gpa, inst_buf.len); | ||
| 613 | |||
| 614 | var res_block: Block = .init(&inst_buf); | ||
| 615 | { | ||
| 616 | const res_alloc_inst = res_block.add(l, .{ | ||
| 617 | .tag = .alloc, | ||
| 618 | .data = .{ .ty = try pt.singleMutPtrType(res_ty) }, | ||
| 619 | }); | ||
| 620 | const index_alloc_inst = res_block.add(l, .{ | ||
| 621 | .tag = .alloc, | ||
| 622 | .data = .{ .ty = .ptr_usize }, | ||
| 623 | }); | ||
| 624 | _ = res_block.add(l, .{ | ||
| 625 | .tag = .store, | ||
| 626 | .data = .{ .bin_op = .{ | ||
| 627 | .lhs = index_alloc_inst.toRef(), | ||
| 628 | .rhs = .zero_usize, | ||
| 629 | } }, | ||
| 630 | }); | ||
| 631 | |||
| 632 | var loop: Loop = .init(l, &res_block); | ||
| 633 | loop.block = .init(res_block.stealRemainingCapacity()); | ||
| 634 | { | ||
| 635 | const cur_index_inst = loop.block.add(l, .{ | ||
| 636 | .tag = .load, | ||
| 637 | .data = .{ .ty_op = .{ | ||
| 638 | .ty = .usize_type, | ||
| 639 | .operand = index_alloc_inst.toRef(), | ||
| 640 | } }, | ||
| 641 | }); | ||
| 642 | _ = loop.block.add(l, .{ | ||
| 643 | .tag = .vector_store_elem, | ||
| 644 | .data = .{ .vector_store_elem = .{ | ||
| 645 | .vector_ptr = res_alloc_inst.toRef(), | ||
| 646 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 647 | .lhs = cur_index_inst.toRef(), | ||
| 648 | .rhs = res_elem: switch (form) { | ||
| 649 | .un_op => loop.block.add(l, .{ | ||
| 650 | .tag = orig.tag, | ||
| 651 | .data = .{ .un_op = loop.block.add(l, .{ | ||
| 652 | .tag = .array_elem_val, | ||
| 653 | .data = .{ .bin_op = .{ | ||
| 654 | .lhs = orig.data.un_op, | ||
| 655 | .rhs = cur_index_inst.toRef(), | ||
| 656 | } }, | ||
| 657 | }).toRef() }, | ||
| 658 | }).toRef(), | ||
| 659 | .ty_op => loop.block.add(l, .{ | ||
| 660 | .tag = orig.tag, | ||
| 661 | .data = .{ .ty_op = .{ | ||
| 662 | .ty = Air.internedToRef(res_ty.childType(zcu).toIntern()), | ||
| 663 | .operand = loop.block.add(l, .{ | ||
| 664 | .tag = .array_elem_val, | ||
| 665 | .data = .{ .bin_op = .{ | ||
| 666 | .lhs = orig.data.ty_op.operand, | ||
| 667 | .rhs = cur_index_inst.toRef(), | ||
| 668 | } }, | ||
| 669 | }).toRef(), | ||
| 670 | } }, | ||
| 671 | }).toRef(), | ||
| 672 | .bin_op => loop.block.add(l, .{ | ||
| 673 | .tag = orig.tag, | ||
| 674 | .data = .{ .bin_op = .{ | ||
| 675 | .lhs = loop.block.add(l, .{ | ||
| 676 | .tag = .array_elem_val, | ||
| 677 | .data = .{ .bin_op = .{ | ||
| 678 | .lhs = orig.data.bin_op.lhs, | ||
| 679 | .rhs = cur_index_inst.toRef(), | ||
| 680 | } }, | ||
| 681 | }).toRef(), | ||
| 682 | .rhs = loop.block.add(l, .{ | ||
| 683 | .tag = .array_elem_val, | ||
| 684 | .data = .{ .bin_op = .{ | ||
| 685 | .lhs = orig.data.bin_op.rhs, | ||
| 686 | .rhs = cur_index_inst.toRef(), | ||
| 687 | } }, | ||
| 688 | }).toRef(), | ||
| 689 | } }, | ||
| 690 | }).toRef(), | ||
| 691 | .ty_pl_vector_cmp => { | ||
| 692 | const extra = l.extraData(Air.VectorCmp, orig.data.ty_pl.payload).data; | ||
| 693 | break :res_elem (try loop.block.addCmp( | ||
| 694 | l, | ||
| 695 | extra.compareOperator(), | ||
| 696 | loop.block.add(l, .{ | ||
| 697 | .tag = .array_elem_val, | ||
| 698 | .data = .{ .bin_op = .{ | ||
| 699 | .lhs = extra.lhs, | ||
| 700 | .rhs = cur_index_inst.toRef(), | ||
| 701 | } }, | ||
| 702 | }).toRef(), | ||
| 703 | loop.block.add(l, .{ | ||
| 704 | .tag = .array_elem_val, | ||
| 705 | .data = .{ .bin_op = .{ | ||
| 706 | .lhs = extra.rhs, | ||
| 707 | .rhs = cur_index_inst.toRef(), | ||
| 708 | } }, | ||
| 709 | }).toRef(), | ||
| 710 | .{ .optimized = switch (orig.tag) { | ||
| 711 | else => unreachable, | ||
| 712 | .cmp_vector => false, | ||
| 713 | .cmp_vector_optimized => true, | ||
| 714 | } }, | ||
| 715 | )).toRef(); | ||
| 716 | }, | ||
| 717 | .pl_op_bin => { | ||
| 718 | const extra = l.extraData(Air.Bin, orig.data.pl_op.payload).data; | ||
| 719 | break :res_elem loop.block.add(l, .{ | ||
| 720 | .tag = orig.tag, | ||
| 721 | .data = .{ .pl_op = .{ | ||
| 722 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 723 | .lhs = loop.block.add(l, .{ | ||
| 724 | .tag = .array_elem_val, | ||
| 725 | .data = .{ .bin_op = .{ | ||
| 726 | .lhs = extra.lhs, | ||
| 727 | .rhs = cur_index_inst.toRef(), | ||
| 728 | } }, | ||
| 729 | }).toRef(), | ||
| 730 | .rhs = loop.block.add(l, .{ | ||
| 731 | .tag = .array_elem_val, | ||
| 732 | .data = .{ .bin_op = .{ | ||
| 733 | .lhs = extra.rhs, | ||
| 734 | .rhs = cur_index_inst.toRef(), | ||
| 735 | } }, | ||
| 736 | }).toRef(), | ||
| 737 | }), | ||
| 738 | .operand = loop.block.add(l, .{ | ||
| 739 | .tag = .array_elem_val, | ||
| 740 | .data = .{ .bin_op = .{ | ||
| 741 | .lhs = orig.data.pl_op.operand, | ||
| 742 | .rhs = cur_index_inst.toRef(), | ||
| 743 | } }, | ||
| 744 | }).toRef(), | ||
| 745 | } }, | ||
| 746 | }).toRef(); | ||
| 747 | }, | ||
| 748 | .shuffle_one, .shuffle_two => { | ||
| 749 | const ip = &zcu.intern_pool; | ||
| 750 | const unwrapped = switch (form) { | ||
| 751 | else => comptime unreachable, | ||
| 752 | .shuffle_one => l.getTmpAir().unwrapShuffleOne(zcu, orig_inst), | ||
| 753 | .shuffle_two => l.getTmpAir().unwrapShuffleTwo(zcu, orig_inst), | ||
| 754 | }; | ||
| 755 | const operand_a = switch (form) { | ||
| 756 | else => comptime unreachable, | ||
| 757 | .shuffle_one => unwrapped.operand, | ||
| 758 | .shuffle_two => unwrapped.operand_a, | ||
| 759 | }; | ||
| 760 | const operand_a_len = l.typeOf(operand_a).vectorLen(zcu); | ||
| 761 | const elem_ty = res_ty.childType(zcu); | ||
| 762 | var res_elem: Result = .init(l, elem_ty, &loop.block); | ||
| 763 | res_elem.block = .init(loop.block.stealCapacity(extra_insts)); | ||
| 764 | { | ||
| 765 | const ExpectedContents = extern struct { | ||
| 766 | mask_elems: [128]InternPool.Index, | ||
| 767 | ct_elems: switch (form) { | ||
| 768 | else => unreachable, | ||
| 769 | .shuffle_one => extern struct { | ||
| 770 | keys: [152]InternPool.Index, | ||
| 771 | header: u8 align(@alignOf(u32)), | ||
| 772 | index: [256][2]u8, | ||
| 773 | }, | ||
| 774 | .shuffle_two => void, | ||
| 775 | }, | ||
| 776 | }; | ||
| 777 | var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) = | ||
| 778 | std.heap.stackFallback(@sizeOf(ExpectedContents), zcu.gpa); | ||
| 779 | const gpa = stack.get(); | ||
| 780 | |||
| 781 | const mask_elems = try gpa.alloc(InternPool.Index, res_len); | ||
| 782 | defer gpa.free(mask_elems); | ||
| 783 | |||
| 784 | var ct_elems: switch (form) { | ||
| 785 | else => unreachable, | ||
| 786 | .shuffle_one => std.AutoArrayHashMapUnmanaged(InternPool.Index, void), | ||
| 787 | .shuffle_two => struct { | ||
| 788 | const empty: @This() = .{}; | ||
| 789 | inline fn deinit(_: @This(), _: std.mem.Allocator) void {} | ||
| 790 | inline fn ensureTotalCapacity(_: @This(), _: std.mem.Allocator, _: usize) error{}!void {} | ||
| 791 | }, | ||
| 792 | } = .empty; | ||
| 793 | defer ct_elems.deinit(gpa); | ||
| 794 | try ct_elems.ensureTotalCapacity(gpa, res_len); | ||
| 795 | |||
| 796 | const mask_elem_ty = try pt.intType(.signed, 1 + Type.smallestUnsignedBits(@max(operand_a_len, switch (form) { | ||
| 797 | else => comptime unreachable, | ||
| 798 | .shuffle_one => res_len, | ||
| 799 | .shuffle_two => l.typeOf(unwrapped.operand_b).vectorLen(zcu), | ||
| 800 | }))); | ||
| 801 | for (mask_elems, unwrapped.mask) |*mask_elem_val, mask_elem| mask_elem_val.* = (try pt.intValue(mask_elem_ty, switch (form) { | ||
| 802 | else => comptime unreachable, | ||
| 803 | .shuffle_one => switch (mask_elem.unwrap()) { | ||
| 804 | .elem => |index| index, | ||
| 805 | .value => |elem_val| if (ip.isUndef(elem_val)) | ||
| 806 | operand_a_len | ||
| 807 | else | ||
| 808 | ~@as(i33, @intCast((ct_elems.getOrPutAssumeCapacity(elem_val)).index)), | ||
| 809 | }, | ||
| 810 | .shuffle_two => switch (mask_elem.unwrap()) { | ||
| 811 | .a_elem => |a_index| a_index, | ||
| 812 | .b_elem => |b_index| ~@as(i33, b_index), | ||
| 813 | .undef => operand_a_len, | ||
| 814 | }, | ||
| 815 | })).toIntern(); | ||
| 816 | const mask_ty = try pt.arrayType(.{ | ||
| 817 | .len = res_len, | ||
| 818 | .child = mask_elem_ty.toIntern(), | ||
| 819 | }); | ||
| 820 | const mask_elem_inst = res_elem.block.add(l, .{ | ||
| 821 | .tag = .ptr_elem_val, | ||
| 822 | .data = .{ .bin_op = .{ | ||
| 823 | .lhs = Air.internedToRef(try pt.intern(.{ .ptr = .{ | ||
| 824 | .ty = (try pt.manyConstPtrType(mask_elem_ty)).toIntern(), | ||
| 825 | .base_addr = .{ .uav = .{ | ||
| 826 | .val = try pt.intern(.{ .aggregate = .{ | ||
| 827 | .ty = mask_ty.toIntern(), | ||
| 828 | .storage = .{ .elems = mask_elems }, | ||
| 829 | } }), | ||
| 830 | .orig_ty = (try pt.singleConstPtrType(mask_ty)).toIntern(), | ||
| 831 | } }, | ||
| 832 | .byte_offset = 0, | ||
| 833 | } })), | ||
| 834 | .rhs = cur_index_inst.toRef(), | ||
| 835 | } }, | ||
| 836 | }); | ||
| 837 | var def_cond_br: CondBr = .init(l, (try res_elem.block.addCmp( | ||
| 838 | l, | ||
| 839 | .lt, | ||
| 840 | mask_elem_inst.toRef(), | ||
| 841 | try pt.intRef(mask_elem_ty, operand_a_len), | ||
| 842 | .{}, | ||
| 843 | )).toRef(), &res_elem.block, .{}); | ||
| 844 | def_cond_br.then_block = .init(res_elem.block.stealRemainingCapacity()); | ||
| 845 | { | ||
| 846 | const operand_b_used = switch (form) { | ||
| 847 | else => comptime unreachable, | ||
| 848 | .shuffle_one => ct_elems.count() > 0, | ||
| 849 | .shuffle_two => true, | ||
| 850 | }; | ||
| 851 | var operand_cond_br: CondBr = undefined; | ||
| 852 | operand_cond_br.then_block = if (operand_b_used) then_block: { | ||
| 853 | operand_cond_br = .init(l, (try def_cond_br.then_block.addCmp( | ||
| 854 | l, | ||
| 855 | .gte, | ||
| 856 | mask_elem_inst.toRef(), | ||
| 857 | try pt.intRef(mask_elem_ty, 0), | ||
| 858 | .{}, | ||
| 859 | )).toRef(), &def_cond_br.then_block, .{}); | ||
| 860 | break :then_block .init(def_cond_br.then_block.stealRemainingCapacity()); | ||
| 861 | } else def_cond_br.then_block; | ||
| 862 | _ = operand_cond_br.then_block.add(l, .{ | ||
| 863 | .tag = .br, | ||
| 864 | .data = .{ .br = .{ | ||
| 865 | .block_inst = res_elem.inst, | ||
| 866 | .operand = operand_cond_br.then_block.add(l, .{ | ||
| 867 | .tag = .array_elem_val, | ||
| 868 | .data = .{ .bin_op = .{ | ||
| 869 | .lhs = operand_a, | ||
| 870 | .rhs = operand_cond_br.then_block.add(l, .{ | ||
| 871 | .tag = .intcast, | ||
| 872 | .data = .{ .ty_op = .{ | ||
| 873 | .ty = .usize_type, | ||
| 874 | .operand = mask_elem_inst.toRef(), | ||
| 875 | } }, | ||
| 876 | }).toRef(), | ||
| 877 | } }, | ||
| 878 | }).toRef(), | ||
| 879 | } }, | ||
| 880 | }); | ||
| 881 | if (operand_b_used) { | ||
| 882 | operand_cond_br.else_block = .init(operand_cond_br.then_block.stealRemainingCapacity()); | ||
| 883 | _ = operand_cond_br.else_block.add(l, .{ | ||
| 884 | .tag = .br, | ||
| 885 | .data = .{ .br = .{ | ||
| 886 | .block_inst = res_elem.inst, | ||
| 887 | .operand = if (switch (form) { | ||
| 888 | else => comptime unreachable, | ||
| 889 | .shuffle_one => ct_elems.count() > 1, | ||
| 890 | .shuffle_two => true, | ||
| 891 | }) operand_cond_br.else_block.add(l, .{ | ||
| 892 | .tag = switch (form) { | ||
| 893 | else => comptime unreachable, | ||
| 894 | .shuffle_one => .ptr_elem_val, | ||
| 895 | .shuffle_two => .array_elem_val, | ||
| 896 | }, | ||
| 897 | .data = .{ .bin_op = .{ | ||
| 898 | .lhs = operand_b: switch (form) { | ||
| 899 | else => comptime unreachable, | ||
| 900 | .shuffle_one => { | ||
| 901 | const ct_elems_ty = try pt.arrayType(.{ | ||
| 902 | .len = ct_elems.count(), | ||
| 903 | .child = elem_ty.toIntern(), | ||
| 904 | }); | ||
| 905 | break :operand_b Air.internedToRef(try pt.intern(.{ .ptr = .{ | ||
| 906 | .ty = (try pt.manyConstPtrType(elem_ty)).toIntern(), | ||
| 907 | .base_addr = .{ .uav = .{ | ||
| 908 | .val = try pt.intern(.{ .aggregate = .{ | ||
| 909 | .ty = ct_elems_ty.toIntern(), | ||
| 910 | .storage = .{ .elems = ct_elems.keys() }, | ||
| 911 | } }), | ||
| 912 | .orig_ty = (try pt.singleConstPtrType(ct_elems_ty)).toIntern(), | ||
| 913 | } }, | ||
| 914 | .byte_offset = 0, | ||
| 915 | } })); | ||
| 916 | }, | ||
| 917 | .shuffle_two => unwrapped.operand_b, | ||
| 918 | }, | ||
| 919 | .rhs = operand_cond_br.else_block.add(l, .{ | ||
| 920 | .tag = .intcast, | ||
| 921 | .data = .{ .ty_op = .{ | ||
| 922 | .ty = .usize_type, | ||
| 923 | .operand = operand_cond_br.else_block.add(l, .{ | ||
| 924 | .tag = .not, | ||
| 925 | .data = .{ .ty_op = .{ | ||
| 926 | .ty = Air.internedToRef(mask_elem_ty.toIntern()), | ||
| 927 | .operand = mask_elem_inst.toRef(), | ||
| 928 | } }, | ||
| 929 | }).toRef(), | ||
| 930 | } }, | ||
| 931 | }).toRef(), | ||
| 932 | } }, | ||
| 933 | }).toRef() else res_elem_br: { | ||
| 934 | _ = operand_cond_br.else_block.stealCapacity(3); | ||
| 935 | break :res_elem_br Air.internedToRef(ct_elems.keys()[0]); | ||
| 936 | }, | ||
| 937 | } }, | ||
| 938 | }); | ||
| 939 | def_cond_br.else_block = .init(operand_cond_br.else_block.stealRemainingCapacity()); | ||
| 940 | try operand_cond_br.finish(l); | ||
| 941 | } else { | ||
| 942 | def_cond_br.then_block = operand_cond_br.then_block; | ||
| 943 | _ = def_cond_br.then_block.stealCapacity(6); | ||
| 944 | def_cond_br.else_block = .init(def_cond_br.then_block.stealRemainingCapacity()); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | _ = def_cond_br.else_block.add(l, .{ | ||
| 948 | .tag = .br, | ||
| 949 | .data = .{ .br = .{ | ||
| 950 | .block_inst = res_elem.inst, | ||
| 951 | .operand = try pt.undefRef(elem_ty), | ||
| 952 | } }, | ||
| 953 | }); | ||
| 954 | try def_cond_br.finish(l); | ||
| 955 | } | ||
| 956 | try res_elem.finish(l); | ||
| 957 | break :res_elem res_elem.inst.toRef(); | ||
| 958 | }, | ||
| 959 | .select => { | ||
| 960 | const extra = l.extraData(Air.Bin, orig.data.pl_op.payload).data; | ||
| 961 | var res_elem: Result = .init(l, l.typeOf(extra.lhs).childType(zcu), &loop.block); | ||
| 962 | res_elem.block = .init(loop.block.stealCapacity(extra_insts)); | ||
| 963 | { | ||
| 964 | var select_cond_br: CondBr = .init(l, res_elem.block.add(l, .{ | ||
| 965 | .tag = .array_elem_val, | ||
| 966 | .data = .{ .bin_op = .{ | ||
| 967 | .lhs = orig.data.pl_op.operand, | ||
| 968 | .rhs = cur_index_inst.toRef(), | ||
| 969 | } }, | ||
| 970 | }).toRef(), &res_elem.block, .{}); | ||
| 971 | select_cond_br.then_block = .init(res_elem.block.stealRemainingCapacity()); | ||
| 972 | _ = select_cond_br.then_block.add(l, .{ | ||
| 973 | .tag = .br, | ||
| 974 | .data = .{ .br = .{ | ||
| 975 | .block_inst = res_elem.inst, | ||
| 976 | .operand = select_cond_br.then_block.add(l, .{ | ||
| 977 | .tag = .array_elem_val, | ||
| 978 | .data = .{ .bin_op = .{ | ||
| 979 | .lhs = extra.lhs, | ||
| 980 | .rhs = cur_index_inst.toRef(), | ||
| 981 | } }, | ||
| 982 | }).toRef(), | ||
| 983 | } }, | ||
| 984 | }); | ||
| 985 | select_cond_br.else_block = .init(select_cond_br.then_block.stealRemainingCapacity()); | ||
| 986 | _ = select_cond_br.else_block.add(l, .{ | ||
| 987 | .tag = .br, | ||
| 988 | .data = .{ .br = .{ | ||
| 989 | .block_inst = res_elem.inst, | ||
| 990 | .operand = select_cond_br.else_block.add(l, .{ | ||
| 991 | .tag = .array_elem_val, | ||
| 992 | .data = .{ .bin_op = .{ | ||
| 993 | .lhs = extra.rhs, | ||
| 994 | .rhs = cur_index_inst.toRef(), | ||
| 995 | } }, | ||
| 996 | }).toRef(), | ||
| 997 | } }, | ||
| 998 | }); | ||
| 999 | try select_cond_br.finish(l); | ||
| 1000 | } | ||
| 1001 | try res_elem.finish(l); | ||
| 1002 | break :res_elem res_elem.inst.toRef(); | ||
| 1003 | }, | ||
| 1004 | }, | ||
| 1005 | }), | ||
| 1006 | } }, | ||
| 1007 | }); | ||
| 1008 | |||
| 1009 | var loop_cond_br: CondBr = .init(l, (try loop.block.addCmp( | ||
| 1010 | l, | ||
| 1011 | .lt, | ||
| 1012 | cur_index_inst.toRef(), | ||
| 1013 | try pt.intRef(.usize, res_len - 1), | ||
| 1014 | .{}, | ||
| 1015 | )).toRef(), &loop.block, .{}); | ||
| 1016 | loop_cond_br.then_block = .init(loop.block.stealRemainingCapacity()); | ||
| 1017 | { | ||
| 1018 | _ = loop_cond_br.then_block.add(l, .{ | ||
| 1019 | .tag = .store, | ||
| 1020 | .data = .{ .bin_op = .{ | ||
| 1021 | .lhs = index_alloc_inst.toRef(), | ||
| 1022 | .rhs = loop_cond_br.then_block.add(l, .{ | ||
| 1023 | .tag = .add, | ||
| 1024 | .data = .{ .bin_op = .{ | ||
| 1025 | .lhs = cur_index_inst.toRef(), | ||
| 1026 | .rhs = .one_usize, | ||
| 1027 | } }, | ||
| 1028 | }).toRef(), | ||
| 1029 | } }, | ||
| 1030 | }); | ||
| 1031 | _ = loop_cond_br.then_block.add(l, .{ | ||
| 1032 | .tag = .repeat, | ||
| 1033 | .data = .{ .repeat = .{ .loop_inst = loop.inst } }, | ||
| 1034 | }); | ||
| 80 | } | 1035 | } |
| 81 | }, | 1036 | loop_cond_br.else_block = .init(loop_cond_br.then_block.stealRemainingCapacity()); |
| 82 | 1037 | _ = loop_cond_br.else_block.add(l, .{ | |
| 83 | .reduce, | 1038 | .tag = .br, |
| 84 | .reduce_optimized, | 1039 | .data = .{ .br = .{ |
| 85 | => if (l.features.contains(.reduce_one_elem_to_bitcast)) done: { | 1040 | .block_inst = orig_inst, |
| 86 | const reduce = data[@intFromEnum(inst)].reduce; | 1041 | .operand = loop_cond_br.else_block.add(l, .{ |
| 87 | const vector_ty = l.air.typeOf(reduce.operand, ip); | 1042 | .tag = .load, |
| 88 | switch (vector_ty.vectorLen(zcu)) { | 1043 | .data = .{ .ty_op = .{ |
| 89 | 0 => unreachable, | 1044 | .ty = Air.internedToRef(res_ty.toIntern()), |
| 90 | 1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{ | 1045 | .operand = res_alloc_inst.toRef(), |
| 91 | .ty = Air.internedToRef(vector_ty.scalarType(zcu).toIntern()), | 1046 | } }, |
| 92 | .operand = reduce.operand, | 1047 | }).toRef(), |
| 93 | } }), | 1048 | } }, |
| 94 | else => break :done, | 1049 | }); |
| 1050 | try loop_cond_br.finish(l); | ||
| 1051 | } | ||
| 1052 | try loop.finish(l); | ||
| 1053 | } | ||
| 1054 | return .{ .ty_pl = .{ | ||
| 1055 | .ty = Air.internedToRef(res_ty.toIntern()), | ||
| 1056 | .payload = try l.addBlockBody(res_block.body()), | ||
| 1057 | } }; | ||
| 1058 | } | ||
| 1059 | fn scalarizeOverflowBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data { | ||
| 1060 | const pt = l.pt; | ||
| 1061 | const zcu = pt.zcu; | ||
| 1062 | |||
| 1063 | const orig = l.air_instructions.get(@intFromEnum(orig_inst)); | ||
| 1064 | const res_ty = l.typeOfIndex(orig_inst); | ||
| 1065 | const wrapped_res_ty = res_ty.fieldType(0, zcu); | ||
| 1066 | const wrapped_res_scalar_ty = wrapped_res_ty.childType(zcu); | ||
| 1067 | const res_len = wrapped_res_ty.vectorLen(zcu); | ||
| 1068 | |||
| 1069 | var inst_buf: [21]Air.Inst.Index = undefined; | ||
| 1070 | try l.air_instructions.ensureUnusedCapacity(zcu.gpa, inst_buf.len); | ||
| 1071 | |||
| 1072 | var res_block: Block = .init(&inst_buf); | ||
| 1073 | { | ||
| 1074 | const res_alloc_inst = res_block.add(l, .{ | ||
| 1075 | .tag = .alloc, | ||
| 1076 | .data = .{ .ty = try pt.singleMutPtrType(res_ty) }, | ||
| 1077 | }); | ||
| 1078 | const ptr_wrapped_res_inst = res_block.add(l, .{ | ||
| 1079 | .tag = .struct_field_ptr_index_0, | ||
| 1080 | .data = .{ .ty_op = .{ | ||
| 1081 | .ty = Air.internedToRef((try pt.singleMutPtrType(wrapped_res_ty)).toIntern()), | ||
| 1082 | .operand = res_alloc_inst.toRef(), | ||
| 1083 | } }, | ||
| 1084 | }); | ||
| 1085 | const ptr_overflow_res_inst = res_block.add(l, .{ | ||
| 1086 | .tag = .struct_field_ptr_index_1, | ||
| 1087 | .data = .{ .ty_op = .{ | ||
| 1088 | .ty = Air.internedToRef((try pt.singleMutPtrType(res_ty.fieldType(1, zcu))).toIntern()), | ||
| 1089 | .operand = res_alloc_inst.toRef(), | ||
| 1090 | } }, | ||
| 1091 | }); | ||
| 1092 | const index_alloc_inst = res_block.add(l, .{ | ||
| 1093 | .tag = .alloc, | ||
| 1094 | .data = .{ .ty = .ptr_usize }, | ||
| 1095 | }); | ||
| 1096 | _ = res_block.add(l, .{ | ||
| 1097 | .tag = .store, | ||
| 1098 | .data = .{ .bin_op = .{ | ||
| 1099 | .lhs = index_alloc_inst.toRef(), | ||
| 1100 | .rhs = .zero_usize, | ||
| 1101 | } }, | ||
| 1102 | }); | ||
| 1103 | |||
| 1104 | var loop: Loop = .init(l, &res_block); | ||
| 1105 | loop.block = .init(res_block.stealRemainingCapacity()); | ||
| 1106 | { | ||
| 1107 | const cur_index_inst = loop.block.add(l, .{ | ||
| 1108 | .tag = .load, | ||
| 1109 | .data = .{ .ty_op = .{ | ||
| 1110 | .ty = .usize_type, | ||
| 1111 | .operand = index_alloc_inst.toRef(), | ||
| 1112 | } }, | ||
| 1113 | }); | ||
| 1114 | const extra = l.extraData(Air.Bin, orig.data.ty_pl.payload).data; | ||
| 1115 | const res_elem = loop.block.add(l, .{ | ||
| 1116 | .tag = orig.tag, | ||
| 1117 | .data = .{ .ty_pl = .{ | ||
| 1118 | .ty = Air.internedToRef(try zcu.intern_pool.getTupleType(zcu.gpa, pt.tid, .{ | ||
| 1119 | .types = &.{ wrapped_res_scalar_ty.toIntern(), .u1_type }, | ||
| 1120 | .values = &(.{.none} ** 2), | ||
| 1121 | })), | ||
| 1122 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 1123 | .lhs = loop.block.add(l, .{ | ||
| 1124 | .tag = .array_elem_val, | ||
| 1125 | .data = .{ .bin_op = .{ | ||
| 1126 | .lhs = extra.lhs, | ||
| 1127 | .rhs = cur_index_inst.toRef(), | ||
| 1128 | } }, | ||
| 1129 | }).toRef(), | ||
| 1130 | .rhs = loop.block.add(l, .{ | ||
| 1131 | .tag = .array_elem_val, | ||
| 1132 | .data = .{ .bin_op = .{ | ||
| 1133 | .lhs = extra.rhs, | ||
| 1134 | .rhs = cur_index_inst.toRef(), | ||
| 1135 | } }, | ||
| 1136 | }).toRef(), | ||
| 1137 | }), | ||
| 1138 | } }, | ||
| 1139 | }); | ||
| 1140 | _ = loop.block.add(l, .{ | ||
| 1141 | .tag = .vector_store_elem, | ||
| 1142 | .data = .{ .vector_store_elem = .{ | ||
| 1143 | .vector_ptr = ptr_overflow_res_inst.toRef(), | ||
| 1144 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 1145 | .lhs = cur_index_inst.toRef(), | ||
| 1146 | .rhs = loop.block.add(l, .{ | ||
| 1147 | .tag = .struct_field_val, | ||
| 1148 | .data = .{ .ty_pl = .{ | ||
| 1149 | .ty = .u1_type, | ||
| 1150 | .payload = try l.addExtra(Air.StructField, .{ | ||
| 1151 | .struct_operand = res_elem.toRef(), | ||
| 1152 | .field_index = 1, | ||
| 1153 | }), | ||
| 1154 | } }, | ||
| 1155 | }).toRef(), | ||
| 1156 | }), | ||
| 1157 | } }, | ||
| 1158 | }); | ||
| 1159 | _ = loop.block.add(l, .{ | ||
| 1160 | .tag = .vector_store_elem, | ||
| 1161 | .data = .{ .vector_store_elem = .{ | ||
| 1162 | .vector_ptr = ptr_wrapped_res_inst.toRef(), | ||
| 1163 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 1164 | .lhs = cur_index_inst.toRef(), | ||
| 1165 | .rhs = loop.block.add(l, .{ | ||
| 1166 | .tag = .struct_field_val, | ||
| 1167 | .data = .{ .ty_pl = .{ | ||
| 1168 | .ty = Air.internedToRef(wrapped_res_scalar_ty.toIntern()), | ||
| 1169 | .payload = try l.addExtra(Air.StructField, .{ | ||
| 1170 | .struct_operand = res_elem.toRef(), | ||
| 1171 | .field_index = 0, | ||
| 1172 | }), | ||
| 1173 | } }, | ||
| 1174 | }).toRef(), | ||
| 1175 | }), | ||
| 1176 | } }, | ||
| 1177 | }); | ||
| 1178 | |||
| 1179 | var loop_cond_br: CondBr = .init(l, (try loop.block.addCmp( | ||
| 1180 | l, | ||
| 1181 | .lt, | ||
| 1182 | cur_index_inst.toRef(), | ||
| 1183 | try pt.intRef(.usize, res_len - 1), | ||
| 1184 | .{}, | ||
| 1185 | )).toRef(), &loop.block, .{}); | ||
| 1186 | loop_cond_br.then_block = .init(loop.block.stealRemainingCapacity()); | ||
| 1187 | { | ||
| 1188 | _ = loop_cond_br.then_block.add(l, .{ | ||
| 1189 | .tag = .store, | ||
| 1190 | .data = .{ .bin_op = .{ | ||
| 1191 | .lhs = index_alloc_inst.toRef(), | ||
| 1192 | .rhs = loop_cond_br.then_block.add(l, .{ | ||
| 1193 | .tag = .add, | ||
| 1194 | .data = .{ .bin_op = .{ | ||
| 1195 | .lhs = cur_index_inst.toRef(), | ||
| 1196 | .rhs = .one_usize, | ||
| 1197 | } }, | ||
| 1198 | }).toRef(), | ||
| 1199 | } }, | ||
| 1200 | }); | ||
| 1201 | _ = loop_cond_br.then_block.add(l, .{ | ||
| 1202 | .tag = .repeat, | ||
| 1203 | .data = .{ .repeat = .{ .loop_inst = loop.inst } }, | ||
| 1204 | }); | ||
| 95 | } | 1205 | } |
| 96 | }, | 1206 | loop_cond_br.else_block = .init(loop_cond_br.then_block.stealRemainingCapacity()); |
| 97 | 1207 | _ = loop_cond_br.else_block.add(l, .{ | |
| 98 | .@"try", .try_cold => { | 1208 | .tag = .br, |
| 99 | const pl_op = data[@intFromEnum(inst)].pl_op; | 1209 | .data = .{ .br = .{ |
| 100 | const extra = l.air.extraData(Air.Try, pl_op.payload); | 1210 | .block_inst = orig_inst, |
| 101 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len])); | 1211 | .operand = loop_cond_br.else_block.add(l, .{ |
| 102 | }, | 1212 | .tag = .load, |
| 103 | .try_ptr, .try_ptr_cold => { | 1213 | .data = .{ .ty_op = .{ |
| 104 | const ty_pl = data[@intFromEnum(inst)].ty_pl; | 1214 | .ty = Air.internedToRef(res_ty.toIntern()), |
| 105 | const extra = l.air.extraData(Air.TryPtr, ty_pl.payload); | 1215 | .operand = res_alloc_inst.toRef(), |
| 106 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len])); | 1216 | } }, |
| 107 | }, | 1217 | }).toRef(), |
| 108 | .block, .loop => { | 1218 | } }, |
| 109 | const ty_pl = data[@intFromEnum(inst)].ty_pl; | 1219 | }); |
| 110 | const extra = l.air.extraData(Air.Block, ty_pl.payload); | 1220 | try loop_cond_br.finish(l); |
| 111 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len])); | 1221 | } |
| 112 | }, | 1222 | try loop.finish(l); |
| 113 | .dbg_inline_block => { | 1223 | } |
| 114 | const ty_pl = data[@intFromEnum(inst)].ty_pl; | 1224 | return .{ .ty_pl = .{ |
| 115 | const extra = l.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 1225 | .ty = Air.internedToRef(res_ty.toIntern()), |
| 116 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len])); | 1226 | .payload = try l.addBlockBody(res_block.body()), |
| 117 | }, | 1227 | } }; |
| 118 | .cond_br => { | 1228 | } |
| 119 | const pl_op = data[@intFromEnum(inst)].pl_op; | 1229 | |
| 120 | const extra = l.air.extraData(Air.CondBr, pl_op.payload); | 1230 | fn safeIntcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data { |
| 121 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.then_body_len])); | 1231 | const pt = l.pt; |
| 122 | try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end + extra.data.then_body_len ..][0..extra.data.else_body_len])); | 1232 | const zcu = pt.zcu; |
| 123 | }, | 1233 | const ty_op = l.air_instructions.items(.data)[@intFromEnum(orig_inst)].ty_op; |
| 124 | .switch_br, .loop_switch_br => { | 1234 | |
| 125 | const switch_br = l.air.unwrapSwitch(inst); | 1235 | const operand_ref = ty_op.operand; |
| 126 | var it = switch_br.iterateCases(); | 1236 | const operand_ty = l.typeOf(operand_ref); |
| 127 | while (it.next()) |case| try l.legalizeBody(case.body); | 1237 | const dest_ty = ty_op.ty.toType(); |
| 128 | try l.legalizeBody(it.elseBody()); | 1238 | |
| 129 | }, | 1239 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 1240 | const operand_scalar_ty = operand_ty.scalarType(zcu); | ||
| 1241 | const dest_scalar_ty = dest_ty.scalarType(zcu); | ||
| 1242 | |||
| 1243 | assert(operand_scalar_ty.zigTypeTag(zcu) == .int); | ||
| 1244 | const dest_is_enum = switch (dest_scalar_ty.zigTypeTag(zcu)) { | ||
| 1245 | .int => false, | ||
| 1246 | .@"enum" => true, | ||
| 1247 | else => unreachable, | ||
| 1248 | }; | ||
| 1249 | |||
| 1250 | const operand_info = operand_scalar_ty.intInfo(zcu); | ||
| 1251 | const dest_info = dest_scalar_ty.intInfo(zcu); | ||
| 1252 | |||
| 1253 | const have_min_check, const have_max_check = c: { | ||
| 1254 | const dest_pos_bits = dest_info.bits - @intFromBool(dest_info.signedness == .signed); | ||
| 1255 | const operand_pos_bits = operand_info.bits - @intFromBool(operand_info.signedness == .signed); | ||
| 1256 | const dest_allows_neg = dest_info.signedness == .signed and dest_info.bits > 0; | ||
| 1257 | const operand_allows_neg = operand_info.signedness == .signed and operand_info.bits > 0; | ||
| 1258 | break :c .{ | ||
| 1259 | operand_allows_neg and (!dest_allows_neg or dest_info.bits < operand_info.bits), | ||
| 1260 | dest_pos_bits < operand_pos_bits, | ||
| 1261 | }; | ||
| 130 | }; | 1262 | }; |
| 1263 | |||
| 1264 | // The worst-case scenario in terms of total instructions and total condbrs is the case where | ||
| 1265 | // the result type is an exhaustive enum whose tag type is smaller than the operand type: | ||
| 1266 | // | ||
| 1267 | // %x = block({ | ||
| 1268 | // %1 = cmp_lt(%y, @min_allowed_int) | ||
| 1269 | // %2 = cmp_gt(%y, @max_allowed_int) | ||
| 1270 | // %3 = bool_or(%1, %2) | ||
| 1271 | // %4 = cond_br(%3, { | ||
| 1272 | // %5 = call(@panic.invalidEnumValue, []) | ||
| 1273 | // %6 = unreach() | ||
| 1274 | // }, { | ||
| 1275 | // %7 = intcast(@res_ty, %y) | ||
| 1276 | // %8 = is_named_enum_value(%7) | ||
| 1277 | // %9 = cond_br(%8, { | ||
| 1278 | // %10 = br(%x, %7) | ||
| 1279 | // }, { | ||
| 1280 | // %11 = call(@panic.invalidEnumValue, []) | ||
| 1281 | // %12 = unreach() | ||
| 1282 | // }) | ||
| 1283 | // }) | ||
| 1284 | // }) | ||
| 1285 | // | ||
| 1286 | // Note that vectors of enums don't exist -- the worst case for vectors is this: | ||
| 1287 | // | ||
| 1288 | // %x = block({ | ||
| 1289 | // %1 = cmp_lt(%y, @min_allowed_int) | ||
| 1290 | // %2 = cmp_gt(%y, @max_allowed_int) | ||
| 1291 | // %3 = bool_or(%1, %2) | ||
| 1292 | // %4 = reduce(%3, .@"or") | ||
| 1293 | // %5 = cond_br(%4, { | ||
| 1294 | // %6 = call(@panic.invalidEnumValue, []) | ||
| 1295 | // %7 = unreach() | ||
| 1296 | // }, { | ||
| 1297 | // %8 = intcast(@res_ty, %y) | ||
| 1298 | // %9 = br(%x, %8) | ||
| 1299 | // }) | ||
| 1300 | // }) | ||
| 1301 | |||
| 1302 | var inst_buf: [12]Air.Inst.Index = undefined; | ||
| 1303 | try l.air_instructions.ensureUnusedCapacity(zcu.gpa, inst_buf.len); | ||
| 1304 | var condbr_buf: [2]CondBr = undefined; | ||
| 1305 | var condbr_idx: usize = 0; | ||
| 1306 | |||
| 1307 | var main_block: Block = .init(&inst_buf); | ||
| 1308 | var cur_block: *Block = &main_block; | ||
| 1309 | |||
| 1310 | const panic_id: Zcu.SimplePanicId = if (dest_is_enum) .invalid_enum_value else .integer_out_of_bounds; | ||
| 1311 | |||
| 1312 | if (have_min_check or have_max_check) { | ||
| 1313 | const dest_int_ty = if (dest_is_enum) dest_ty.intTagType(zcu) else dest_ty; | ||
| 1314 | const condbr = &condbr_buf[condbr_idx]; | ||
| 1315 | condbr_idx += 1; | ||
| 1316 | const below_min_inst: Air.Inst.Index = if (have_min_check) inst: { | ||
| 1317 | const min_val_ref = Air.internedToRef((try dest_int_ty.minInt(pt, operand_ty)).toIntern()); | ||
| 1318 | break :inst try cur_block.addCmp(l, .lt, operand_ref, min_val_ref, .{ .vector = is_vector }); | ||
| 1319 | } else undefined; | ||
| 1320 | const above_max_inst: Air.Inst.Index = if (have_max_check) inst: { | ||
| 1321 | const max_val_ref = Air.internedToRef((try dest_int_ty.maxInt(pt, operand_ty)).toIntern()); | ||
| 1322 | break :inst try cur_block.addCmp(l, .gt, operand_ref, max_val_ref, .{ .vector = is_vector }); | ||
| 1323 | } else undefined; | ||
| 1324 | const out_of_range_inst: Air.Inst.Index = inst: { | ||
| 1325 | if (have_min_check and have_max_check) break :inst cur_block.add(l, .{ | ||
| 1326 | .tag = .bool_or, | ||
| 1327 | .data = .{ .bin_op = .{ | ||
| 1328 | .lhs = below_min_inst.toRef(), | ||
| 1329 | .rhs = above_max_inst.toRef(), | ||
| 1330 | } }, | ||
| 1331 | }); | ||
| 1332 | if (have_min_check) break :inst below_min_inst; | ||
| 1333 | if (have_max_check) break :inst above_max_inst; | ||
| 1334 | unreachable; | ||
| 1335 | }; | ||
| 1336 | const scalar_out_of_range_inst: Air.Inst.Index = if (is_vector) cur_block.add(l, .{ | ||
| 1337 | .tag = .reduce, | ||
| 1338 | .data = .{ .reduce = .{ | ||
| 1339 | .operand = out_of_range_inst.toRef(), | ||
| 1340 | .operation = .Or, | ||
| 1341 | } }, | ||
| 1342 | }) else out_of_range_inst; | ||
| 1343 | condbr.* = .init(l, scalar_out_of_range_inst.toRef(), cur_block, .{ .true = .cold }); | ||
| 1344 | condbr.then_block = .init(cur_block.stealRemainingCapacity()); | ||
| 1345 | try condbr.then_block.addPanic(l, panic_id); | ||
| 1346 | condbr.else_block = .init(condbr.then_block.stealRemainingCapacity()); | ||
| 1347 | cur_block = &condbr.else_block; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | // Now we know we're in-range, we can intcast: | ||
| 1351 | const cast_inst = cur_block.add(l, .{ | ||
| 1352 | .tag = .intcast, | ||
| 1353 | .data = .{ .ty_op = .{ | ||
| 1354 | .ty = Air.internedToRef(dest_ty.toIntern()), | ||
| 1355 | .operand = operand_ref, | ||
| 1356 | } }, | ||
| 1357 | }); | ||
| 1358 | // For ints we're already done, but for exhaustive enums we must check this is a valid tag. | ||
| 1359 | if (dest_is_enum and !dest_ty.isNonexhaustiveEnum(zcu) and zcu.backendSupportsFeature(.is_named_enum_value)) { | ||
| 1360 | assert(!is_vector); // vectors of enums don't exist | ||
| 1361 | // We are building this: | ||
| 1362 | // %1 = is_named_enum_value(%cast_inst) | ||
| 1363 | // %2 = cond_br(%1, { | ||
| 1364 | // <new cursor> | ||
| 1365 | // }, { | ||
| 1366 | // <panic> | ||
| 1367 | // }) | ||
| 1368 | const is_named_inst = cur_block.add(l, .{ | ||
| 1369 | .tag = .is_named_enum_value, | ||
| 1370 | .data = .{ .un_op = cast_inst.toRef() }, | ||
| 1371 | }); | ||
| 1372 | const condbr = &condbr_buf[condbr_idx]; | ||
| 1373 | condbr_idx += 1; | ||
| 1374 | condbr.* = .init(l, is_named_inst.toRef(), cur_block, .{ .false = .cold }); | ||
| 1375 | condbr.else_block = .init(cur_block.stealRemainingCapacity()); | ||
| 1376 | try condbr.else_block.addPanic(l, panic_id); | ||
| 1377 | condbr.then_block = .init(condbr.else_block.stealRemainingCapacity()); | ||
| 1378 | cur_block = &condbr.then_block; | ||
| 1379 | } | ||
| 1380 | // Finally, just `br` to our outer `block`. | ||
| 1381 | _ = cur_block.add(l, .{ | ||
| 1382 | .tag = .br, | ||
| 1383 | .data = .{ .br = .{ | ||
| 1384 | .block_inst = orig_inst, | ||
| 1385 | .operand = cast_inst.toRef(), | ||
| 1386 | } }, | ||
| 1387 | }); | ||
| 1388 | // We might not have used all of the instructions; that's intentional. | ||
| 1389 | _ = cur_block.stealRemainingCapacity(); | ||
| 1390 | |||
| 1391 | for (condbr_buf[0..condbr_idx]) |*condbr| try condbr.finish(l); | ||
| 1392 | return .{ .ty_pl = .{ | ||
| 1393 | .ty = Air.internedToRef(dest_ty.toIntern()), | ||
| 1394 | .payload = try l.addBlockBody(main_block.body()), | ||
| 1395 | } }; | ||
| 1396 | } | ||
| 1397 | fn safeArithmeticBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, overflow_op_tag: Air.Inst.Tag) Error!Air.Inst.Data { | ||
| 1398 | const pt = l.pt; | ||
| 1399 | const zcu = pt.zcu; | ||
| 1400 | const bin_op = l.air_instructions.items(.data)[@intFromEnum(orig_inst)].bin_op; | ||
| 1401 | |||
| 1402 | const operand_ty = l.typeOf(bin_op.lhs); | ||
| 1403 | assert(l.typeOf(bin_op.rhs).toIntern() == operand_ty.toIntern()); | ||
| 1404 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; | ||
| 1405 | |||
| 1406 | const overflow_tuple_ty = try pt.overflowArithmeticTupleType(operand_ty); | ||
| 1407 | const overflow_bits_ty = overflow_tuple_ty.fieldType(1, zcu); | ||
| 1408 | |||
| 1409 | // The worst-case scenario is a vector operand: | ||
| 1410 | // | ||
| 1411 | // %1 = add_with_overflow(%x, %y) | ||
| 1412 | // %2 = struct_field_val(%1, .@"1") | ||
| 1413 | // %3 = reduce(%2, .@"or") | ||
| 1414 | // %4 = bitcast(%3, @bool_type) | ||
| 1415 | // %5 = cond_br(%4, { | ||
| 1416 | // %6 = call(@panic.integerOverflow, []) | ||
| 1417 | // %7 = unreach() | ||
| 1418 | // }, { | ||
| 1419 | // %8 = struct_field_val(%1, .@"0") | ||
| 1420 | // %9 = br(%z, %8) | ||
| 1421 | // }) | ||
| 1422 | var inst_buf: [9]Air.Inst.Index = undefined; | ||
| 1423 | try l.air_instructions.ensureUnusedCapacity(zcu.gpa, inst_buf.len); | ||
| 1424 | |||
| 1425 | var main_block: Block = .init(&inst_buf); | ||
| 1426 | |||
| 1427 | const overflow_op_inst = main_block.add(l, .{ | ||
| 1428 | .tag = overflow_op_tag, | ||
| 1429 | .data = .{ .ty_pl = .{ | ||
| 1430 | .ty = Air.internedToRef(overflow_tuple_ty.toIntern()), | ||
| 1431 | .payload = try l.addExtra(Air.Bin, .{ | ||
| 1432 | .lhs = bin_op.lhs, | ||
| 1433 | .rhs = bin_op.rhs, | ||
| 1434 | }), | ||
| 1435 | } }, | ||
| 1436 | }); | ||
| 1437 | const overflow_bits_inst = main_block.add(l, .{ | ||
| 1438 | .tag = .struct_field_val, | ||
| 1439 | .data = .{ .ty_pl = .{ | ||
| 1440 | .ty = Air.internedToRef(overflow_bits_ty.toIntern()), | ||
| 1441 | .payload = try l.addExtra(Air.StructField, .{ | ||
| 1442 | .struct_operand = overflow_op_inst.toRef(), | ||
| 1443 | .field_index = 1, | ||
| 1444 | }), | ||
| 1445 | } }, | ||
| 1446 | }); | ||
| 1447 | const any_overflow_bit_inst = if (is_vector) main_block.add(l, .{ | ||
| 1448 | .tag = .reduce, | ||
| 1449 | .data = .{ .reduce = .{ | ||
| 1450 | .operand = overflow_bits_inst.toRef(), | ||
| 1451 | .operation = .Or, | ||
| 1452 | } }, | ||
| 1453 | }) else overflow_bits_inst; | ||
| 1454 | const any_overflow_inst = try main_block.addCmp(l, .eq, any_overflow_bit_inst.toRef(), .one_u1, .{}); | ||
| 1455 | |||
| 1456 | var condbr: CondBr = .init(l, any_overflow_inst.toRef(), &main_block, .{ .true = .cold }); | ||
| 1457 | condbr.then_block = .init(main_block.stealRemainingCapacity()); | ||
| 1458 | try condbr.then_block.addPanic(l, .integer_overflow); | ||
| 1459 | condbr.else_block = .init(condbr.then_block.stealRemainingCapacity()); | ||
| 1460 | |||
| 1461 | const result_inst = condbr.else_block.add(l, .{ | ||
| 1462 | .tag = .struct_field_val, | ||
| 1463 | .data = .{ .ty_pl = .{ | ||
| 1464 | .ty = Air.internedToRef(operand_ty.toIntern()), | ||
| 1465 | .payload = try l.addExtra(Air.StructField, .{ | ||
| 1466 | .struct_operand = overflow_op_inst.toRef(), | ||
| 1467 | .field_index = 0, | ||
| 1468 | }), | ||
| 1469 | } }, | ||
| 1470 | }); | ||
| 1471 | _ = condbr.else_block.add(l, .{ | ||
| 1472 | .tag = .br, | ||
| 1473 | .data = .{ .br = .{ | ||
| 1474 | .block_inst = orig_inst, | ||
| 1475 | .operand = result_inst.toRef(), | ||
| 1476 | } }, | ||
| 1477 | }); | ||
| 1478 | // We might not have used all of the instructions; that's intentional. | ||
| 1479 | _ = condbr.else_block.stealRemainingCapacity(); | ||
| 1480 | |||
| 1481 | try condbr.finish(l); | ||
| 1482 | return .{ .ty_pl = .{ | ||
| 1483 | .ty = Air.internedToRef(operand_ty.toIntern()), | ||
| 1484 | .payload = try l.addBlockBody(main_block.body()), | ||
| 1485 | } }; | ||
| 1486 | } | ||
| 1487 | |||
| 1488 | const Block = struct { | ||
| 1489 | instructions: []Air.Inst.Index, | ||
| 1490 | len: usize, | ||
| 1491 | |||
| 1492 | /// There are two common usages of the API: | ||
| 1493 | /// * `buf.len` is exactly the number of instructions which will be in this block | ||
| 1494 | /// * `buf.len` is no smaller than necessary, and `b.stealRemainingCapacity` will be used | ||
| 1495 | fn init(buf: []Air.Inst.Index) Block { | ||
| 1496 | return .{ | ||
| 1497 | .instructions = buf, | ||
| 1498 | .len = 0, | ||
| 1499 | }; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | /// Like `Legalize.addInstAssumeCapacity`, but also appends the instruction to `b`. | ||
| 1503 | fn add(b: *Block, l: *Legalize, inst_data: Air.Inst) Air.Inst.Index { | ||
| 1504 | const inst = l.addInstAssumeCapacity(inst_data); | ||
| 1505 | b.instructions[b.len] = inst; | ||
| 1506 | b.len += 1; | ||
| 1507 | return inst; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | /// Adds the code to call the panic handler `panic_id`. This is usually `.call` then `.unreach`, | ||
| 1511 | /// but if `Zcu.Feature.panic_fn` is unsupported, we lower to `.trap` instead. | ||
| 1512 | fn addPanic(b: *Block, l: *Legalize, panic_id: Zcu.SimplePanicId) Error!void { | ||
| 1513 | const zcu = l.pt.zcu; | ||
| 1514 | if (!zcu.backendSupportsFeature(.panic_fn)) { | ||
| 1515 | _ = b.add(l, .{ | ||
| 1516 | .tag = .trap, | ||
| 1517 | .data = .{ .no_op = {} }, | ||
| 1518 | }); | ||
| 1519 | return; | ||
| 1520 | } | ||
| 1521 | const panic_fn_val = zcu.builtin_decl_values.get(panic_id.toBuiltin()); | ||
| 1522 | _ = b.add(l, .{ | ||
| 1523 | .tag = .call, | ||
| 1524 | .data = .{ .pl_op = .{ | ||
| 1525 | .operand = Air.internedToRef(panic_fn_val), | ||
| 1526 | .payload = try l.addExtra(Air.Call, .{ .args_len = 0 }), | ||
| 1527 | } }, | ||
| 1528 | }); | ||
| 1529 | _ = b.add(l, .{ | ||
| 1530 | .tag = .unreach, | ||
| 1531 | .data = .{ .no_op = {} }, | ||
| 1532 | }); | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | /// Adds a `cmp_*` instruction (including maybe `cmp_vector`) to `b`. This is a fairly thin wrapper | ||
| 1536 | /// around `add`, although it does compute the result type if `is_vector` (`@Vector(n, bool)`). | ||
| 1537 | fn addCmp( | ||
| 1538 | b: *Block, | ||
| 1539 | l: *Legalize, | ||
| 1540 | op: std.math.CompareOperator, | ||
| 1541 | lhs: Air.Inst.Ref, | ||
| 1542 | rhs: Air.Inst.Ref, | ||
| 1543 | opts: struct { optimized: bool = false, vector: bool = false }, | ||
| 1544 | ) Error!Air.Inst.Index { | ||
| 1545 | const pt = l.pt; | ||
| 1546 | if (opts.vector) { | ||
| 1547 | const bool_vec_ty = try pt.vectorType(.{ | ||
| 1548 | .child = .bool_type, | ||
| 1549 | .len = l.typeOf(lhs).vectorLen(pt.zcu), | ||
| 1550 | }); | ||
| 1551 | return b.add(l, .{ | ||
| 1552 | .tag = if (opts.optimized) .cmp_vector_optimized else .cmp_vector, | ||
| 1553 | .data = .{ .ty_pl = .{ | ||
| 1554 | .ty = Air.internedToRef(bool_vec_ty.toIntern()), | ||
| 1555 | .payload = try l.addExtra(Air.VectorCmp, .{ | ||
| 1556 | .lhs = lhs, | ||
| 1557 | .rhs = rhs, | ||
| 1558 | .op = Air.VectorCmp.encodeOp(op), | ||
| 1559 | }), | ||
| 1560 | } }, | ||
| 1561 | }); | ||
| 1562 | } | ||
| 1563 | return b.add(l, .{ | ||
| 1564 | .tag = switch (op) { | ||
| 1565 | .lt => if (opts.optimized) .cmp_lt_optimized else .cmp_lt, | ||
| 1566 | .lte => if (opts.optimized) .cmp_lte_optimized else .cmp_lte, | ||
| 1567 | .eq => if (opts.optimized) .cmp_eq_optimized else .cmp_eq, | ||
| 1568 | .gte => if (opts.optimized) .cmp_gte_optimized else .cmp_gte, | ||
| 1569 | .gt => if (opts.optimized) .cmp_gt_optimized else .cmp_gt, | ||
| 1570 | .neq => if (opts.optimized) .cmp_neq_optimized else .cmp_neq, | ||
| 1571 | }, | ||
| 1572 | .data = .{ .bin_op = .{ | ||
| 1573 | .lhs = lhs, | ||
| 1574 | .rhs = rhs, | ||
| 1575 | } }, | ||
| 1576 | }); | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | /// Returns the unused capacity of `b.instructions`, and shrinks `b.instructions` down to `b.len`. | ||
| 1580 | /// This is useful when you've provided a buffer big enough for all your instructions, but you are | ||
| 1581 | /// now starting a new block and some of them need to live there instead. | ||
| 1582 | fn stealRemainingCapacity(b: *Block) []Air.Inst.Index { | ||
| 1583 | return b.stealFrom(b.len); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | /// Returns `len` elements taken from the unused capacity of `b.instructions`, and shrinks | ||
| 1587 | /// `b.instructions` down to not include them anymore. | ||
| 1588 | /// This is useful when you've provided a buffer big enough for all your instructions, but you are | ||
| 1589 | /// now starting a new block and some of them need to live there instead. | ||
| 1590 | fn stealCapacity(b: *Block, len: usize) []Air.Inst.Index { | ||
| 1591 | return b.stealFrom(b.instructions.len - len); | ||
| 1592 | } | ||
| 1593 | |||
| 1594 | fn stealFrom(b: *Block, start: usize) []Air.Inst.Index { | ||
| 1595 | assert(start >= b.len); | ||
| 1596 | defer b.instructions.len = start; | ||
| 1597 | return b.instructions[start..]; | ||
| 1598 | } | ||
| 1599 | |||
| 1600 | fn body(b: *const Block) []const Air.Inst.Index { | ||
| 1601 | assert(b.len == b.instructions.len); | ||
| 1602 | return b.instructions; | ||
| 1603 | } | ||
| 1604 | }; | ||
| 1605 | |||
| 1606 | const Result = struct { | ||
| 1607 | inst: Air.Inst.Index, | ||
| 1608 | block: Block, | ||
| 1609 | |||
| 1610 | /// The return value has `block` initialized to `undefined`; it is the caller's reponsibility | ||
| 1611 | /// to initialize it. | ||
| 1612 | fn init(l: *Legalize, ty: Type, parent_block: *Block) Result { | ||
| 1613 | return .{ | ||
| 1614 | .inst = parent_block.add(l, .{ | ||
| 1615 | .tag = .block, | ||
| 1616 | .data = .{ .ty_pl = .{ | ||
| 1617 | .ty = Air.internedToRef(ty.toIntern()), | ||
| 1618 | .payload = undefined, | ||
| 1619 | } }, | ||
| 1620 | }), | ||
| 1621 | .block = undefined, | ||
| 1622 | }; | ||
| 1623 | } | ||
| 1624 | |||
| 1625 | fn finish(res: Result, l: *Legalize) Error!void { | ||
| 1626 | const data = &l.air_instructions.items(.data)[@intFromEnum(res.inst)]; | ||
| 1627 | data.ty_pl.payload = try l.addBlockBody(res.block.body()); | ||
| 1628 | } | ||
| 1629 | }; | ||
| 1630 | |||
| 1631 | const Loop = struct { | ||
| 1632 | inst: Air.Inst.Index, | ||
| 1633 | block: Block, | ||
| 1634 | |||
| 1635 | /// The return value has `block` initialized to `undefined`; it is the caller's reponsibility | ||
| 1636 | /// to initialize it. | ||
| 1637 | fn init(l: *Legalize, parent_block: *Block) Loop { | ||
| 1638 | return .{ | ||
| 1639 | .inst = parent_block.add(l, .{ | ||
| 1640 | .tag = .loop, | ||
| 1641 | .data = .{ .ty_pl = .{ | ||
| 1642 | .ty = .noreturn_type, | ||
| 1643 | .payload = undefined, | ||
| 1644 | } }, | ||
| 1645 | }), | ||
| 1646 | .block = undefined, | ||
| 1647 | }; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | fn finish(loop: Loop, l: *Legalize) Error!void { | ||
| 1651 | const data = &l.air_instructions.items(.data)[@intFromEnum(loop.inst)]; | ||
| 1652 | data.ty_pl.payload = try l.addBlockBody(loop.block.body()); | ||
| 1653 | } | ||
| 1654 | }; | ||
| 1655 | |||
| 1656 | const CondBr = struct { | ||
| 1657 | inst: Air.Inst.Index, | ||
| 1658 | hints: Air.CondBr.BranchHints, | ||
| 1659 | then_block: Block, | ||
| 1660 | else_block: Block, | ||
| 1661 | |||
| 1662 | /// The return value has `then_block` and `else_block` initialized to `undefined`; it is the | ||
| 1663 | /// caller's reponsibility to initialize them. | ||
| 1664 | fn init(l: *Legalize, operand: Air.Inst.Ref, parent_block: *Block, hints: Air.CondBr.BranchHints) CondBr { | ||
| 1665 | return .{ | ||
| 1666 | .inst = parent_block.add(l, .{ | ||
| 1667 | .tag = .cond_br, | ||
| 1668 | .data = .{ .pl_op = .{ | ||
| 1669 | .operand = operand, | ||
| 1670 | .payload = undefined, | ||
| 1671 | } }, | ||
| 1672 | }), | ||
| 1673 | .hints = hints, | ||
| 1674 | .then_block = undefined, | ||
| 1675 | .else_block = undefined, | ||
| 1676 | }; | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | fn finish(cond_br: CondBr, l: *Legalize) Error!void { | ||
| 1680 | const then_body = cond_br.then_block.body(); | ||
| 1681 | const else_body = cond_br.else_block.body(); | ||
| 1682 | try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, 3 + then_body.len + else_body.len); | ||
| 1683 | |||
| 1684 | const data = &l.air_instructions.items(.data)[@intFromEnum(cond_br.inst)]; | ||
| 1685 | data.pl_op.payload = @intCast(l.air_extra.items.len); | ||
| 1686 | l.air_extra.appendSliceAssumeCapacity(&.{ | ||
| 1687 | @intCast(then_body.len), | ||
| 1688 | @intCast(else_body.len), | ||
| 1689 | @bitCast(cond_br.hints), | ||
| 1690 | }); | ||
| 1691 | l.air_extra.appendSliceAssumeCapacity(@ptrCast(then_body)); | ||
| 1692 | l.air_extra.appendSliceAssumeCapacity(@ptrCast(else_body)); | ||
| 1693 | } | ||
| 1694 | }; | ||
| 1695 | |||
| 1696 | fn addInstAssumeCapacity(l: *Legalize, inst: Air.Inst) Air.Inst.Index { | ||
| 1697 | defer l.air_instructions.appendAssumeCapacity(inst); | ||
| 1698 | return @enumFromInt(l.air_instructions.len); | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | fn addExtra(l: *Legalize, comptime Extra: type, extra: Extra) Error!u32 { | ||
| 1702 | const extra_fields = @typeInfo(Extra).@"struct".fields; | ||
| 1703 | try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, extra_fields.len); | ||
| 1704 | defer inline for (extra_fields) |field| l.air_extra.appendAssumeCapacity(switch (field.type) { | ||
| 1705 | u32 => @field(extra, field.name), | ||
| 1706 | Air.Inst.Ref => @intFromEnum(@field(extra, field.name)), | ||
| 1707 | else => @compileError(@typeName(field.type)), | ||
| 1708 | }); | ||
| 1709 | return @intCast(l.air_extra.items.len); | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | fn addBlockBody(l: *Legalize, body: []const Air.Inst.Index) Error!u32 { | ||
| 1713 | try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, 1 + body.len); | ||
| 1714 | defer { | ||
| 1715 | l.air_extra.appendAssumeCapacity(@intCast(body.len)); | ||
| 1716 | l.air_extra.appendSliceAssumeCapacity(@ptrCast(body)); | ||
| 1717 | } | ||
| 1718 | return @intCast(l.air_extra.items.len); | ||
| 131 | } | 1719 | } |
| 132 | 1720 | ||
| 133 | // inline to propagate comptime `tag`s | 1721 | /// Returns `tag` to remind the caller to `continue :inst` the result. |
| 134 | inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag { | 1722 | /// This is inline to propagate the comptime-known `tag`. |
| 135 | const ip = &l.zcu.intern_pool; | 1723 | inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, comptime tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag { |
| 136 | const orig_ty = if (std.debug.runtime_safety) l.air.typeOfIndex(inst, ip) else {}; | 1724 | const orig_ty = if (std.debug.runtime_safety) l.typeOfIndex(inst) else {}; |
| 137 | l.air.instructions.items(.tag)[@intFromEnum(inst)] = tag; | 1725 | l.air_instructions.set(@intFromEnum(inst), .{ .tag = tag, .data = data }); |
| 138 | l.air.instructions.items(.data)[@intFromEnum(inst)] = data; | 1726 | if (std.debug.runtime_safety) assert(l.typeOfIndex(inst).toIntern() == orig_ty.toIntern()); |
| 139 | if (std.debug.runtime_safety) std.debug.assert(l.air.typeOfIndex(inst, ip).toIntern() == orig_ty.toIntern()); | ||
| 140 | return tag; | 1727 | return tag; |
| 141 | } | 1728 | } |
| 142 | 1729 | ||
| 143 | const Air = @import("../Air.zig"); | 1730 | const Air = @import("../Air.zig"); |
| 144 | const codegen = @import("../codegen.zig"); | 1731 | const assert = std.debug.assert; |
| 1732 | const dev = @import("../dev.zig"); | ||
| 1733 | const InternPool = @import("../InternPool.zig"); | ||
| 145 | const Legalize = @This(); | 1734 | const Legalize = @This(); |
| 146 | const std = @import("std"); | 1735 | const std = @import("std"); |
| 1736 | const Type = @import("../Type.zig"); | ||
| 147 | const Zcu = @import("../Zcu.zig"); | 1737 | const Zcu = @import("../Zcu.zig"); |
src/Air/Liveness.zig+24-9| ... | @@ -15,6 +15,7 @@ const Liveness = @This(); | ... | @@ -15,6 +15,7 @@ const Liveness = @This(); |
| 15 | const trace = @import("../tracy.zig").trace; | 15 | const trace = @import("../tracy.zig").trace; |
| 16 | const Air = @import("../Air.zig"); | 16 | const Air = @import("../Air.zig"); |
| 17 | const InternPool = @import("../InternPool.zig"); | 17 | const InternPool = @import("../InternPool.zig"); |
| 18 | const Zcu = @import("../Zcu.zig"); | ||
| 18 | 19 | ||
| 19 | pub const Verify = @import("Liveness/Verify.zig"); | 20 | pub const Verify = @import("Liveness/Verify.zig"); |
| 20 | 21 | ||
| ... | @@ -136,12 +137,15 @@ fn LivenessPassData(comptime pass: LivenessPass) type { | ... | @@ -136,12 +137,15 @@ fn LivenessPassData(comptime pass: LivenessPass) type { |
| 136 | }; | 137 | }; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | pub fn analyze(gpa: Allocator, air: Air, intern_pool: *InternPool) Allocator.Error!Liveness { | 140 | pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Liveness { |
| 140 | const tracy = trace(@src()); | 141 | const tracy = trace(@src()); |
| 141 | defer tracy.end(); | 142 | defer tracy.end(); |
| 142 | 143 | ||
| 144 | const gpa = zcu.gpa; | ||
| 145 | |||
| 143 | var a: Analysis = .{ | 146 | var a: Analysis = .{ |
| 144 | .gpa = gpa, | 147 | .gpa = gpa, |
| 148 | .zcu = zcu, | ||
| 145 | .air = air, | 149 | .air = air, |
| 146 | .tomb_bits = try gpa.alloc( | 150 | .tomb_bits = try gpa.alloc( |
| 147 | usize, | 151 | usize, |
| ... | @@ -220,6 +224,7 @@ const OperandCategory = enum { | ... | @@ -220,6 +224,7 @@ const OperandCategory = enum { |
| 220 | pub fn categorizeOperand( | 224 | pub fn categorizeOperand( |
| 221 | l: Liveness, | 225 | l: Liveness, |
| 222 | air: Air, | 226 | air: Air, |
| 227 | zcu: *Zcu, | ||
| 223 | inst: Air.Inst.Index, | 228 | inst: Air.Inst.Index, |
| 224 | operand: Air.Inst.Index, | 229 | operand: Air.Inst.Index, |
| 225 | ip: *const InternPool, | 230 | ip: *const InternPool, |
| ... | @@ -511,10 +516,15 @@ pub fn categorizeOperand( | ... | @@ -511,10 +516,15 @@ pub fn categorizeOperand( |
| 511 | if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .none); | 516 | if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .none); |
| 512 | return .none; | 517 | return .none; |
| 513 | }, | 518 | }, |
| 514 | .shuffle => { | 519 | .shuffle_one => { |
| 515 | const extra = air.extraData(Air.Shuffle, air_datas[@intFromEnum(inst)].ty_pl.payload).data; | 520 | const unwrapped = air.unwrapShuffleOne(zcu, inst); |
| 516 | if (extra.a == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); | 521 | if (unwrapped.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| 517 | if (extra.b == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none); | 522 | return .none; |
| 523 | }, | ||
| 524 | .shuffle_two => { | ||
| 525 | const unwrapped = air.unwrapShuffleTwo(zcu, inst); | ||
| 526 | if (unwrapped.operand_a == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); | ||
| 527 | if (unwrapped.operand_b == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none); | ||
| 518 | return .none; | 528 | return .none; |
| 519 | }, | 529 | }, |
| 520 | .reduce, .reduce_optimized => { | 530 | .reduce, .reduce_optimized => { |
| ... | @@ -639,7 +649,7 @@ pub fn categorizeOperand( | ... | @@ -639,7 +649,7 @@ pub fn categorizeOperand( |
| 639 | 649 | ||
| 640 | var operand_live: bool = true; | 650 | var operand_live: bool = true; |
| 641 | for (&[_]Air.Inst.Index{ then_body[0], else_body[0] }) |cond_inst| { | 651 | for (&[_]Air.Inst.Index{ then_body[0], else_body[0] }) |cond_inst| { |
| 642 | if (l.categorizeOperand(air, cond_inst, operand, ip) == .tomb) | 652 | if (l.categorizeOperand(air, zcu, cond_inst, operand, ip) == .tomb) |
| 643 | operand_live = false; | 653 | operand_live = false; |
| 644 | 654 | ||
| 645 | switch (air_tags[@intFromEnum(cond_inst)]) { | 655 | switch (air_tags[@intFromEnum(cond_inst)]) { |
| ... | @@ -824,6 +834,7 @@ pub const BigTomb = struct { | ... | @@ -824,6 +834,7 @@ pub const BigTomb = struct { |
| 824 | /// In-progress data; on successful analysis converted into `Liveness`. | 834 | /// In-progress data; on successful analysis converted into `Liveness`. |
| 825 | const Analysis = struct { | 835 | const Analysis = struct { |
| 826 | gpa: Allocator, | 836 | gpa: Allocator, |
| 837 | zcu: *Zcu, | ||
| 827 | air: Air, | 838 | air: Air, |
| 828 | intern_pool: *InternPool, | 839 | intern_pool: *InternPool, |
| 829 | tomb_bits: []usize, | 840 | tomb_bits: []usize, |
| ... | @@ -1119,9 +1130,13 @@ fn analyzeInst( | ... | @@ -1119,9 +1130,13 @@ fn analyzeInst( |
| 1119 | const extra = a.air.extraData(Air.Bin, pl_op.payload).data; | 1130 | const extra = a.air.extraData(Air.Bin, pl_op.payload).data; |
| 1120 | return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.lhs, extra.rhs }); | 1131 | return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.lhs, extra.rhs }); |
| 1121 | }, | 1132 | }, |
| 1122 | .shuffle => { | 1133 | .shuffle_one => { |
| 1123 | const extra = a.air.extraData(Air.Shuffle, inst_datas[@intFromEnum(inst)].ty_pl.payload).data; | 1134 | const unwrapped = a.air.unwrapShuffleOne(a.zcu, inst); |
| 1124 | return analyzeOperands(a, pass, data, inst, .{ extra.a, extra.b, .none }); | 1135 | return analyzeOperands(a, pass, data, inst, .{ unwrapped.operand, .none, .none }); |
| 1136 | }, | ||
| 1137 | .shuffle_two => { | ||
| 1138 | const unwrapped = a.air.unwrapShuffleTwo(a.zcu, inst); | ||
| 1139 | return analyzeOperands(a, pass, data, inst, .{ unwrapped.operand_a, unwrapped.operand_b, .none }); | ||
| 1125 | }, | 1140 | }, |
| 1126 | .reduce, .reduce_optimized => { | 1141 | .reduce, .reduce_optimized => { |
| 1127 | const reduce = inst_datas[@intFromEnum(inst)].reduce; | 1142 | const reduce = inst_datas[@intFromEnum(inst)].reduce; |
src/Air/Liveness/Verify.zig+9-4| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | //! Verifies that Liveness information is valid. | 1 | //! Verifies that Liveness information is valid. |
| 2 | 2 | ||
| 3 | gpa: std.mem.Allocator, | 3 | gpa: std.mem.Allocator, |
| 4 | zcu: *Zcu, | ||
| 4 | air: Air, | 5 | air: Air, |
| 5 | liveness: Liveness, | 6 | liveness: Liveness, |
| 6 | live: LiveMap = .{}, | 7 | live: LiveMap = .{}, |
| ... | @@ -287,10 +288,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -287,10 +288,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 287 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 288 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 288 | try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none }); | 289 | try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none }); |
| 289 | }, | 290 | }, |
| 290 | .shuffle => { | 291 | .shuffle_one => { |
| 291 | const ty_pl = data[@intFromEnum(inst)].ty_pl; | 292 | const unwrapped = self.air.unwrapShuffleOne(self.zcu, inst); |
| 292 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 293 | try self.verifyInstOperands(inst, .{ unwrapped.operand, .none, .none }); |
| 293 | try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none }); | 294 | }, |
| 295 | .shuffle_two => { | ||
| 296 | const unwrapped = self.air.unwrapShuffleTwo(self.zcu, inst); | ||
| 297 | try self.verifyInstOperands(inst, .{ unwrapped.operand_a, unwrapped.operand_b, .none }); | ||
| 294 | }, | 298 | }, |
| 295 | .cmp_vector, | 299 | .cmp_vector, |
| 296 | .cmp_vector_optimized, | 300 | .cmp_vector_optimized, |
| ... | @@ -639,4 +643,5 @@ const log = std.log.scoped(.liveness_verify); | ... | @@ -639,4 +643,5 @@ const log = std.log.scoped(.liveness_verify); |
| 639 | const Air = @import("../../Air.zig"); | 643 | const Air = @import("../../Air.zig"); |
| 640 | const Liveness = @import("../Liveness.zig"); | 644 | const Liveness = @import("../Liveness.zig"); |
| 641 | const InternPool = @import("../../InternPool.zig"); | 645 | const InternPool = @import("../../InternPool.zig"); |
| 646 | const Zcu = @import("../../Zcu.zig"); | ||
| 642 | const Verify = @This(); | 647 | const Verify = @This(); |
src/Air/types_resolved.zig+16-6| ... | @@ -249,12 +249,22 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool { | ... | @@ -249,12 +249,22 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool { |
| 249 | if (!checkRef(extra.struct_operand, zcu)) return false; | 249 | if (!checkRef(extra.struct_operand, zcu)) return false; |
| 250 | }, | 250 | }, |
| 251 | 251 | ||
| 252 | .shuffle => { | 252 | .shuffle_one => { |
| 253 | const extra = air.extraData(Air.Shuffle, data.ty_pl.payload).data; | 253 | const unwrapped = air.unwrapShuffleOne(zcu, inst); |
| 254 | if (!checkType(data.ty_pl.ty.toType(), zcu)) return false; | 254 | if (!checkType(unwrapped.result_ty, zcu)) return false; |
| 255 | if (!checkRef(extra.a, zcu)) return false; | 255 | if (!checkRef(unwrapped.operand, zcu)) return false; |
| 256 | if (!checkRef(extra.b, zcu)) return false; | 256 | for (unwrapped.mask) |m| switch (m.unwrap()) { |
| 257 | if (!checkVal(Value.fromInterned(extra.mask), zcu)) return false; | 257 | .elem => {}, |
| 258 | .value => |val| if (!checkVal(.fromInterned(val), zcu)) return false, | ||
| 259 | }; | ||
| 260 | }, | ||
| 261 | |||
| 262 | .shuffle_two => { | ||
| 263 | const unwrapped = air.unwrapShuffleTwo(zcu, inst); | ||
| 264 | if (!checkType(unwrapped.result_ty, zcu)) return false; | ||
| 265 | if (!checkRef(unwrapped.operand_a, zcu)) return false; | ||
| 266 | if (!checkRef(unwrapped.operand_b, zcu)) return false; | ||
| 267 | // No values to check because there are no comptime-known values other than undef | ||
| 258 | }, | 268 | }, |
| 259 | 269 | ||
| 260 | .cmpxchg_weak, | 270 | .cmpxchg_weak, |
src/Compilation.zig+1-1| ... | @@ -2529,6 +2529,7 @@ pub fn destroy(comp: *Compilation) void { | ... | @@ -2529,6 +2529,7 @@ pub fn destroy(comp: *Compilation) void { |
| 2529 | 2529 | ||
| 2530 | pub fn clearMiscFailures(comp: *Compilation) void { | 2530 | pub fn clearMiscFailures(comp: *Compilation) void { |
| 2531 | comp.alloc_failure_occurred = false; | 2531 | comp.alloc_failure_occurred = false; |
| 2532 | comp.link_diags.flags = .{}; | ||
| 2532 | for (comp.misc_failures.values()) |*value| { | 2533 | for (comp.misc_failures.values()) |*value| { |
| 2533 | value.deinit(comp.gpa); | 2534 | value.deinit(comp.gpa); |
| 2534 | } | 2535 | } |
| ... | @@ -2795,7 +2796,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2795,7 +2796,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2795 | 2796 | ||
| 2796 | if (anyErrors(comp)) { | 2797 | if (anyErrors(comp)) { |
| 2797 | // Skip flushing and keep source files loaded for error reporting. | 2798 | // Skip flushing and keep source files loaded for error reporting. |
| 2798 | comp.link_diags.flags = .{}; | ||
| 2799 | return; | 2799 | return; |
| 2800 | } | 2800 | } |
| 2801 | 2801 |
src/InternPool.zig+60-24| ... | @@ -4579,10 +4579,11 @@ pub const Index = enum(u32) { | ... | @@ -4579,10 +4579,11 @@ pub const Index = enum(u32) { |
| 4579 | undefined_type, | 4579 | undefined_type, |
| 4580 | enum_literal_type, | 4580 | enum_literal_type, |
| 4581 | 4581 | ||
| 4582 | ptr_usize_type, | ||
| 4583 | ptr_const_comptime_int_type, | ||
| 4582 | manyptr_u8_type, | 4584 | manyptr_u8_type, |
| 4583 | manyptr_const_u8_type, | 4585 | manyptr_const_u8_type, |
| 4584 | manyptr_const_u8_sentinel_0_type, | 4586 | manyptr_const_u8_sentinel_0_type, |
| 4585 | single_const_pointer_to_comptime_int_type, | ||
| 4586 | slice_const_u8_type, | 4587 | slice_const_u8_type, |
| 4587 | slice_const_u8_sentinel_0_type, | 4588 | slice_const_u8_sentinel_0_type, |
| 4588 | 4589 | ||
| ... | @@ -4649,19 +4650,29 @@ pub const Index = enum(u32) { | ... | @@ -4649,19 +4650,29 @@ pub const Index = enum(u32) { |
| 4649 | 4650 | ||
| 4650 | /// `undefined` (untyped) | 4651 | /// `undefined` (untyped) |
| 4651 | undef, | 4652 | undef, |
| 4653 | /// `@as(bool, undefined)` | ||
| 4654 | undef_bool, | ||
| 4655 | /// `@as(usize, undefined)` | ||
| 4656 | undef_usize, | ||
| 4657 | /// `@as(u1, undefined)` | ||
| 4658 | undef_u1, | ||
| 4652 | /// `0` (comptime_int) | 4659 | /// `0` (comptime_int) |
| 4653 | zero, | 4660 | zero, |
| 4654 | /// `0` (usize) | 4661 | /// `@as(usize, 0)` |
| 4655 | zero_usize, | 4662 | zero_usize, |
| 4656 | /// `0` (u8) | 4663 | /// `@as(u1, 0)` |
| 4664 | zero_u1, | ||
| 4665 | /// `@as(u8, 0)` | ||
| 4657 | zero_u8, | 4666 | zero_u8, |
| 4658 | /// `1` (comptime_int) | 4667 | /// `1` (comptime_int) |
| 4659 | one, | 4668 | one, |
| 4660 | /// `1` (usize) | 4669 | /// `@as(usize, 1)` |
| 4661 | one_usize, | 4670 | one_usize, |
| 4662 | /// `1` (u8) | 4671 | /// `@as(u1, 1)` |
| 4672 | one_u1, | ||
| 4673 | /// `@as(u8, 1)` | ||
| 4663 | one_u8, | 4674 | one_u8, |
| 4664 | /// `4` (u8) | 4675 | /// `@as(u8, 4)` |
| 4665 | four_u8, | 4676 | four_u8, |
| 4666 | /// `-1` (comptime_int) | 4677 | /// `-1` (comptime_int) |
| 4667 | negative_one, | 4678 | negative_one, |
| ... | @@ -5074,6 +5085,20 @@ pub const static_keys: [static_len]Key = .{ | ... | @@ -5074,6 +5085,20 @@ pub const static_keys: [static_len]Key = .{ |
| 5074 | .{ .simple_type = .undefined }, | 5085 | .{ .simple_type = .undefined }, |
| 5075 | .{ .simple_type = .enum_literal }, | 5086 | .{ .simple_type = .enum_literal }, |
| 5076 | 5087 | ||
| 5088 | // *usize | ||
| 5089 | .{ .ptr_type = .{ | ||
| 5090 | .child = .usize_type, | ||
| 5091 | .flags = .{}, | ||
| 5092 | } }, | ||
| 5093 | |||
| 5094 | // *const comptime_int | ||
| 5095 | .{ .ptr_type = .{ | ||
| 5096 | .child = .comptime_int_type, | ||
| 5097 | .flags = .{ | ||
| 5098 | .is_const = true, | ||
| 5099 | }, | ||
| 5100 | } }, | ||
| 5101 | |||
| 5077 | // [*]u8 | 5102 | // [*]u8 |
| 5078 | .{ .ptr_type = .{ | 5103 | .{ .ptr_type = .{ |
| 5079 | .child = .u8_type, | 5104 | .child = .u8_type, |
| ... | @@ -5101,15 +5126,6 @@ pub const static_keys: [static_len]Key = .{ | ... | @@ -5101,15 +5126,6 @@ pub const static_keys: [static_len]Key = .{ |
| 5101 | }, | 5126 | }, |
| 5102 | } }, | 5127 | } }, |
| 5103 | 5128 | ||
| 5104 | // *const comptime_int | ||
| 5105 | .{ .ptr_type = .{ | ||
| 5106 | .child = .comptime_int_type, | ||
| 5107 | .flags = .{ | ||
| 5108 | .size = .one, | ||
| 5109 | .is_const = true, | ||
| 5110 | }, | ||
| 5111 | } }, | ||
| 5112 | |||
| 5113 | // []const u8 | 5129 | // []const u8 |
| 5114 | .{ .ptr_type = .{ | 5130 | .{ .ptr_type = .{ |
| 5115 | .child = .u8_type, | 5131 | .child = .u8_type, |
| ... | @@ -5245,6 +5261,9 @@ pub const static_keys: [static_len]Key = .{ | ... | @@ -5245,6 +5261,9 @@ pub const static_keys: [static_len]Key = .{ |
| 5245 | } }, | 5261 | } }, |
| 5246 | 5262 | ||
| 5247 | .{ .simple_value = .undefined }, | 5263 | .{ .simple_value = .undefined }, |
| 5264 | .{ .undef = .bool_type }, | ||
| 5265 | .{ .undef = .usize_type }, | ||
| 5266 | .{ .undef = .u1_type }, | ||
| 5248 | 5267 | ||
| 5249 | .{ .int = .{ | 5268 | .{ .int = .{ |
| 5250 | .ty = .comptime_int_type, | 5269 | .ty = .comptime_int_type, |
| ... | @@ -5256,6 +5275,11 @@ pub const static_keys: [static_len]Key = .{ | ... | @@ -5256,6 +5275,11 @@ pub const static_keys: [static_len]Key = .{ |
| 5256 | .storage = .{ .u64 = 0 }, | 5275 | .storage = .{ .u64 = 0 }, |
| 5257 | } }, | 5276 | } }, |
| 5258 | 5277 | ||
| 5278 | .{ .int = .{ | ||
| 5279 | .ty = .u1_type, | ||
| 5280 | .storage = .{ .u64 = 0 }, | ||
| 5281 | } }, | ||
| 5282 | |||
| 5259 | .{ .int = .{ | 5283 | .{ .int = .{ |
| 5260 | .ty = .u8_type, | 5284 | .ty = .u8_type, |
| 5261 | .storage = .{ .u64 = 0 }, | 5285 | .storage = .{ .u64 = 0 }, |
| ... | @@ -5271,17 +5295,21 @@ pub const static_keys: [static_len]Key = .{ | ... | @@ -5271,17 +5295,21 @@ pub const static_keys: [static_len]Key = .{ |
| 5271 | .storage = .{ .u64 = 1 }, | 5295 | .storage = .{ .u64 = 1 }, |
| 5272 | } }, | 5296 | } }, |
| 5273 | 5297 | ||
| 5274 | // one_u8 | 5298 | .{ .int = .{ |
| 5299 | .ty = .u1_type, | ||
| 5300 | .storage = .{ .u64 = 1 }, | ||
| 5301 | } }, | ||
| 5302 | |||
| 5275 | .{ .int = .{ | 5303 | .{ .int = .{ |
| 5276 | .ty = .u8_type, | 5304 | .ty = .u8_type, |
| 5277 | .storage = .{ .u64 = 1 }, | 5305 | .storage = .{ .u64 = 1 }, |
| 5278 | } }, | 5306 | } }, |
| 5279 | // four_u8 | 5307 | |
| 5280 | .{ .int = .{ | 5308 | .{ .int = .{ |
| 5281 | .ty = .u8_type, | 5309 | .ty = .u8_type, |
| 5282 | .storage = .{ .u64 = 4 }, | 5310 | .storage = .{ .u64 = 4 }, |
| 5283 | } }, | 5311 | } }, |
| 5284 | // negative_one | 5312 | |
| 5285 | .{ .int = .{ | 5313 | .{ .int = .{ |
| 5286 | .ty = .comptime_int_type, | 5314 | .ty = .comptime_int_type, |
| 5287 | .storage = .{ .i64 = -1 }, | 5315 | .storage = .{ .i64 = -1 }, |
| ... | @@ -10482,7 +10510,7 @@ pub fn getCoerced( | ... | @@ -10482,7 +10510,7 @@ pub fn getCoerced( |
| 10482 | .base_addr = .int, | 10510 | .base_addr = .int, |
| 10483 | .byte_offset = 0, | 10511 | .byte_offset = 0, |
| 10484 | } }), | 10512 | } }), |
| 10485 | .len = try ip.get(gpa, tid, .{ .undef = .usize_type }), | 10513 | .len = .undef_usize, |
| 10486 | } }), | 10514 | } }), |
| 10487 | }; | 10515 | }; |
| 10488 | }, | 10516 | }, |
| ... | @@ -10601,7 +10629,7 @@ pub fn getCoerced( | ... | @@ -10601,7 +10629,7 @@ pub fn getCoerced( |
| 10601 | .base_addr = .int, | 10629 | .base_addr = .int, |
| 10602 | .byte_offset = 0, | 10630 | .byte_offset = 0, |
| 10603 | } }), | 10631 | } }), |
| 10604 | .len = try ip.get(gpa, tid, .{ .undef = .usize_type }), | 10632 | .len = .undef_usize, |
| 10605 | } }), | 10633 | } }), |
| 10606 | }, | 10634 | }, |
| 10607 | else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty), | 10635 | else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty), |
| ... | @@ -11847,10 +11875,11 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -11847,10 +11875,11 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11847 | .null_type, | 11875 | .null_type, |
| 11848 | .undefined_type, | 11876 | .undefined_type, |
| 11849 | .enum_literal_type, | 11877 | .enum_literal_type, |
| 11878 | .ptr_usize_type, | ||
| 11879 | .ptr_const_comptime_int_type, | ||
| 11850 | .manyptr_u8_type, | 11880 | .manyptr_u8_type, |
| 11851 | .manyptr_const_u8_type, | 11881 | .manyptr_const_u8_type, |
| 11852 | .manyptr_const_u8_sentinel_0_type, | 11882 | .manyptr_const_u8_sentinel_0_type, |
| 11853 | .single_const_pointer_to_comptime_int_type, | ||
| 11854 | .slice_const_u8_type, | 11883 | .slice_const_u8_type, |
| 11855 | .slice_const_u8_sentinel_0_type, | 11884 | .slice_const_u8_sentinel_0_type, |
| 11856 | .vector_8_i8_type, | 11885 | .vector_8_i8_type, |
| ... | @@ -11909,12 +11938,13 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -11909,12 +11938,13 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11909 | 11938 | ||
| 11910 | .undef => .undefined_type, | 11939 | .undef => .undefined_type, |
| 11911 | .zero, .one, .negative_one => .comptime_int_type, | 11940 | .zero, .one, .negative_one => .comptime_int_type, |
| 11912 | .zero_usize, .one_usize => .usize_type, | 11941 | .undef_usize, .zero_usize, .one_usize => .usize_type, |
| 11942 | .undef_u1, .zero_u1, .one_u1 => .u1_type, | ||
| 11913 | .zero_u8, .one_u8, .four_u8 => .u8_type, | 11943 | .zero_u8, .one_u8, .four_u8 => .u8_type, |
| 11914 | .void_value => .void_type, | 11944 | .void_value => .void_type, |
| 11915 | .unreachable_value => .noreturn_type, | 11945 | .unreachable_value => .noreturn_type, |
| 11916 | .null_value => .null_type, | 11946 | .null_value => .null_type, |
| 11917 | .bool_true, .bool_false => .bool_type, | 11947 | .undef_bool, .bool_true, .bool_false => .bool_type, |
| 11918 | .empty_tuple => .empty_tuple_type, | 11948 | .empty_tuple => .empty_tuple_type, |
| 11919 | 11949 | ||
| 11920 | // This optimization on tags is needed so that indexToKey can call | 11950 | // This optimization on tags is needed so that indexToKey can call |
| ... | @@ -12186,10 +12216,11 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { | ... | @@ -12186,10 +12216,11 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12186 | .undefined_type => .undefined, | 12216 | .undefined_type => .undefined, |
| 12187 | .enum_literal_type => .enum_literal, | 12217 | .enum_literal_type => .enum_literal, |
| 12188 | 12218 | ||
| 12219 | .ptr_usize_type, | ||
| 12220 | .ptr_const_comptime_int_type, | ||
| 12189 | .manyptr_u8_type, | 12221 | .manyptr_u8_type, |
| 12190 | .manyptr_const_u8_type, | 12222 | .manyptr_const_u8_type, |
| 12191 | .manyptr_const_u8_sentinel_0_type, | 12223 | .manyptr_const_u8_sentinel_0_type, |
| 12192 | .single_const_pointer_to_comptime_int_type, | ||
| 12193 | .slice_const_u8_type, | 12224 | .slice_const_u8_type, |
| 12194 | .slice_const_u8_sentinel_0_type, | 12225 | .slice_const_u8_sentinel_0_type, |
| 12195 | => .pointer, | 12226 | => .pointer, |
| ... | @@ -12251,11 +12282,16 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { | ... | @@ -12251,11 +12282,16 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12251 | 12282 | ||
| 12252 | // values, not types | 12283 | // values, not types |
| 12253 | .undef => unreachable, | 12284 | .undef => unreachable, |
| 12285 | .undef_bool => unreachable, | ||
| 12286 | .undef_usize => unreachable, | ||
| 12287 | .undef_u1 => unreachable, | ||
| 12254 | .zero => unreachable, | 12288 | .zero => unreachable, |
| 12255 | .zero_usize => unreachable, | 12289 | .zero_usize => unreachable, |
| 12290 | .zero_u1 => unreachable, | ||
| 12256 | .zero_u8 => unreachable, | 12291 | .zero_u8 => unreachable, |
| 12257 | .one => unreachable, | 12292 | .one => unreachable, |
| 12258 | .one_usize => unreachable, | 12293 | .one_usize => unreachable, |
| 12294 | .one_u1 => unreachable, | ||
| 12259 | .one_u8 => unreachable, | 12295 | .one_u8 => unreachable, |
| 12260 | .four_u8 => unreachable, | 12296 | .four_u8 => unreachable, |
| 12261 | .negative_one => unreachable, | 12297 | .negative_one => unreachable, |
src/Sema.zig+553-795| ... | @@ -1881,7 +1881,7 @@ fn analyzeBodyInner( | ... | @@ -1881,7 +1881,7 @@ fn analyzeBodyInner( |
| 1881 | extra.data.else_body_len, | 1881 | extra.data.else_body_len, |
| 1882 | ); | 1882 | ); |
| 1883 | const uncasted_cond = try sema.resolveInst(extra.data.condition); | 1883 | const uncasted_cond = try sema.resolveInst(extra.data.condition); |
| 1884 | const cond = try sema.coerce(block, Type.bool, uncasted_cond, cond_src); | 1884 | const cond = try sema.coerce(block, .bool, uncasted_cond, cond_src); |
| 1885 | const cond_val = try sema.resolveConstDefinedValue( | 1885 | const cond_val = try sema.resolveConstDefinedValue( |
| 1886 | block, | 1886 | block, |
| 1887 | cond_src, | 1887 | cond_src, |
| ... | @@ -2012,7 +2012,7 @@ fn resolveConstBool( | ... | @@ -2012,7 +2012,7 @@ fn resolveConstBool( |
| 2012 | reason: ComptimeReason, | 2012 | reason: ComptimeReason, |
| 2013 | ) !bool { | 2013 | ) !bool { |
| 2014 | const air_inst = try sema.resolveInst(zir_ref); | 2014 | const air_inst = try sema.resolveInst(zir_ref); |
| 2015 | const wanted_type = Type.bool; | 2015 | const wanted_type: Type = .bool; |
| 2016 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 2016 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 2017 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 2017 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| 2018 | return val.toBool(); | 2018 | return val.toBool(); |
| ... | @@ -2037,7 +2037,7 @@ pub fn toConstString( | ... | @@ -2037,7 +2037,7 @@ pub fn toConstString( |
| 2037 | reason: ComptimeReason, | 2037 | reason: ComptimeReason, |
| 2038 | ) ![]u8 { | 2038 | ) ![]u8 { |
| 2039 | const pt = sema.pt; | 2039 | const pt = sema.pt; |
| 2040 | const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src); | 2040 | const coerced_inst = try sema.coerce(block, .slice_const_u8, air_inst, src); |
| 2041 | const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 2041 | const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| 2042 | const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason); | 2042 | const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason); |
| 2043 | return arr_val.toAllocatedBytes(arr_val.typeOf(pt.zcu), sema.arena, pt); | 2043 | return arr_val.toAllocatedBytes(arr_val.typeOf(pt.zcu), sema.arena, pt); |
| ... | @@ -2051,7 +2051,7 @@ pub fn resolveConstStringIntern( | ... | @@ -2051,7 +2051,7 @@ pub fn resolveConstStringIntern( |
| 2051 | reason: ComptimeReason, | 2051 | reason: ComptimeReason, |
| 2052 | ) !InternPool.NullTerminatedString { | 2052 | ) !InternPool.NullTerminatedString { |
| 2053 | const air_inst = try sema.resolveInst(zir_ref); | 2053 | const air_inst = try sema.resolveInst(zir_ref); |
| 2054 | const wanted_type = Type.slice_const_u8; | 2054 | const wanted_type: Type = .slice_const_u8; |
| 2055 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 2055 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 2056 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 2056 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| 2057 | return sema.sliceToIpString(block, src, val, reason); | 2057 | return sema.sliceToIpString(block, src, val, reason); |
| ... | @@ -2180,7 +2180,7 @@ fn analyzeAsType( | ... | @@ -2180,7 +2180,7 @@ fn analyzeAsType( |
| 2180 | src: LazySrcLoc, | 2180 | src: LazySrcLoc, |
| 2181 | air_inst: Air.Inst.Ref, | 2181 | air_inst: Air.Inst.Ref, |
| 2182 | ) !Type { | 2182 | ) !Type { |
| 2183 | const wanted_type = Type.type; | 2183 | const wanted_type: Type = .type; |
| 2184 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 2184 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 2185 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, .{ .simple = .type }); | 2185 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, .{ .simple = .type }); |
| 2186 | return val.toType(); | 2186 | return val.toType(); |
| ... | @@ -2641,7 +2641,7 @@ fn reparentOwnedErrorMsg( | ... | @@ -2641,7 +2641,7 @@ fn reparentOwnedErrorMsg( |
| 2641 | msg.msg = msg_str; | 2641 | msg.msg = msg_str; |
| 2642 | } | 2642 | } |
| 2643 | 2643 | ||
| 2644 | const align_ty = Type.u29; | 2644 | const align_ty: Type = .u29; |
| 2645 | 2645 | ||
| 2646 | pub fn analyzeAsAlign( | 2646 | pub fn analyzeAsAlign( |
| 2647 | sema: *Sema, | 2647 | sema: *Sema, |
| ... | @@ -2819,7 +2819,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us | ... | @@ -2819,7 +2819,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us |
| 2819 | const pt = sema.pt; | 2819 | const pt = sema.pt; |
| 2820 | const zcu = pt.zcu; | 2820 | const zcu = pt.zcu; |
| 2821 | const ip = &zcu.intern_pool; | 2821 | const ip = &zcu.intern_pool; |
| 2822 | const parent_ty = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type); | 2822 | const parent_ty: Type = .fromInterned(zcu.namespacePtr(block.namespace).owner_type); |
| 2823 | const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu); | 2823 | const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu); |
| 2824 | 2824 | ||
| 2825 | const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len); | 2825 | const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len); |
| ... | @@ -3777,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3777,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3777 | const alloc = try sema.resolveInst(inst_data.operand); | 3777 | const alloc = try sema.resolveInst(inst_data.operand); |
| 3778 | const alloc_ty = sema.typeOf(alloc); | 3778 | const alloc_ty = sema.typeOf(alloc); |
| 3779 | const ptr_info = alloc_ty.ptrInfo(zcu); | 3779 | const ptr_info = alloc_ty.ptrInfo(zcu); |
| 3780 | const elem_ty = Type.fromInterned(ptr_info.child); | 3780 | const elem_ty: Type = .fromInterned(ptr_info.child); |
| 3781 | 3781 | ||
| 3782 | // If the alloc was created in a comptime scope, we already created a comptime alloc for it. | 3782 | // If the alloc was created in a comptime scope, we already created a comptime alloc for it. |
| 3783 | // However, if the final constructed value does not reference comptime-mutable memory, we wish | 3783 | // However, if the final constructed value does not reference comptime-mutable memory, we wish |
| ... | @@ -3848,7 +3848,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -3848,7 +3848,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 3848 | 3848 | ||
| 3849 | const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc); | 3849 | const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc); |
| 3850 | const ptr_info = alloc_ty.ptrInfo(zcu); | 3850 | const ptr_info = alloc_ty.ptrInfo(zcu); |
| 3851 | const elem_ty = Type.fromInterned(ptr_info.child); | 3851 | const elem_ty: Type = .fromInterned(ptr_info.child); |
| 3852 | 3852 | ||
| 3853 | const alloc_inst = alloc.toIndex() orelse return null; | 3853 | const alloc_inst = alloc.toIndex() orelse return null; |
| 3854 | const comptime_info = sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return null; | 3854 | const comptime_info = sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return null; |
| ... | @@ -4024,9 +4024,9 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -4024,9 +4024,9 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 4024 | // As this is a union field, we must store to the pointer now to set the tag. | 4024 | // As this is a union field, we must store to the pointer now to set the tag. |
| 4025 | // If the payload is OPV, there will not be a payload store, so we store that value. | 4025 | // If the payload is OPV, there will not be a payload store, so we store that value. |
| 4026 | // Otherwise, there will be a payload store to process later, so undef will suffice. | 4026 | // Otherwise, there will be a payload store to process later, so undef will suffice. |
| 4027 | const payload_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]); | 4027 | const payload_ty: Type = .fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]); |
| 4028 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); | 4028 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); |
| 4029 | const tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx); | 4029 | const tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), idx); |
| 4030 | const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val); | 4030 | const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val); |
| 4031 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty); | 4031 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty); |
| 4032 | } | 4032 | } |
| ... | @@ -4050,7 +4050,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -4050,7 +4050,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 4050 | const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?; | 4050 | const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?; |
| 4051 | const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?; | 4051 | const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?; |
| 4052 | const new_ptr = ptr_mapping.get(air_ptr_inst).?; | 4052 | const new_ptr = ptr_mapping.get(air_ptr_inst).?; |
| 4053 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(new_ptr), store_val, Type.fromInterned(zcu.intern_pool.typeOf(store_val.toIntern()))); | 4053 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(new_ptr), store_val, .fromInterned(zcu.intern_pool.typeOf(store_val.toIntern()))); |
| 4054 | }, | 4054 | }, |
| 4055 | else => unreachable, | 4055 | else => unreachable, |
| 4056 | } | 4056 | } |
| ... | @@ -4284,7 +4284,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4284,7 +4284,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4284 | else => unreachable, | 4284 | else => unreachable, |
| 4285 | }; | 4285 | }; |
| 4286 | if (zcu.intern_pool.isFuncBody(val)) { | 4286 | if (zcu.intern_pool.isFuncBody(val)) { |
| 4287 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(val)); | 4287 | const ty: Type = .fromInterned(zcu.intern_pool.typeOf(val)); |
| 4288 | if (try ty.fnHasRuntimeBitsSema(pt)) { | 4288 | if (try ty.fnHasRuntimeBitsSema(pt)) { |
| 4289 | try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = val })); | 4289 | try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = val })); |
| 4290 | try zcu.ensureFuncBodyAnalysisQueued(val); | 4290 | try zcu.ensureFuncBodyAnalysisQueued(val); |
| ... | @@ -4447,14 +4447,14 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4447,14 +4447,14 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4447 | const range_end = try sema.resolveInst(zir_arg_pair[1]); | 4447 | const range_end = try sema.resolveInst(zir_arg_pair[1]); |
| 4448 | break :l try sema.analyzeArithmetic(block, .sub, range_end, range_start, arg_src, arg_src, arg_src, true); | 4448 | break :l try sema.analyzeArithmetic(block, .sub, range_end, range_start, arg_src, arg_src, arg_src, true); |
| 4449 | }; | 4449 | }; |
| 4450 | const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src); | 4450 | const arg_len = try sema.coerce(block, .usize, arg_len_uncoerced, arg_src); |
| 4451 | if (len == .none) { | 4451 | if (len == .none) { |
| 4452 | len = arg_len; | 4452 | len = arg_len; |
| 4453 | len_idx = i; | 4453 | len_idx = i; |
| 4454 | } | 4454 | } |
| 4455 | if (try sema.resolveDefinedValue(block, src, arg_len)) |arg_val| { | 4455 | if (try sema.resolveDefinedValue(block, src, arg_len)) |arg_val| { |
| 4456 | if (len_val) |v| { | 4456 | if (len_val) |v| { |
| 4457 | if (!(try sema.valuesEqual(arg_val, v, Type.usize))) { | 4457 | if (!(try sema.valuesEqual(arg_val, v, .usize))) { |
| 4458 | const msg = msg: { | 4458 | const msg = msg: { |
| 4459 | const msg = try sema.errMsg(src, "non-matching for loop lengths", .{}); | 4459 | const msg = try sema.errMsg(src, "non-matching for loop lengths", .{}); |
| 4460 | errdefer msg.destroy(gpa); | 4460 | errdefer msg.destroy(gpa); |
| ... | @@ -5343,7 +5343,7 @@ fn zirValidatePtrArrayInit( | ... | @@ -5343,7 +5343,7 @@ fn zirValidatePtrArrayInit( |
| 5343 | // sentinel-terminated array, the sentinel will not have been populated by | 5343 | // sentinel-terminated array, the sentinel will not have been populated by |
| 5344 | // any ZIR instructions at comptime; we need to do that here. | 5344 | // any ZIR instructions at comptime; we need to do that here. |
| 5345 | if (array_ty.sentinel(zcu)) |sentinel_val| { | 5345 | if (array_ty.sentinel(zcu)) |sentinel_val| { |
| 5346 | const array_len_ref = try pt.intRef(Type.usize, array_len); | 5346 | const array_len_ref = try pt.intRef(.usize, array_len); |
| 5347 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); | 5347 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); |
| 5348 | const sentinel = Air.internedToRef(sentinel_val.toIntern()); | 5348 | const sentinel = Air.internedToRef(sentinel_val.toIntern()); |
| 5349 | try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); | 5349 | try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); |
| ... | @@ -5828,7 +5828,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -5828,7 +5828,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 5828 | defer tracy.end(); | 5828 | defer tracy.end(); |
| 5829 | 5829 | ||
| 5830 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int; | 5830 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int; |
| 5831 | return sema.pt.intRef(Type.comptime_int, int); | 5831 | return sema.pt.intRef(.comptime_int, int); |
| 5832 | } | 5832 | } |
| 5833 | 5833 | ||
| 5834 | fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5834 | fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5846,7 +5846,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -5846,7 +5846,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 5846 | const limbs = try sema.arena.alloc(std.math.big.Limb, int.len); | 5846 | const limbs = try sema.arena.alloc(std.math.big.Limb, int.len); |
| 5847 | @memcpy(mem.sliceAsBytes(limbs), limb_bytes); | 5847 | @memcpy(mem.sliceAsBytes(limbs), limb_bytes); |
| 5848 | 5848 | ||
| 5849 | return Air.internedToRef((try sema.pt.intValue_big(Type.comptime_int, .{ | 5849 | return Air.internedToRef((try sema.pt.intValue_big(.comptime_int, .{ |
| 5850 | .limbs = limbs, | 5850 | .limbs = limbs, |
| 5851 | .positive = true, | 5851 | .positive = true, |
| 5852 | })).toIntern()); | 5852 | })).toIntern()); |
| ... | @@ -5856,7 +5856,7 @@ fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -5856,7 +5856,7 @@ fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 5856 | _ = block; | 5856 | _ = block; |
| 5857 | const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float; | 5857 | const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float; |
| 5858 | return Air.internedToRef((try sema.pt.floatValue( | 5858 | return Air.internedToRef((try sema.pt.floatValue( |
| 5859 | Type.comptime_float, | 5859 | .comptime_float, |
| 5860 | number, | 5860 | number, |
| 5861 | )).toIntern()); | 5861 | )).toIntern()); |
| 5862 | } | 5862 | } |
| ... | @@ -5866,7 +5866,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -5866,7 +5866,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 5866 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5866 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5867 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; | 5867 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; |
| 5868 | const number = extra.get(); | 5868 | const number = extra.get(); |
| 5869 | return Air.internedToRef((try sema.pt.floatValue(Type.comptime_float, number)).toIntern()); | 5869 | return Air.internedToRef((try sema.pt.floatValue(.comptime_float, number)).toIntern()); |
| 5870 | } | 5870 | } |
| 5871 | 5871 | ||
| 5872 | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 5872 | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -6641,7 +6641,7 @@ pub fn analyzeExport( | ... | @@ -6641,7 +6641,7 @@ pub fn analyzeExport( |
| 6641 | }; | 6641 | }; |
| 6642 | 6642 | ||
| 6643 | const exported_nav = ip.getNav(exported_nav_index); | 6643 | const exported_nav = ip.getNav(exported_nav_index); |
| 6644 | const export_ty = Type.fromInterned(exported_nav.typeOf(ip)); | 6644 | const export_ty: Type = .fromInterned(exported_nav.typeOf(ip)); |
| 6645 | 6645 | ||
| 6646 | if (!try sema.validateExternType(export_ty, .other)) { | 6646 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6647 | return sema.failWithOwnedErrorMsg(block, msg: { | 6647 | return sema.failWithOwnedErrorMsg(block, msg: { |
| ... | @@ -7005,7 +7005,7 @@ fn lookupInNamespace( | ... | @@ -7005,7 +7005,7 @@ fn lookupInNamespace( |
| 7005 | 7005 | ||
| 7006 | for (usingnamespaces.items) |sub_ns_nav| { | 7006 | for (usingnamespaces.items) |sub_ns_nav| { |
| 7007 | try sema.ensureNavResolved(block, src, sub_ns_nav, .fully); | 7007 | try sema.ensureNavResolved(block, src, sub_ns_nav, .fully); |
| 7008 | const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.fully_resolved.val); | 7008 | const sub_ns_ty: Type = .fromInterned(ip.getNav(sub_ns_nav).status.fully_resolved.val); |
| 7009 | const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu)); | 7009 | const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu)); |
| 7010 | try checked_namespaces.put(gpa, sub_ns, {}); | 7010 | try checked_namespaces.put(gpa, sub_ns, {}); |
| 7011 | } | 7011 | } |
| ... | @@ -7081,7 +7081,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref | ... | @@ -7081,7 +7081,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 7081 | const gpa = sema.gpa; | 7081 | const gpa = sema.gpa; |
| 7082 | 7082 | ||
| 7083 | if (block.isComptime() or block.is_typeof) { | 7083 | if (block.isComptime() or block.is_typeof) { |
| 7084 | const index_val = try pt.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len); | 7084 | const index_val = try pt.intValue_u64(.usize, sema.comptime_err_ret_trace.items.len); |
| 7085 | return Air.internedToRef(index_val.toIntern()); | 7085 | return Air.internedToRef(index_val.toIntern()); |
| 7086 | } | 7086 | } |
| 7087 | 7087 | ||
| ... | @@ -7326,13 +7326,13 @@ fn checkCallArgumentCount( | ... | @@ -7326,13 +7326,13 @@ fn checkCallArgumentCount( |
| 7326 | ) !Type { | 7326 | ) !Type { |
| 7327 | const pt = sema.pt; | 7327 | const pt = sema.pt; |
| 7328 | const zcu = pt.zcu; | 7328 | const zcu = pt.zcu; |
| 7329 | const func_ty = func_ty: { | 7329 | const func_ty: Type = func_ty: { |
| 7330 | switch (callee_ty.zigTypeTag(zcu)) { | 7330 | switch (callee_ty.zigTypeTag(zcu)) { |
| 7331 | .@"fn" => break :func_ty callee_ty, | 7331 | .@"fn" => break :func_ty callee_ty, |
| 7332 | .pointer => { | 7332 | .pointer => { |
| 7333 | const ptr_info = callee_ty.ptrInfo(zcu); | 7333 | const ptr_info = callee_ty.ptrInfo(zcu); |
| 7334 | if (ptr_info.flags.size == .one and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") { | 7334 | if (ptr_info.flags.size == .one and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") { |
| 7335 | break :func_ty Type.fromInterned(ptr_info.child); | 7335 | break :func_ty .fromInterned(ptr_info.child); |
| 7336 | } | 7336 | } |
| 7337 | }, | 7337 | }, |
| 7338 | .optional => { | 7338 | .optional => { |
| ... | @@ -7405,13 +7405,13 @@ fn callBuiltin( | ... | @@ -7405,13 +7405,13 @@ fn callBuiltin( |
| 7405 | const pt = sema.pt; | 7405 | const pt = sema.pt; |
| 7406 | const zcu = pt.zcu; | 7406 | const zcu = pt.zcu; |
| 7407 | const callee_ty = sema.typeOf(builtin_fn); | 7407 | const callee_ty = sema.typeOf(builtin_fn); |
| 7408 | const func_ty = func_ty: { | 7408 | const func_ty: Type = func_ty: { |
| 7409 | switch (callee_ty.zigTypeTag(zcu)) { | 7409 | switch (callee_ty.zigTypeTag(zcu)) { |
| 7410 | .@"fn" => break :func_ty callee_ty, | 7410 | .@"fn" => break :func_ty callee_ty, |
| 7411 | .pointer => { | 7411 | .pointer => { |
| 7412 | const ptr_info = callee_ty.ptrInfo(zcu); | 7412 | const ptr_info = callee_ty.ptrInfo(zcu); |
| 7413 | if (ptr_info.flags.size == .one and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") { | 7413 | if (ptr_info.flags.size == .one and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") { |
| 7414 | break :func_ty Type.fromInterned(ptr_info.child); | 7414 | break :func_ty .fromInterned(ptr_info.child); |
| 7415 | } | 7415 | } |
| 7416 | }, | 7416 | }, |
| 7417 | else => {}, | 7417 | else => {}, |
| ... | @@ -7568,7 +7568,7 @@ const CallArgsInfo = union(enum) { | ... | @@ -7568,7 +7568,7 @@ const CallArgsInfo = union(enum) { |
| 7568 | } | 7568 | } |
| 7569 | } | 7569 | } |
| 7570 | // Give the arg its result type | 7570 | // Give the arg its result type |
| 7571 | const provide_param_ty = if (maybe_param_ty) |t| t else Type.generic_poison; | 7571 | const provide_param_ty: Type = maybe_param_ty orelse .generic_poison; |
| 7572 | sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(provide_param_ty.toIntern())); | 7572 | sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(provide_param_ty.toIntern())); |
| 7573 | // Resolve the arg! | 7573 | // Resolve the arg! |
| 7574 | const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst); | 7574 | const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst); |
| ... | @@ -8353,7 +8353,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ | ... | @@ -8353,7 +8353,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ |
| 8353 | @tagName(backend), @tagName(target.cpu.arch), | 8353 | @tagName(backend), @tagName(target.cpu.arch), |
| 8354 | }); | 8354 | }); |
| 8355 | } | 8355 | } |
| 8356 | const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty); | 8356 | const owner_func_ty: Type = .fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty); |
| 8357 | if (owner_func_ty.toIntern() != func_ty.toIntern()) { | 8357 | if (owner_func_ty.toIntern() != func_ty.toIntern()) { |
| 8358 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ | 8358 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ |
| 8359 | func_ty.fmt(pt), owner_func_ty.fmt(pt), | 8359 | func_ty.fmt(pt), owner_func_ty.fmt(pt), |
| ... | @@ -8452,7 +8452,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -8452,7 +8452,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 8452 | const len_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 8452 | const len_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 8453 | const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 8453 | const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 8454 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8454 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8455 | const len: u32 = @intCast(try sema.resolveInt(block, len_src, extra.lhs, Type.u32, .{ .simple = .vector_length })); | 8455 | const len: u32 = @intCast(try sema.resolveInt(block, len_src, extra.lhs, .u32, .{ .simple = .vector_length })); |
| 8456 | const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); | 8456 | const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); |
| 8457 | try sema.checkVectorElemType(block, elem_type_src, elem_type); | 8457 | try sema.checkVectorElemType(block, elem_type_src, elem_type); |
| 8458 | const vector_type = try sema.pt.vectorType(.{ | 8458 | const vector_type = try sema.pt.vectorType(.{ |
| ... | @@ -8470,7 +8470,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -8470,7 +8470,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 8470 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8470 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8471 | const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node }); | 8471 | const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node }); |
| 8472 | const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node }); | 8472 | const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node }); |
| 8473 | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, .{ .simple = .array_length }); | 8473 | const len = try sema.resolveInt(block, len_src, extra.lhs, .usize, .{ .simple = .array_length }); |
| 8474 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); | 8474 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); |
| 8475 | try sema.validateArrayElemType(block, elem_type, elem_src); | 8475 | try sema.validateArrayElemType(block, elem_type, elem_src); |
| 8476 | const array_ty = try sema.pt.arrayType(.{ | 8476 | const array_ty = try sema.pt.arrayType(.{ |
| ... | @@ -8490,7 +8490,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -8490,7 +8490,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8490 | const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node }); | 8490 | const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node }); |
| 8491 | const sentinel_src = block.src(.{ .node_offset_array_type_sentinel = inst_data.src_node }); | 8491 | const sentinel_src = block.src(.{ .node_offset_array_type_sentinel = inst_data.src_node }); |
| 8492 | const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node }); | 8492 | const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node }); |
| 8493 | const len = try sema.resolveInt(block, len_src, extra.len, Type.usize, .{ .simple = .array_length }); | 8493 | const len = try sema.resolveInt(block, len_src, extra.len, .usize, .{ .simple = .array_length }); |
| 8494 | const elem_type = try sema.resolveType(block, elem_src, extra.elem_type); | 8494 | const elem_type = try sema.resolveType(block, elem_src, extra.elem_type); |
| 8495 | try sema.validateArrayElemType(block, elem_type, elem_src); | 8495 | try sema.validateArrayElemType(block, elem_type, elem_src); |
| 8496 | const uncasted_sentinel = try sema.resolveInst(extra.sentinel); | 8496 | const uncasted_sentinel = try sema.resolveInst(extra.sentinel); |
| ... | @@ -8599,7 +8599,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -8599,7 +8599,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8599 | const src = block.nodeOffset(extra.node); | 8599 | const src = block.nodeOffset(extra.node); |
| 8600 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 8600 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 8601 | const uncasted_operand = try sema.resolveInst(extra.operand); | 8601 | const uncasted_operand = try sema.resolveInst(extra.operand); |
| 8602 | const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src); | 8602 | const operand = try sema.coerce(block, .anyerror, uncasted_operand, operand_src); |
| 8603 | const err_int_ty = try pt.errorIntType(); | 8603 | const err_int_ty = try pt.errorIntType(); |
| 8604 | 8604 | ||
| 8605 | if (try sema.resolveValue(operand)) |val| { | 8605 | if (try sema.resolveValue(operand)) |val| { |
| ... | @@ -8912,21 +8912,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8912,21 +8912,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8912 | 8912 | ||
| 8913 | try sema.requireRuntimeBlock(block, src, operand_src); | 8913 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 8914 | if (block.wantSafety()) { | 8914 | if (block.wantSafety()) { |
| 8915 | if (zcu.backendSupportsFeature(.safety_checked_instructions)) { | 8915 | if (zcu.backendSupportsFeature(.panic_fn)) { |
| 8916 | _ = try sema.preparePanicId(src, .invalid_enum_value); | 8916 | _ = try sema.preparePanicId(src, .invalid_enum_value); |
| 8917 | return block.addTyOp(.intcast_safe, dest_ty, operand); | ||
| 8918 | } else { | ||
| 8919 | // Slightly silly fallback case... | ||
| 8920 | const int_tag_ty = dest_ty.intTagType(zcu); | ||
| 8921 | // Use `intCast`, since it'll set up the Sema-emitted safety checks for us! | ||
| 8922 | const int_val = try sema.intCast(block, src, int_tag_ty, src, operand, src, true, true); | ||
| 8923 | const result = try block.addBitCast(dest_ty, int_val); | ||
| 8924 | if (!dest_ty.isNonexhaustiveEnum(zcu) and zcu.backendSupportsFeature(.is_named_enum_value)) { | ||
| 8925 | const ok = try block.addUnOp(.is_named_enum_value, result); | ||
| 8926 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); | ||
| 8927 | } | ||
| 8928 | return result; | ||
| 8929 | } | 8917 | } |
| 8918 | return block.addTyOp(.intcast_safe, dest_ty, operand); | ||
| 8930 | } | 8919 | } |
| 8931 | return block.addTyOp(.intcast, dest_ty, operand); | 8920 | return block.addTyOp(.intcast, dest_ty, operand); |
| 8932 | } | 8921 | } |
| ... | @@ -9309,7 +9298,7 @@ fn zirFunc( | ... | @@ -9309,7 +9298,7 @@ fn zirFunc( |
| 9309 | const ret_ty: Type = if (extra.data.ret_ty.is_generic) | 9298 | const ret_ty: Type = if (extra.data.ret_ty.is_generic) |
| 9310 | .generic_poison | 9299 | .generic_poison |
| 9311 | else switch (extra.data.ret_ty.body_len) { | 9300 | else switch (extra.data.ret_ty.body_len) { |
| 9312 | 0 => Type.void, | 9301 | 0 => .void, |
| 9313 | 1 => blk: { | 9302 | 1 => blk: { |
| 9314 | const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | 9303 | const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 9315 | extra_index += 1; | 9304 | extra_index += 1; |
| ... | @@ -9319,7 +9308,7 @@ fn zirFunc( | ... | @@ -9319,7 +9308,7 @@ fn zirFunc( |
| 9319 | const ret_ty_body = sema.code.bodySlice(extra_index, extra.data.ret_ty.body_len); | 9308 | const ret_ty_body = sema.code.bodySlice(extra_index, extra.data.ret_ty.body_len); |
| 9320 | extra_index += ret_ty_body.len; | 9309 | extra_index += ret_ty_body.len; |
| 9321 | 9310 | ||
| 9322 | const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, .{ .simple = .function_ret_ty }); | 9311 | const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, .type, .{ .simple = .function_ret_ty }); |
| 9323 | break :blk ret_ty_val.toType(); | 9312 | break :blk ret_ty_val.toType(); |
| 9324 | }, | 9313 | }, |
| 9325 | }; | 9314 | }; |
| ... | @@ -9649,7 +9638,7 @@ fn funcCommon( | ... | @@ -9649,7 +9638,7 @@ fn funcCommon( |
| 9649 | 9638 | ||
| 9650 | var comptime_bits: u32 = 0; | 9639 | var comptime_bits: u32 = 0; |
| 9651 | for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| { | 9640 | for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| { |
| 9652 | const param_ty = Type.fromInterned(param_ty_ip); | 9641 | const param_ty: Type = .fromInterned(param_ty_ip); |
| 9653 | const is_noalias = blk: { | 9642 | const is_noalias = blk: { |
| 9654 | const index = std.math.cast(u5, i) orelse break :blk false; | 9643 | const index = std.math.cast(u5, i) orelse break :blk false; |
| 9655 | break :blk @as(u1, @truncate(noalias_bits >> index)) != 0; | 9644 | break :blk @as(u1, @truncate(noalias_bits >> index)) != 0; |
| ... | @@ -9870,7 +9859,7 @@ fn finishFunc( | ... | @@ -9870,7 +9859,7 @@ fn finishFunc( |
| 9870 | const return_type: Type = if (opt_func_index == .none or ret_poison) | 9859 | const return_type: Type = if (opt_func_index == .none or ret_poison) |
| 9871 | bare_return_type | 9860 | bare_return_type |
| 9872 | else | 9861 | else |
| 9873 | Type.fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index))); | 9862 | .fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index))); |
| 9874 | 9863 | ||
| 9875 | if (!return_type.isValidReturnType(zcu)) { | 9864 | if (!return_type.isValidReturnType(zcu)) { |
| 9876 | const opaque_str = if (return_type.zigTypeTag(zcu) == .@"opaque") "opaque " else ""; | 9865 | const opaque_str = if (return_type.zigTypeTag(zcu) == .@"opaque") "opaque " else ""; |
| ... | @@ -10130,14 +10119,14 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10130,14 +10119,14 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10130 | if (try sema.resolveValue(operand)) |operand_val| ct: { | 10119 | if (try sema.resolveValue(operand)) |operand_val| ct: { |
| 10131 | if (!is_vector) { | 10120 | if (!is_vector) { |
| 10132 | if (operand_val.isUndef(zcu)) { | 10121 | if (operand_val.isUndef(zcu)) { |
| 10133 | return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern()); | 10122 | return .undef_usize; |
| 10134 | } | 10123 | } |
| 10135 | const addr = try operand_val.getUnsignedIntSema(pt) orelse { | 10124 | const addr = try operand_val.getUnsignedIntSema(pt) orelse { |
| 10136 | // Wasn't an integer pointer. This is a runtime operation. | 10125 | // Wasn't an integer pointer. This is a runtime operation. |
| 10137 | break :ct; | 10126 | break :ct; |
| 10138 | }; | 10127 | }; |
| 10139 | return Air.internedToRef((try pt.intValue( | 10128 | return Air.internedToRef((try pt.intValue( |
| 10140 | Type.usize, | 10129 | .usize, |
| 10141 | addr, | 10130 | addr, |
| 10142 | )).toIntern()); | 10131 | )).toIntern()); |
| 10143 | } | 10132 | } |
| ... | @@ -10145,7 +10134,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10145,7 +10134,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10145 | for (new_elems, 0..) |*new_elem, i| { | 10134 | for (new_elems, 0..) |*new_elem, i| { |
| 10146 | const ptr_val = try operand_val.elemValue(pt, i); | 10135 | const ptr_val = try operand_val.elemValue(pt, i); |
| 10147 | if (ptr_val.isUndef(zcu)) { | 10136 | if (ptr_val.isUndef(zcu)) { |
| 10148 | new_elem.* = (try pt.undefValue(Type.usize)).toIntern(); | 10137 | new_elem.* = .undef_usize; |
| 10149 | continue; | 10138 | continue; |
| 10150 | } | 10139 | } |
| 10151 | const addr = try ptr_val.getUnsignedIntSema(pt) orelse { | 10140 | const addr = try ptr_val.getUnsignedIntSema(pt) orelse { |
| ... | @@ -10153,7 +10142,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10153,7 +10142,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10153 | break :ct; | 10142 | break :ct; |
| 10154 | }; | 10143 | }; |
| 10155 | new_elem.* = (try pt.intValue( | 10144 | new_elem.* = (try pt.intValue( |
| 10156 | Type.usize, | 10145 | .usize, |
| 10157 | addr, | 10146 | addr, |
| 10158 | )).toIntern(); | 10147 | )).toIntern(); |
| 10159 | } | 10148 | } |
| ... | @@ -10165,16 +10154,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10165,16 +10154,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10165 | try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); | 10154 | try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); |
| 10166 | try sema.validateRuntimeValue(block, ptr_src, operand); | 10155 | try sema.validateRuntimeValue(block, ptr_src, operand); |
| 10167 | try sema.checkLogicalPtrOperation(block, ptr_src, ptr_ty); | 10156 | try sema.checkLogicalPtrOperation(block, ptr_src, ptr_ty); |
| 10168 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 10157 | return block.addBitCast(dest_ty, operand); |
| 10169 | return block.addBitCast(dest_ty, operand); | ||
| 10170 | } | ||
| 10171 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | ||
| 10172 | for (new_elems, 0..) |*new_elem, i| { | ||
| 10173 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 10174 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | ||
| 10175 | new_elem.* = try block.addBitCast(.usize, old_elem); | ||
| 10176 | } | ||
| 10177 | return block.addAggregateInit(dest_ty, new_elems); | ||
| 10178 | } | 10158 | } |
| 10179 | 10159 | ||
| 10180 | fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 10160 | fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -10283,7 +10263,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10283,7 +10263,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10283 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast"); | 10263 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast"); |
| 10284 | const operand = try sema.resolveInst(extra.rhs); | 10264 | const operand = try sema.resolveInst(extra.rhs); |
| 10285 | 10265 | ||
| 10286 | return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src, true, false); | 10266 | return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src); |
| 10287 | } | 10267 | } |
| 10288 | 10268 | ||
| 10289 | fn intCast( | 10269 | fn intCast( |
| ... | @@ -10294,8 +10274,6 @@ fn intCast( | ... | @@ -10294,8 +10274,6 @@ fn intCast( |
| 10294 | dest_ty_src: LazySrcLoc, | 10274 | dest_ty_src: LazySrcLoc, |
| 10295 | operand: Air.Inst.Ref, | 10275 | operand: Air.Inst.Ref, |
| 10296 | operand_src: LazySrcLoc, | 10276 | operand_src: LazySrcLoc, |
| 10297 | runtime_safety: bool, | ||
| 10298 | safety_panics_are_enum: bool, | ||
| 10299 | ) CompileError!Air.Inst.Ref { | 10277 | ) CompileError!Air.Inst.Ref { |
| 10300 | const pt = sema.pt; | 10278 | const pt = sema.pt; |
| 10301 | const zcu = pt.zcu; | 10279 | const zcu = pt.zcu; |
| ... | @@ -10314,7 +10292,7 @@ fn intCast( | ... | @@ -10314,7 +10292,7 @@ fn intCast( |
| 10314 | 10292 | ||
| 10315 | if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| { | 10293 | if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| { |
| 10316 | // requirement: intCast(u0, input) iff input == 0 | 10294 | // requirement: intCast(u0, input) iff input == 0 |
| 10317 | if (runtime_safety and block.wantSafety()) { | 10295 | if (block.wantSafety()) { |
| 10318 | try sema.requireRuntimeBlock(block, src, operand_src); | 10296 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 10319 | const wanted_info = dest_scalar_ty.intInfo(zcu); | 10297 | const wanted_info = dest_scalar_ty.intInfo(zcu); |
| 10320 | const wanted_bits = wanted_info.bits; | 10298 | const wanted_bits = wanted_info.bits; |
| ... | @@ -10331,7 +10309,7 @@ fn intCast( | ... | @@ -10331,7 +10309,7 @@ fn intCast( |
| 10331 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); | 10309 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); |
| 10332 | break :ok is_in_range; | 10310 | break :ok is_in_range; |
| 10333 | }; | 10311 | }; |
| 10334 | try sema.addSafetyCheck(block, src, ok, if (safety_panics_are_enum) .invalid_enum_value else .cast_truncated_data); | 10312 | try sema.addSafetyCheck(block, src, ok, .integer_out_of_bounds); |
| 10335 | } | 10313 | } |
| 10336 | } | 10314 | } |
| 10337 | 10315 | ||
| ... | @@ -10339,91 +10317,11 @@ fn intCast( | ... | @@ -10339,91 +10317,11 @@ fn intCast( |
| 10339 | } | 10317 | } |
| 10340 | 10318 | ||
| 10341 | try sema.requireRuntimeBlock(block, src, operand_src); | 10319 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 10342 | if (runtime_safety and block.wantSafety()) { | 10320 | if (block.wantSafety()) { |
| 10343 | if (zcu.backendSupportsFeature(.safety_checked_instructions)) { | 10321 | if (zcu.backendSupportsFeature(.panic_fn)) { |
| 10344 | _ = try sema.preparePanicId(src, .negative_to_unsigned); | 10322 | _ = try sema.preparePanicId(src, .integer_out_of_bounds); |
| 10345 | _ = try sema.preparePanicId(src, .cast_truncated_data); | ||
| 10346 | return block.addTyOp(.intcast_safe, dest_ty, operand); | ||
| 10347 | } | ||
| 10348 | const actual_info = operand_scalar_ty.intInfo(zcu); | ||
| 10349 | const wanted_info = dest_scalar_ty.intInfo(zcu); | ||
| 10350 | const actual_bits = actual_info.bits; | ||
| 10351 | const wanted_bits = wanted_info.bits; | ||
| 10352 | const actual_value_bits = actual_bits - @intFromBool(actual_info.signedness == .signed); | ||
| 10353 | const wanted_value_bits = wanted_bits - @intFromBool(wanted_info.signedness == .signed); | ||
| 10354 | |||
| 10355 | // range shrinkage | ||
| 10356 | // requirement: int value fits into target type | ||
| 10357 | if (wanted_value_bits < actual_value_bits) { | ||
| 10358 | const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(pt, operand_scalar_ty); | ||
| 10359 | const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar); | ||
| 10360 | const dest_max = Air.internedToRef(dest_max_val.toIntern()); | ||
| 10361 | |||
| 10362 | if (actual_info.signedness == .signed) { | ||
| 10363 | const diff = try block.addBinOp(.sub_wrap, dest_max, operand); | ||
| 10364 | |||
| 10365 | // Reinterpret the sign-bit as part of the value. This will make | ||
| 10366 | // negative differences (`operand` > `dest_max`) appear too big. | ||
| 10367 | const unsigned_scalar_operand_ty = try pt.intType(.unsigned, actual_bits); | ||
| 10368 | const unsigned_operand_ty = if (is_vector) try pt.vectorType(.{ | ||
| 10369 | .len = dest_ty.vectorLen(zcu), | ||
| 10370 | .child = unsigned_scalar_operand_ty.toIntern(), | ||
| 10371 | }) else unsigned_scalar_operand_ty; | ||
| 10372 | const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff); | ||
| 10373 | |||
| 10374 | // If the destination type is signed, then we need to double its | ||
| 10375 | // range to account for negative values. | ||
| 10376 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { | ||
| 10377 | const one_scalar = try pt.intValue(unsigned_scalar_operand_ty, 1); | ||
| 10378 | const one = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ | ||
| 10379 | .ty = unsigned_operand_ty.toIntern(), | ||
| 10380 | .storage = .{ .repeated_elem = one_scalar.toIntern() }, | ||
| 10381 | } })) else one_scalar; | ||
| 10382 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, pt); | ||
| 10383 | const result = try arith.addWithOverflow(sema, unsigned_operand_ty, range_minus_one, one); | ||
| 10384 | assert(result.overflow_bit.compareAllWithZero(.eq, zcu)); | ||
| 10385 | break :range_val result.wrapped_result; | ||
| 10386 | } else try pt.getCoerced(dest_max_val, unsigned_operand_ty); | ||
| 10387 | const dest_range = Air.internedToRef(dest_range_val.toIntern()); | ||
| 10388 | |||
| 10389 | const ok = if (is_vector) ok: { | ||
| 10390 | const is_in_range = try block.addCmpVector(diff_unsigned, dest_range, .lte); | ||
| 10391 | const all_in_range = try block.addReduce(is_in_range, .And); | ||
| 10392 | break :ok all_in_range; | ||
| 10393 | } else ok: { | ||
| 10394 | const is_in_range = try block.addBinOp(.cmp_lte, diff_unsigned, dest_range); | ||
| 10395 | break :ok is_in_range; | ||
| 10396 | }; | ||
| 10397 | // TODO negative_to_unsigned? | ||
| 10398 | try sema.addSafetyCheck(block, src, ok, if (safety_panics_are_enum) .invalid_enum_value else .cast_truncated_data); | ||
| 10399 | } else { | ||
| 10400 | const ok = if (is_vector) ok: { | ||
| 10401 | const is_in_range = try block.addCmpVector(operand, dest_max, .lte); | ||
| 10402 | const all_in_range = try block.addReduce(is_in_range, .And); | ||
| 10403 | break :ok all_in_range; | ||
| 10404 | } else ok: { | ||
| 10405 | const is_in_range = try block.addBinOp(.cmp_lte, operand, dest_max); | ||
| 10406 | break :ok is_in_range; | ||
| 10407 | }; | ||
| 10408 | try sema.addSafetyCheck(block, src, ok, if (safety_panics_are_enum) .invalid_enum_value else .cast_truncated_data); | ||
| 10409 | } | ||
| 10410 | } else if (actual_info.signedness == .signed and wanted_info.signedness == .unsigned) { | ||
| 10411 | // no shrinkage, yes sign loss | ||
| 10412 | // requirement: signed to unsigned >= 0 | ||
| 10413 | const ok = if (is_vector) ok: { | ||
| 10414 | const scalar_zero = try pt.intValue(operand_scalar_ty, 0); | ||
| 10415 | const zero_val = try sema.splat(operand_ty, scalar_zero); | ||
| 10416 | const zero_inst = Air.internedToRef(zero_val.toIntern()); | ||
| 10417 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); | ||
| 10418 | const all_in_range = try block.addReduce(is_in_range, .And); | ||
| 10419 | break :ok all_in_range; | ||
| 10420 | } else ok: { | ||
| 10421 | const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern()); | ||
| 10422 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); | ||
| 10423 | break :ok is_in_range; | ||
| 10424 | }; | ||
| 10425 | try sema.addSafetyCheck(block, src, ok, if (safety_panics_are_enum) .invalid_enum_value else .negative_to_unsigned); | ||
| 10426 | } | 10323 | } |
| 10324 | return block.addTyOp(.intcast_safe, dest_ty, operand); | ||
| 10427 | } | 10325 | } |
| 10428 | return block.addTyOp(.intcast, dest_ty, operand); | 10326 | return block.addTyOp(.intcast, dest_ty, operand); |
| 10429 | } | 10327 | } |
| ... | @@ -10640,17 +10538,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -10640,17 +10538,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10640 | if (dst_bits >= src_bits) { | 10538 | if (dst_bits >= src_bits) { |
| 10641 | return sema.coerce(block, dest_ty, operand, operand_src); | 10539 | return sema.coerce(block, dest_ty, operand, operand_src); |
| 10642 | } | 10540 | } |
| 10643 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 10541 | return block.addTyOp(.fptrunc, dest_ty, operand); |
| 10644 | return block.addTyOp(.fptrunc, dest_ty, operand); | ||
| 10645 | } | ||
| 10646 | const vec_len = operand_ty.vectorLen(zcu); | ||
| 10647 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len); | ||
| 10648 | for (new_elems, 0..) |*new_elem, i| { | ||
| 10649 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 10650 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | ||
| 10651 | new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem); | ||
| 10652 | } | ||
| 10653 | return block.addAggregateInit(dest_ty, new_elems); | ||
| 10654 | } | 10542 | } |
| 10655 | 10543 | ||
| 10656 | fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 10544 | fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -10675,7 +10563,7 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10675,7 +10563,7 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10675 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 10563 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 10676 | const array = try sema.resolveInst(extra.lhs); | 10564 | const array = try sema.resolveInst(extra.lhs); |
| 10677 | const uncoerced_elem_index = try sema.resolveInst(extra.rhs); | 10565 | const uncoerced_elem_index = try sema.resolveInst(extra.rhs); |
| 10678 | const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src); | 10566 | const elem_index = try sema.coerce(block, .usize, uncoerced_elem_index, elem_index_src); |
| 10679 | return sema.elemVal(block, src, array, elem_index, elem_index_src, true); | 10567 | return sema.elemVal(block, src, array, elem_index, elem_index_src, true); |
| 10680 | } | 10568 | } |
| 10681 | 10569 | ||
| ... | @@ -10685,7 +10573,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10685,7 +10573,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10685 | 10573 | ||
| 10686 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm; | 10574 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm; |
| 10687 | const array = try sema.resolveInst(inst_data.operand); | 10575 | const array = try sema.resolveInst(inst_data.operand); |
| 10688 | const elem_index = try sema.pt.intRef(Type.usize, inst_data.idx); | 10576 | const elem_index = try sema.pt.intRef(.usize, inst_data.idx); |
| 10689 | return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false); | 10577 | return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false); |
| 10690 | } | 10578 | } |
| 10691 | 10579 | ||
| ... | @@ -10728,7 +10616,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10728,7 +10616,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10728 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 10616 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 10729 | const array_ptr = try sema.resolveInst(extra.lhs); | 10617 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 10730 | const uncoerced_elem_index = try sema.resolveInst(extra.rhs); | 10618 | const uncoerced_elem_index = try sema.resolveInst(extra.rhs); |
| 10731 | const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src); | 10619 | const elem_index = try sema.coerce(block, .usize, uncoerced_elem_index, elem_index_src); |
| 10732 | return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true); | 10620 | return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true); |
| 10733 | } | 10621 | } |
| 10734 | 10622 | ||
| ... | @@ -10742,7 +10630,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile | ... | @@ -10742,7 +10630,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile |
| 10742 | const src = block.nodeOffset(inst_data.src_node); | 10630 | const src = block.nodeOffset(inst_data.src_node); |
| 10743 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; | 10631 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; |
| 10744 | const array_ptr = try sema.resolveInst(extra.ptr); | 10632 | const array_ptr = try sema.resolveInst(extra.ptr); |
| 10745 | const elem_index = try pt.intRef(Type.usize, extra.index); | 10633 | const elem_index = try pt.intRef(.usize, extra.index); |
| 10746 | const array_ty = sema.typeOf(array_ptr).childType(zcu); | 10634 | const array_ty = sema.typeOf(array_ptr).childType(zcu); |
| 10747 | switch (array_ty.zigTypeTag(zcu)) { | 10635 | switch (array_ty.zigTypeTag(zcu)) { |
| 10748 | .array, .vector => {}, | 10636 | .array, .vector => {}, |
| ... | @@ -11104,7 +10992,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11104,7 +10992,7 @@ const SwitchProngAnalysis = struct { |
| 11104 | if (operand_ty.zigTypeTag(zcu) == .@"union") { | 10992 | if (operand_ty.zigTypeTag(zcu) == .@"union") { |
| 11105 | const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?); | 10993 | const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?); |
| 11106 | const union_obj = zcu.typeToUnion(operand_ty).?; | 10994 | const union_obj = zcu.typeToUnion(operand_ty).?; |
| 11107 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 10995 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 11108 | if (capture_byref) { | 10996 | if (capture_byref) { |
| 11109 | const ptr_field_ty = try pt.ptrTypeSema(.{ | 10997 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 11110 | .child = field_ty.toIntern(), | 10998 | .child = field_ty.toIntern(), |
| ... | @@ -11154,7 +11042,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11154,7 +11042,7 @@ const SwitchProngAnalysis = struct { |
| 11154 | const first_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable; | 11042 | const first_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable; |
| 11155 | 11043 | ||
| 11156 | const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?; | 11044 | const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?; |
| 11157 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[first_field_index]); | 11045 | const first_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_field_index]); |
| 11158 | 11046 | ||
| 11159 | const field_indices = try sema.arena.alloc(u32, case_vals.len); | 11047 | const field_indices = try sema.arena.alloc(u32, case_vals.len); |
| 11160 | for (case_vals, field_indices) |item, *field_idx| { | 11048 | for (case_vals, field_indices) |item, *field_idx| { |
| ... | @@ -11165,7 +11053,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11165,7 +11053,7 @@ const SwitchProngAnalysis = struct { |
| 11165 | // Fast path: if all the operands are the same type already, we don't need to hit | 11053 | // Fast path: if all the operands are the same type already, we don't need to hit |
| 11166 | // PTR! This will also allow us to emit simpler code. | 11054 | // PTR! This will also allow us to emit simpler code. |
| 11167 | const same_types = for (field_indices[1..]) |field_idx| { | 11055 | const same_types = for (field_indices[1..]) |field_idx| { |
| 11168 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11056 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11169 | if (!field_ty.eql(first_field_ty, zcu)) break false; | 11057 | if (!field_ty.eql(first_field_ty, zcu)) break false; |
| 11170 | } else true; | 11058 | } else true; |
| 11171 | 11059 | ||
| ... | @@ -11173,7 +11061,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11173,7 +11061,7 @@ const SwitchProngAnalysis = struct { |
| 11173 | // We need values to run PTR on, so make a bunch of undef constants. | 11061 | // We need values to run PTR on, so make a bunch of undef constants. |
| 11174 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); | 11062 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); |
| 11175 | for (dummy_captures, field_indices) |*dummy, field_idx| { | 11063 | for (dummy_captures, field_indices) |*dummy, field_idx| { |
| 11176 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11064 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11177 | dummy.* = try pt.undefRef(field_ty); | 11065 | dummy.* = try pt.undefRef(field_ty); |
| 11178 | } | 11066 | } |
| 11179 | 11067 | ||
| ... | @@ -11208,7 +11096,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11208,7 +11096,7 @@ const SwitchProngAnalysis = struct { |
| 11208 | // We need values to run PTR on, so make a bunch of undef constants. | 11096 | // We need values to run PTR on, so make a bunch of undef constants. |
| 11209 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); | 11097 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); |
| 11210 | for (field_indices, dummy_captures) |field_idx, *dummy| { | 11098 | for (field_indices, dummy_captures) |field_idx, *dummy| { |
| 11211 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11099 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11212 | const field_ptr_ty = try pt.ptrTypeSema(.{ | 11100 | const field_ptr_ty = try pt.ptrTypeSema(.{ |
| 11213 | .child = field_ty.toIntern(), | 11101 | .child = field_ty.toIntern(), |
| 11214 | .flags = .{ | 11102 | .flags = .{ |
| ... | @@ -11271,7 +11159,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11271,7 +11159,7 @@ const SwitchProngAnalysis = struct { |
| 11271 | // If we can, try to avoid that using in-memory coercions. | 11159 | // If we can, try to avoid that using in-memory coercions. |
| 11272 | const first_non_imc = in_mem: { | 11160 | const first_non_imc = in_mem: { |
| 11273 | for (field_indices, 0..) |field_idx, i| { | 11161 | for (field_indices, 0..) |field_idx, i| { |
| 11274 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11162 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11275 | if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) { | 11163 | if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) { |
| 11276 | break :in_mem i; | 11164 | break :in_mem i; |
| 11277 | } | 11165 | } |
| ... | @@ -11294,7 +11182,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11294,7 +11182,7 @@ const SwitchProngAnalysis = struct { |
| 11294 | { | 11182 | { |
| 11295 | const next = first_non_imc + 1; | 11183 | const next = first_non_imc + 1; |
| 11296 | for (field_indices[next..], next..) |field_idx, i| { | 11184 | for (field_indices[next..], next..) |field_idx, i| { |
| 11297 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11185 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11298 | if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) { | 11186 | if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) { |
| 11299 | in_mem_coercible.unset(i); | 11187 | in_mem_coercible.unset(i); |
| 11300 | } | 11188 | } |
| ... | @@ -11341,7 +11229,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11341,7 +11229,7 @@ const SwitchProngAnalysis = struct { |
| 11341 | }; | 11229 | }; |
| 11342 | 11230 | ||
| 11343 | const field_idx = field_indices[idx]; | 11231 | const field_idx = field_indices[idx]; |
| 11344 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11232 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11345 | const uncoerced = try coerce_block.addStructFieldVal(operand_val, field_idx, field_ty); | 11233 | const uncoerced = try coerce_block.addStructFieldVal(operand_val, field_idx, field_ty); |
| 11346 | const coerced = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src); | 11234 | const coerced = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src); |
| 11347 | _ = try coerce_block.addBr(capture_block_inst, coerced); | 11235 | _ = try coerce_block.addBr(capture_block_inst, coerced); |
| ... | @@ -11365,7 +11253,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11365,7 +11253,7 @@ const SwitchProngAnalysis = struct { |
| 11365 | 11253 | ||
| 11366 | const first_imc_item_idx = in_mem_coercible.findFirstSet().?; | 11254 | const first_imc_item_idx = in_mem_coercible.findFirstSet().?; |
| 11367 | const first_imc_field_idx = field_indices[first_imc_item_idx]; | 11255 | const first_imc_field_idx = field_indices[first_imc_item_idx]; |
| 11368 | const first_imc_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[first_imc_field_idx]); | 11256 | const first_imc_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_imc_field_idx]); |
| 11369 | const uncoerced = try coerce_block.addStructFieldVal(operand_val, first_imc_field_idx, first_imc_field_ty); | 11257 | const uncoerced = try coerce_block.addStructFieldVal(operand_val, first_imc_field_idx, first_imc_field_ty); |
| 11370 | const coerced = try coerce_block.addBitCast(capture_ty, uncoerced); | 11258 | const coerced = try coerce_block.addBitCast(capture_ty, uncoerced); |
| 11371 | _ = try coerce_block.addBr(capture_block_inst, coerced); | 11259 | _ = try coerce_block.addBr(capture_block_inst, coerced); |
| ... | @@ -13165,7 +13053,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -13165,7 +13053,7 @@ fn analyzeSwitchRuntimeBlock( |
| 13165 | for (seen_enum_fields, 0..) |seen_field, index| { | 13053 | for (seen_enum_fields, 0..) |seen_field, index| { |
| 13166 | if (seen_field != null) continue; | 13054 | if (seen_field != null) continue; |
| 13167 | const union_obj = zcu.typeToUnion(maybe_union_ty).?; | 13055 | const union_obj = zcu.typeToUnion(maybe_union_ty).?; |
| 13168 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[index]); | 13056 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[index]); |
| 13169 | if (field_ty.zigTypeTag(zcu) != .noreturn) break true; | 13057 | if (field_ty.zigTypeTag(zcu) != .noreturn) break true; |
| 13170 | } else false | 13058 | } else false |
| 13171 | else | 13059 | else |
| ... | @@ -13490,7 +13378,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -13490,7 +13378,7 @@ const RangeSetUnhandledIterator = struct { |
| 13490 | inline .u64, .i64 => |val_int| { | 13378 | inline .u64, .i64 => |val_int| { |
| 13491 | const next_int = @addWithOverflow(val_int, 1); | 13379 | const next_int = @addWithOverflow(val_int, 1); |
| 13492 | if (next_int[1] == 0) | 13380 | if (next_int[1] == 0) |
| 13493 | return (try it.pt.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern(); | 13381 | return (try it.pt.intValue(.fromInterned(int.ty), next_int[0])).toIntern(); |
| 13494 | }, | 13382 | }, |
| 13495 | .big_int => {}, | 13383 | .big_int => {}, |
| 13496 | .lazy_align, .lazy_size => unreachable, | 13384 | .lazy_align, .lazy_size => unreachable, |
| ... | @@ -13506,7 +13394,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -13506,7 +13394,7 @@ const RangeSetUnhandledIterator = struct { |
| 13506 | ); | 13394 | ); |
| 13507 | 13395 | ||
| 13508 | result_bigint.addScalar(val_bigint, 1); | 13396 | result_bigint.addScalar(val_bigint, 1); |
| 13509 | return (try it.pt.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern(); | 13397 | return (try it.pt.intValue_big(.fromInterned(int.ty), result_bigint.toConst())).toIntern(); |
| 13510 | } | 13398 | } |
| 13511 | 13399 | ||
| 13512 | fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index { | 13400 | fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index { |
| ... | @@ -13636,7 +13524,7 @@ fn validateErrSetSwitch( | ... | @@ -13636,7 +13524,7 @@ fn validateErrSetSwitch( |
| 13636 | .{}, | 13524 | .{}, |
| 13637 | ); | 13525 | ); |
| 13638 | } | 13526 | } |
| 13639 | return Type.anyerror; | 13527 | return .anyerror; |
| 13640 | }, | 13528 | }, |
| 13641 | else => |err_set_ty_index| else_validation: { | 13529 | else => |err_set_ty_index| else_validation: { |
| 13642 | const error_names = ip.indexToKey(err_set_ty_index).error_set_type.names; | 13530 | const error_names = ip.indexToKey(err_set_ty_index).error_set_type.names; |
| ... | @@ -13839,7 +13727,7 @@ fn validateSwitchItemBool( | ... | @@ -13839,7 +13727,7 @@ fn validateSwitchItemBool( |
| 13839 | item_ref: Zir.Inst.Ref, | 13727 | item_ref: Zir.Inst.Ref, |
| 13840 | item_src: LazySrcLoc, | 13728 | item_src: LazySrcLoc, |
| 13841 | ) CompileError!Air.Inst.Ref { | 13729 | ) CompileError!Air.Inst.Ref { |
| 13842 | const item = try sema.resolveSwitchItemVal(block, item_ref, Type.bool, item_src); | 13730 | const item = try sema.resolveSwitchItemVal(block, item_ref, .bool, item_src); |
| 13843 | if (Value.fromInterned(item.val).toBool()) { | 13731 | if (Value.fromInterned(item.val).toBool()) { |
| 13844 | true_count.* += 1; | 13732 | true_count.* += 1; |
| 13845 | } else { | 13733 | } else { |
| ... | @@ -14224,7 +14112,7 @@ fn zirShl( | ... | @@ -14224,7 +14112,7 @@ fn zirShl( |
| 14224 | return lhs; | 14112 | return lhs; |
| 14225 | } | 14113 | } |
| 14226 | if (air_tag != .shl_sat and scalar_ty.zigTypeTag(zcu) != .comptime_int) { | 14114 | if (air_tag != .shl_sat and scalar_ty.zigTypeTag(zcu) != .comptime_int) { |
| 14227 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(zcu).bits); | 14115 | const bit_value = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits); |
| 14228 | if (rhs_ty.zigTypeTag(zcu) == .vector) { | 14116 | if (rhs_ty.zigTypeTag(zcu) == .vector) { |
| 14229 | var i: usize = 0; | 14117 | var i: usize = 0; |
| 14230 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | 14118 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| ... | @@ -14335,7 +14223,7 @@ fn zirShl( | ... | @@ -14335,7 +14223,7 @@ fn zirShl( |
| 14335 | } | 14223 | } |
| 14336 | 14224 | ||
| 14337 | if (air_tag == .shl_exact) { | 14225 | if (air_tag == .shl_exact) { |
| 14338 | const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(lhs_ty); | 14226 | const op_ov_tuple_ty = try pt.overflowArithmeticTupleType(lhs_ty); |
| 14339 | const op_ov = try block.addInst(.{ | 14227 | const op_ov = try block.addInst(.{ |
| 14340 | .tag = .shl_with_overflow, | 14228 | .tag = .shl_with_overflow, |
| 14341 | .data = .{ .ty_pl = .{ | 14229 | .data = .{ .ty_pl = .{ |
| ... | @@ -14351,8 +14239,7 @@ fn zirShl( | ... | @@ -14351,8 +14239,7 @@ fn zirShl( |
| 14351 | try block.addReduce(ov_bit, .Or) | 14239 | try block.addReduce(ov_bit, .Or) |
| 14352 | else | 14240 | else |
| 14353 | ov_bit; | 14241 | ov_bit; |
| 14354 | const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); | 14242 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, .zero_u1); |
| 14355 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | ||
| 14356 | 14243 | ||
| 14357 | try sema.addSafetyCheck(block, src, no_ov, .shl_overflow); | 14244 | try sema.addSafetyCheck(block, src, no_ov, .shl_overflow); |
| 14358 | return sema.tupleFieldValByIndex(block, op_ov, 0, op_ov_tuple_ty); | 14245 | return sema.tupleFieldValByIndex(block, op_ov, 0, op_ov_tuple_ty); |
| ... | @@ -14406,7 +14293,7 @@ fn zirShr( | ... | @@ -14406,7 +14293,7 @@ fn zirShr( |
| 14406 | return lhs; | 14293 | return lhs; |
| 14407 | } | 14294 | } |
| 14408 | if (scalar_ty.zigTypeTag(zcu) != .comptime_int) { | 14295 | if (scalar_ty.zigTypeTag(zcu) != .comptime_int) { |
| 14409 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(zcu).bits); | 14296 | const bit_value = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits); |
| 14410 | if (rhs_ty.zigTypeTag(zcu) == .vector) { | 14297 | if (rhs_ty.zigTypeTag(zcu) == .vector) { |
| 14411 | var i: usize = 0; | 14298 | var i: usize = 0; |
| 14412 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | 14299 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| ... | @@ -14689,7 +14576,7 @@ fn analyzeTupleCat( | ... | @@ -14689,7 +14576,7 @@ fn analyzeTupleCat( |
| 14689 | try sema.tupleFieldValByIndex(block, rhs, i, rhs_ty); | 14576 | try sema.tupleFieldValByIndex(block, rhs, i, rhs_ty); |
| 14690 | } | 14577 | } |
| 14691 | 14578 | ||
| 14692 | return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs); | 14579 | return block.addAggregateInit(.fromInterned(tuple_ty), element_refs); |
| 14693 | } | 14580 | } |
| 14694 | 14581 | ||
| 14695 | fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 14582 | fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -14716,7 +14603,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14716,7 +14603,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14716 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 14603 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); |
| 14717 | 14604 | ||
| 14718 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: { | 14605 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: { |
| 14719 | if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined); | 14606 | if (lhs_is_tuple) break :lhs_info undefined; |
| 14720 | return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)}); | 14607 | return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)}); |
| 14721 | }; | 14608 | }; |
| 14722 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse { | 14609 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse { |
| ... | @@ -14892,7 +14779,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14892,7 +14779,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14892 | 14779 | ||
| 14893 | // lhs_dest_slice = dest[0..lhs.len] | 14780 | // lhs_dest_slice = dest[0..lhs.len] |
| 14894 | const slice_ty_ref = Air.internedToRef(slice_ty.toIntern()); | 14781 | const slice_ty_ref = Air.internedToRef(slice_ty.toIntern()); |
| 14895 | const lhs_len_ref = try pt.intRef(Type.usize, lhs_len); | 14782 | const lhs_len_ref = try pt.intRef(.usize, lhs_len); |
| 14896 | const lhs_dest_slice = try block.addInst(.{ | 14783 | const lhs_dest_slice = try block.addInst(.{ |
| 14897 | .tag = .slice, | 14784 | .tag = .slice, |
| 14898 | .data = .{ .ty_pl = .{ | 14785 | .data = .{ .ty_pl = .{ |
| ... | @@ -14907,7 +14794,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14907,7 +14794,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14907 | _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs); | 14794 | _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs); |
| 14908 | 14795 | ||
| 14909 | // rhs_dest_slice = dest[lhs.len..][0..rhs.len] | 14796 | // rhs_dest_slice = dest[lhs.len..][0..rhs.len] |
| 14910 | const rhs_len_ref = try pt.intRef(Type.usize, rhs_len); | 14797 | const rhs_len_ref = try pt.intRef(.usize, rhs_len); |
| 14911 | const rhs_dest_offset = try block.addInst(.{ | 14798 | const rhs_dest_offset = try block.addInst(.{ |
| 14912 | .tag = .ptr_add, | 14799 | .tag = .ptr_add, |
| 14913 | .data = .{ .ty_pl = .{ | 14800 | .data = .{ .ty_pl = .{ |
| ... | @@ -14932,7 +14819,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14932,7 +14819,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14932 | _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs); | 14819 | _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs); |
| 14933 | 14820 | ||
| 14934 | if (res_sent_val) |sent_val| { | 14821 | if (res_sent_val) |sent_val| { |
| 14935 | const elem_index = try pt.intRef(Type.usize, result_len); | 14822 | const elem_index = try pt.intRef(.usize, result_len); |
| 14936 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); | 14823 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); |
| 14937 | const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); | 14824 | const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); |
| 14938 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); | 14825 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| ... | @@ -14943,7 +14830,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14943,7 +14830,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14943 | 14830 | ||
| 14944 | var elem_i: u32 = 0; | 14831 | var elem_i: u32 = 0; |
| 14945 | while (elem_i < lhs_len) : (elem_i += 1) { | 14832 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14946 | const elem_index = try pt.intRef(Type.usize, elem_i); | 14833 | const elem_index = try pt.intRef(.usize, elem_i); |
| 14947 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); | 14834 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); |
| 14948 | const operand_src = block.src(.{ .array_cat_lhs = .{ | 14835 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14949 | .array_cat_offset = inst_data.src_node, | 14836 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14954,8 +14841,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14954,8 +14841,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14954 | } | 14841 | } |
| 14955 | while (elem_i < result_len) : (elem_i += 1) { | 14842 | while (elem_i < result_len) : (elem_i += 1) { |
| 14956 | const rhs_elem_i = elem_i - lhs_len; | 14843 | const rhs_elem_i = elem_i - lhs_len; |
| 14957 | const elem_index = try pt.intRef(Type.usize, elem_i); | 14844 | const elem_index = try pt.intRef(.usize, elem_i); |
| 14958 | const rhs_index = try pt.intRef(Type.usize, rhs_elem_i); | 14845 | const rhs_index = try pt.intRef(.usize, rhs_elem_i); |
| 14959 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); | 14846 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); |
| 14960 | const operand_src = block.src(.{ .array_cat_rhs = .{ | 14847 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14961 | .array_cat_offset = inst_data.src_node, | 14848 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14965,7 +14852,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14965,7 +14852,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14965 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); | 14852 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); |
| 14966 | } | 14853 | } |
| 14967 | if (res_sent_val) |sent_val| { | 14854 | if (res_sent_val) |sent_val| { |
| 14968 | const elem_index = try pt.intRef(Type.usize, result_len); | 14855 | const elem_index = try pt.intRef(.usize, result_len); |
| 14969 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); | 14856 | const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty); |
| 14970 | const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); | 14857 | const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); |
| 14971 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); | 14858 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| ... | @@ -14978,7 +14865,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14978,7 +14865,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14978 | { | 14865 | { |
| 14979 | var elem_i: u32 = 0; | 14866 | var elem_i: u32 = 0; |
| 14980 | while (elem_i < lhs_len) : (elem_i += 1) { | 14867 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14981 | const index = try pt.intRef(Type.usize, elem_i); | 14868 | const index = try pt.intRef(.usize, elem_i); |
| 14982 | const operand_src = block.src(.{ .array_cat_lhs = .{ | 14869 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14983 | .array_cat_offset = inst_data.src_node, | 14870 | .array_cat_offset = inst_data.src_node, |
| 14984 | .elem_index = elem_i, | 14871 | .elem_index = elem_i, |
| ... | @@ -14988,7 +14875,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14988,7 +14875,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14988 | } | 14875 | } |
| 14989 | while (elem_i < result_len) : (elem_i += 1) { | 14876 | while (elem_i < result_len) : (elem_i += 1) { |
| 14990 | const rhs_elem_i = elem_i - lhs_len; | 14877 | const rhs_elem_i = elem_i - lhs_len; |
| 14991 | const index = try pt.intRef(Type.usize, rhs_elem_i); | 14878 | const index = try pt.intRef(.usize, rhs_elem_i); |
| 14992 | const operand_src = block.src(.{ .array_cat_rhs = .{ | 14879 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14993 | .array_cat_offset = inst_data.src_node, | 14880 | .array_cat_offset = inst_data.src_node, |
| 14994 | .elem_index = @intCast(rhs_elem_i), | 14881 | .elem_index = @intCast(rhs_elem_i), |
| ... | @@ -15012,8 +14899,8 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -15012,8 +14899,8 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 15012 | switch (ptr_info.flags.size) { | 14899 | switch (ptr_info.flags.size) { |
| 15013 | .slice => { | 14900 | .slice => { |
| 15014 | const val = try sema.resolveConstDefinedValue(block, src, operand, .{ .simple = .slice_cat_operand }); | 14901 | const val = try sema.resolveConstDefinedValue(block, src, operand, .{ .simple = .slice_cat_operand }); |
| 15015 | return Type.ArrayInfo{ | 14902 | return .{ |
| 15016 | .elem_type = Type.fromInterned(ptr_info.child), | 14903 | .elem_type = .fromInterned(ptr_info.child), |
| 15017 | .sentinel = switch (ptr_info.sentinel) { | 14904 | .sentinel = switch (ptr_info.sentinel) { |
| 15018 | .none => null, | 14905 | .none => null, |
| 15019 | else => Value.fromInterned(ptr_info.sentinel), | 14906 | else => Value.fromInterned(ptr_info.sentinel), |
| ... | @@ -15113,7 +15000,7 @@ fn analyzeTupleMul( | ... | @@ -15113,7 +15000,7 @@ fn analyzeTupleMul( |
| 15113 | @memcpy(element_refs[tuple_len * i ..][0..tuple_len], element_refs[0..tuple_len]); | 15000 | @memcpy(element_refs[tuple_len * i ..][0..tuple_len], element_refs[0..tuple_len]); |
| 15114 | } | 15001 | } |
| 15115 | 15002 | ||
| 15116 | return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs); | 15003 | return block.addAggregateInit(.fromInterned(tuple_ty), element_refs); |
| 15117 | } | 15004 | } |
| 15118 | 15005 | ||
| 15119 | fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15006 | fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -15166,7 +15053,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15166,7 +15053,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15166 | 15053 | ||
| 15167 | if (lhs_ty.isTuple(zcu)) { | 15054 | if (lhs_ty.isTuple(zcu)) { |
| 15168 | // In `**` rhs must be comptime-known, but lhs can be runtime-known | 15055 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 15169 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, .{ .simple = .array_mul_factor }); | 15056 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, .usize, .{ .simple = .array_mul_factor }); |
| 15170 | const factor_casted = try sema.usizeCast(block, rhs_src, factor); | 15057 | const factor_casted = try sema.usizeCast(block, rhs_src, factor); |
| 15171 | return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor_casted); | 15058 | return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor_casted); |
| 15172 | } | 15059 | } |
| ... | @@ -15188,7 +15075,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15188,7 +15075,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15188 | }; | 15075 | }; |
| 15189 | 15076 | ||
| 15190 | // In `**` rhs must be comptime-known, but lhs can be runtime-known | 15077 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 15191 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, .{ .simple = .array_mul_factor }); | 15078 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, .usize, .{ .simple = .array_mul_factor }); |
| 15192 | 15079 | ||
| 15193 | const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch | 15080 | const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch |
| 15194 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); | 15081 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |
| ... | @@ -15246,7 +15133,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15246,7 +15133,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15246 | // to get the same elem values. | 15133 | // to get the same elem values. |
| 15247 | const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len); | 15134 | const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len); |
| 15248 | for (lhs_vals, 0..) |*lhs_val, idx| { | 15135 | for (lhs_vals, 0..) |*lhs_val, idx| { |
| 15249 | const idx_ref = try pt.intRef(Type.usize, idx); | 15136 | const idx_ref = try pt.intRef(.usize, idx); |
| 15250 | lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false); | 15137 | lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false); |
| 15251 | } | 15138 | } |
| 15252 | 15139 | ||
| ... | @@ -15267,14 +15154,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15267,14 +15154,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15267 | var elem_i: usize = 0; | 15154 | var elem_i: usize = 0; |
| 15268 | while (elem_i < result_len) { | 15155 | while (elem_i < result_len) { |
| 15269 | for (lhs_vals) |lhs_val| { | 15156 | for (lhs_vals) |lhs_val| { |
| 15270 | const elem_index = try pt.intRef(Type.usize, elem_i); | 15157 | const elem_index = try pt.intRef(.usize, elem_i); |
| 15271 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 15158 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 15272 | try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store); | 15159 | try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store); |
| 15273 | elem_i += 1; | 15160 | elem_i += 1; |
| 15274 | } | 15161 | } |
| 15275 | } | 15162 | } |
| 15276 | if (lhs_info.sentinel) |sent_val| { | 15163 | if (lhs_info.sentinel) |sent_val| { |
| 15277 | const elem_index = try pt.intRef(Type.usize, result_len); | 15164 | const elem_index = try pt.intRef(.usize, result_len); |
| 15278 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 15165 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 15279 | const init = Air.internedToRef(sent_val.toIntern()); | 15166 | const init = Air.internedToRef(sent_val.toIntern()); |
| 15280 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); | 15167 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| ... | @@ -16131,15 +16018,14 @@ fn zirOverflowArithmetic( | ... | @@ -16131,15 +16018,14 @@ fn zirOverflowArithmetic( |
| 16131 | const maybe_lhs_val = try sema.resolveValue(lhs); | 16018 | const maybe_lhs_val = try sema.resolveValue(lhs); |
| 16132 | const maybe_rhs_val = try sema.resolveValue(rhs); | 16019 | const maybe_rhs_val = try sema.resolveValue(rhs); |
| 16133 | 16020 | ||
| 16134 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); | 16021 | const tuple_ty = try pt.overflowArithmeticTupleType(dest_ty); |
| 16135 | const overflow_ty = Type.fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]); | 16022 | const overflow_ty: Type = .fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]); |
| 16136 | 16023 | ||
| 16137 | var result: struct { | 16024 | var result: struct { |
| 16138 | inst: Air.Inst.Ref = .none, | 16025 | inst: Air.Inst.Ref = .none, |
| 16139 | wrapped: Value = Value.@"unreachable", | 16026 | wrapped: Value = Value.@"unreachable", |
| 16140 | overflow_bit: Value, | 16027 | overflow_bit: Value, |
| 16141 | } = result: { | 16028 | } = result: { |
| 16142 | const zero_bit = try pt.intValue(Type.u1, 0); | ||
| 16143 | switch (zir_tag) { | 16029 | switch (zir_tag) { |
| 16144 | .add_with_overflow => { | 16030 | .add_with_overflow => { |
| 16145 | // If either of the arguments is zero, `false` is returned and the other is stored | 16031 | // If either of the arguments is zero, `false` is returned and the other is stored |
| ... | @@ -16147,12 +16033,12 @@ fn zirOverflowArithmetic( | ... | @@ -16147,12 +16033,12 @@ fn zirOverflowArithmetic( |
| 16147 | // Otherwise, if either of the argument is undefined, undefined is returned. | 16033 | // Otherwise, if either of the argument is undefined, undefined is returned. |
| 16148 | if (maybe_lhs_val) |lhs_val| { | 16034 | if (maybe_lhs_val) |lhs_val| { |
| 16149 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | 16035 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16150 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16036 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs }; |
| 16151 | } | 16037 | } |
| 16152 | } | 16038 | } |
| 16153 | if (maybe_rhs_val) |rhs_val| { | 16039 | if (maybe_rhs_val) |rhs_val| { |
| 16154 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | 16040 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16155 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16041 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16156 | } | 16042 | } |
| 16157 | } | 16043 | } |
| 16158 | if (maybe_lhs_val) |lhs_val| { | 16044 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -16173,7 +16059,7 @@ fn zirOverflowArithmetic( | ... | @@ -16173,7 +16059,7 @@ fn zirOverflowArithmetic( |
| 16173 | if (rhs_val.isUndef(zcu)) { | 16059 | if (rhs_val.isUndef(zcu)) { |
| 16174 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 16060 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16175 | } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { | 16061 | } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16176 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16062 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16177 | } else if (maybe_lhs_val) |lhs_val| { | 16063 | } else if (maybe_lhs_val) |lhs_val| { |
| 16178 | if (lhs_val.isUndef(zcu)) { | 16064 | if (lhs_val.isUndef(zcu)) { |
| 16179 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 16065 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| ... | @@ -16192,9 +16078,9 @@ fn zirOverflowArithmetic( | ... | @@ -16192,9 +16078,9 @@ fn zirOverflowArithmetic( |
| 16192 | if (maybe_lhs_val) |lhs_val| { | 16078 | if (maybe_lhs_val) |lhs_val| { |
| 16193 | if (!lhs_val.isUndef(zcu)) { | 16079 | if (!lhs_val.isUndef(zcu)) { |
| 16194 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { | 16080 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16195 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16081 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16196 | } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { | 16082 | } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| 16197 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16083 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs }; |
| 16198 | } | 16084 | } |
| 16199 | } | 16085 | } |
| 16200 | } | 16086 | } |
| ... | @@ -16202,9 +16088,9 @@ fn zirOverflowArithmetic( | ... | @@ -16202,9 +16088,9 @@ fn zirOverflowArithmetic( |
| 16202 | if (maybe_rhs_val) |rhs_val| { | 16088 | if (maybe_rhs_val) |rhs_val| { |
| 16203 | if (!rhs_val.isUndef(zcu)) { | 16089 | if (!rhs_val.isUndef(zcu)) { |
| 16204 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { | 16090 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16205 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16091 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs }; |
| 16206 | } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { | 16092 | } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| 16207 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16093 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16208 | } | 16094 | } |
| 16209 | } | 16095 | } |
| 16210 | } | 16096 | } |
| ... | @@ -16226,12 +16112,12 @@ fn zirOverflowArithmetic( | ... | @@ -16226,12 +16112,12 @@ fn zirOverflowArithmetic( |
| 16226 | // Oterhwise if either of the arguments is undefined, both results are undefined. | 16112 | // Oterhwise if either of the arguments is undefined, both results are undefined. |
| 16227 | if (maybe_lhs_val) |lhs_val| { | 16113 | if (maybe_lhs_val) |lhs_val| { |
| 16228 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | 16114 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16229 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16115 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16230 | } | 16116 | } |
| 16231 | } | 16117 | } |
| 16232 | if (maybe_rhs_val) |rhs_val| { | 16118 | if (maybe_rhs_val) |rhs_val| { |
| 16233 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | 16119 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16234 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16120 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs }; |
| 16235 | } | 16121 | } |
| 16236 | } | 16122 | } |
| 16237 | if (maybe_lhs_val) |lhs_val| { | 16123 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -16305,24 +16191,6 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { | ... | @@ -16305,24 +16191,6 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 16305 | return Value.fromInterned(repeated); | 16191 | return Value.fromInterned(repeated); |
| 16306 | } | 16192 | } |
| 16307 | 16193 | ||
| 16308 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { | ||
| 16309 | const pt = sema.pt; | ||
| 16310 | const zcu = pt.zcu; | ||
| 16311 | const ip = &zcu.intern_pool; | ||
| 16312 | const ov_ty = if (ty.zigTypeTag(zcu) == .vector) try pt.vectorType(.{ | ||
| 16313 | .len = ty.vectorLen(zcu), | ||
| 16314 | .child = .u1_type, | ||
| 16315 | }) else Type.u1; | ||
| 16316 | |||
| 16317 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; | ||
| 16318 | const values = [2]InternPool.Index{ .none, .none }; | ||
| 16319 | const tuple_ty = try ip.getTupleType(zcu.gpa, pt.tid, .{ | ||
| 16320 | .types = &types, | ||
| 16321 | .values = &values, | ||
| 16322 | }); | ||
| 16323 | return Type.fromInterned(tuple_ty); | ||
| 16324 | } | ||
| 16325 | |||
| 16326 | fn analyzeArithmetic( | 16194 | fn analyzeArithmetic( |
| 16327 | sema: *Sema, | 16195 | sema: *Sema, |
| 16328 | block: *Block, | 16196 | block: *Block, |
| ... | @@ -16380,7 +16248,7 @@ fn analyzeArithmetic( | ... | @@ -16380,7 +16248,7 @@ fn analyzeArithmetic( |
| 16380 | const address = std.math.sub(u64, lhs_ptr.byte_offset, rhs_ptr.byte_offset) catch | 16248 | const address = std.math.sub(u64, lhs_ptr.byte_offset, rhs_ptr.byte_offset) catch |
| 16381 | return sema.fail(block, src, "operation results in overflow", .{}); | 16249 | return sema.fail(block, src, "operation results in overflow", .{}); |
| 16382 | const result = address / elem_size; | 16250 | const result = address / elem_size; |
| 16383 | return try pt.intRef(Type.usize, result); | 16251 | return try pt.intRef(.usize, result); |
| 16384 | } else { | 16252 | } else { |
| 16385 | break :runtime_src lhs_src; | 16253 | break :runtime_src lhs_src; |
| 16386 | } | 16254 | } |
| ... | @@ -16395,7 +16263,7 @@ fn analyzeArithmetic( | ... | @@ -16395,7 +16263,7 @@ fn analyzeArithmetic( |
| 16395 | const lhs_int = try block.addBitCast(.usize, lhs); | 16263 | const lhs_int = try block.addBitCast(.usize, lhs); |
| 16396 | const rhs_int = try block.addBitCast(.usize, rhs); | 16264 | const rhs_int = try block.addBitCast(.usize, rhs); |
| 16397 | const address = try block.addBinOp(.sub_wrap, lhs_int, rhs_int); | 16265 | const address = try block.addBinOp(.sub_wrap, lhs_int, rhs_int); |
| 16398 | return try block.addBinOp(.div_exact, address, try pt.intRef(Type.usize, elem_size)); | 16266 | return try block.addBinOp(.div_exact, address, try pt.intRef(.usize, elem_size)); |
| 16399 | } | 16267 | } |
| 16400 | } else { | 16268 | } else { |
| 16401 | switch (lhs_ty.ptrSize(zcu)) { | 16269 | switch (lhs_ty.ptrSize(zcu)) { |
| ... | @@ -16498,42 +16366,10 @@ fn analyzeArithmetic( | ... | @@ -16498,42 +16366,10 @@ fn analyzeArithmetic( |
| 16498 | } | 16366 | } |
| 16499 | 16367 | ||
| 16500 | if (block.wantSafety() and want_safety and scalar_tag == .int) { | 16368 | if (block.wantSafety() and want_safety and scalar_tag == .int) { |
| 16501 | if (zcu.backendSupportsFeature(.safety_checked_instructions)) { | 16369 | if (air_tag != air_tag_safe and zcu.backendSupportsFeature(.panic_fn)) { |
| 16502 | if (air_tag != air_tag_safe) { | 16370 | _ = try sema.preparePanicId(src, .integer_overflow); |
| 16503 | _ = try sema.preparePanicId(src, .integer_overflow); | ||
| 16504 | } | ||
| 16505 | return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); | ||
| 16506 | } else { | ||
| 16507 | const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { | ||
| 16508 | .add => .add_with_overflow, | ||
| 16509 | .sub => .sub_with_overflow, | ||
| 16510 | .mul => .mul_with_overflow, | ||
| 16511 | else => null, | ||
| 16512 | }; | ||
| 16513 | if (maybe_op_ov) |op_ov_tag| { | ||
| 16514 | const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(resolved_type); | ||
| 16515 | const op_ov = try block.addInst(.{ | ||
| 16516 | .tag = op_ov_tag, | ||
| 16517 | .data = .{ .ty_pl = .{ | ||
| 16518 | .ty = Air.internedToRef(op_ov_tuple_ty.toIntern()), | ||
| 16519 | .payload = try sema.addExtra(Air.Bin{ | ||
| 16520 | .lhs = casted_lhs, | ||
| 16521 | .rhs = casted_rhs, | ||
| 16522 | }), | ||
| 16523 | } }, | ||
| 16524 | }); | ||
| 16525 | const ov_bit = try sema.tupleFieldValByIndex(block, op_ov, 1, op_ov_tuple_ty); | ||
| 16526 | const any_ov_bit = if (resolved_type.zigTypeTag(zcu) == .vector) | ||
| 16527 | try block.addReduce(ov_bit, .Or) | ||
| 16528 | else | ||
| 16529 | ov_bit; | ||
| 16530 | const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); | ||
| 16531 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | ||
| 16532 | |||
| 16533 | try sema.addSafetyCheck(block, src, no_ov, .integer_overflow); | ||
| 16534 | return sema.tupleFieldValByIndex(block, op_ov, 0, op_ov_tuple_ty); | ||
| 16535 | } | ||
| 16536 | } | 16371 | } |
| 16372 | return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); | ||
| 16537 | } | 16373 | } |
| 16538 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); | 16374 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 16539 | } | 16375 | } |
| ... | @@ -16550,7 +16386,7 @@ fn analyzePtrArithmetic( | ... | @@ -16550,7 +16386,7 @@ fn analyzePtrArithmetic( |
| 16550 | ) CompileError!Air.Inst.Ref { | 16386 | ) CompileError!Air.Inst.Ref { |
| 16551 | // TODO if the operand is comptime-known to be negative, or is a negative int, | 16387 | // TODO if the operand is comptime-known to be negative, or is a negative int, |
| 16552 | // coerce to isize instead of usize. | 16388 | // coerce to isize instead of usize. |
| 16553 | const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src); | 16389 | const offset = try sema.coerce(block, .usize, uncasted_offset, offset_src); |
| 16554 | const pt = sema.pt; | 16390 | const pt = sema.pt; |
| 16555 | const zcu = pt.zcu; | 16391 | const zcu = pt.zcu; |
| 16556 | const opt_ptr_val = try sema.resolveValue(ptr); | 16392 | const opt_ptr_val = try sema.resolveValue(ptr); |
| ... | @@ -16736,8 +16572,8 @@ fn zirAsm( | ... | @@ -16736,8 +16572,8 @@ fn zirAsm( |
| 16736 | const uncasted_arg = try sema.resolveInst(input.data.operand); | 16572 | const uncasted_arg = try sema.resolveInst(input.data.operand); |
| 16737 | const uncasted_arg_ty = sema.typeOf(uncasted_arg); | 16573 | const uncasted_arg_ty = sema.typeOf(uncasted_arg); |
| 16738 | switch (uncasted_arg_ty.zigTypeTag(zcu)) { | 16574 | switch (uncasted_arg_ty.zigTypeTag(zcu)) { |
| 16739 | .comptime_int => arg.* = try sema.coerce(block, Type.usize, uncasted_arg, src), | 16575 | .comptime_int => arg.* = try sema.coerce(block, .usize, uncasted_arg, src), |
| 16740 | .comptime_float => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src), | 16576 | .comptime_float => arg.* = try sema.coerce(block, .f64, uncasted_arg, src), |
| 16741 | else => { | 16577 | else => { |
| 16742 | arg.* = uncasted_arg; | 16578 | arg.* = uncasted_arg; |
| 16743 | }, | 16579 | }, |
| ... | @@ -16860,9 +16696,7 @@ fn zirCmpEq( | ... | @@ -16860,9 +16696,7 @@ fn zirCmpEq( |
| 16860 | const runtime_src: LazySrcLoc = src: { | 16696 | const runtime_src: LazySrcLoc = src: { |
| 16861 | if (try sema.resolveValue(lhs)) |lval| { | 16697 | if (try sema.resolveValue(lhs)) |lval| { |
| 16862 | if (try sema.resolveValue(rhs)) |rval| { | 16698 | if (try sema.resolveValue(rhs)) |rval| { |
| 16863 | if (lval.isUndef(zcu) or rval.isUndef(zcu)) { | 16699 | if (lval.isUndef(zcu) or rval.isUndef(zcu)) return .undef_bool; |
| 16864 | return pt.undefRef(Type.bool); | ||
| 16865 | } | ||
| 16866 | const lkey = zcu.intern_pool.indexToKey(lval.toIntern()); | 16700 | const lkey = zcu.intern_pool.indexToKey(lval.toIntern()); |
| 16867 | const rkey = zcu.intern_pool.indexToKey(rval.toIntern()); | 16701 | const rkey = zcu.intern_pool.indexToKey(rval.toIntern()); |
| 16868 | return if ((lkey.err.name == rkey.err.name) == (op == .eq)) | 16702 | return if ((lkey.err.name == rkey.err.name) == (op == .eq)) |
| ... | @@ -16916,7 +16750,7 @@ fn analyzeCmpUnionTag( | ... | @@ -16916,7 +16750,7 @@ fn analyzeCmpUnionTag( |
| 16916 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); | 16750 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); |
| 16917 | 16751 | ||
| 16918 | if (try sema.resolveValue(coerced_tag)) |enum_val| { | 16752 | if (try sema.resolveValue(coerced_tag)) |enum_val| { |
| 16919 | if (enum_val.isUndef(zcu)) return pt.undefRef(Type.bool); | 16753 | if (enum_val.isUndef(zcu)) return .undef_bool; |
| 16920 | const field_ty = union_ty.unionFieldType(enum_val, zcu).?; | 16754 | const field_ty = union_ty.unionFieldType(enum_val, zcu).?; |
| 16921 | if (field_ty.zigTypeTag(zcu) == .noreturn) { | 16755 | if (field_ty.zigTypeTag(zcu) == .noreturn) { |
| 16922 | return .bool_false; | 16756 | return .bool_false; |
| ... | @@ -17027,8 +16861,8 @@ fn cmpSelf( | ... | @@ -17027,8 +16861,8 @@ fn cmpSelf( |
| 17027 | 16861 | ||
| 17028 | const maybe_lhs_val = try sema.resolveValue(casted_lhs); | 16862 | const maybe_lhs_val = try sema.resolveValue(casted_lhs); |
| 17029 | const maybe_rhs_val = try sema.resolveValue(casted_rhs); | 16863 | const maybe_rhs_val = try sema.resolveValue(casted_rhs); |
| 17030 | if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool); | 16864 | if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool; |
| 17031 | if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool); | 16865 | if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool; |
| 17032 | 16866 | ||
| 17033 | const runtime_src: LazySrcLoc = src: { | 16867 | const runtime_src: LazySrcLoc = src: { |
| 17034 | if (maybe_lhs_val) |lhs_val| { | 16868 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -17083,7 +16917,7 @@ fn runtimeBoolCmp( | ... | @@ -17083,7 +16917,7 @@ fn runtimeBoolCmp( |
| 17083 | ) CompileError!Air.Inst.Ref { | 16917 | ) CompileError!Air.Inst.Ref { |
| 17084 | if ((op == .neq) == rhs) { | 16918 | if ((op == .neq) == rhs) { |
| 17085 | try sema.requireRuntimeBlock(block, src, runtime_src); | 16919 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17086 | return block.addTyOp(.not, Type.bool, lhs); | 16920 | return block.addTyOp(.not, .bool, lhs); |
| 17087 | } else { | 16921 | } else { |
| 17088 | return lhs; | 16922 | return lhs; |
| 17089 | } | 16923 | } |
| ... | @@ -17107,7 +16941,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -17107,7 +16941,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 17107 | .comptime_float, | 16941 | .comptime_float, |
| 17108 | .comptime_int, | 16942 | .comptime_int, |
| 17109 | .void, | 16943 | .void, |
| 17110 | => return pt.intRef(Type.comptime_int, 0), | 16944 | => return .zero, |
| 17111 | 16945 | ||
| 17112 | .bool, | 16946 | .bool, |
| 17113 | .int, | 16947 | .int, |
| ... | @@ -17148,7 +16982,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -17148,7 +16982,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17148 | .comptime_float, | 16982 | .comptime_float, |
| 17149 | .comptime_int, | 16983 | .comptime_int, |
| 17150 | .void, | 16984 | .void, |
| 17151 | => return pt.intRef(Type.comptime_int, 0), | 16985 | => return .zero, |
| 17152 | 16986 | ||
| 17153 | .bool, | 16987 | .bool, |
| 17154 | .int, | 16988 | .int, |
| ... | @@ -17167,7 +17001,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -17167,7 +17001,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17167 | => {}, | 17001 | => {}, |
| 17168 | } | 17002 | } |
| 17169 | const bit_size = try operand_ty.bitSizeSema(pt); | 17003 | const bit_size = try operand_ty.bitSizeSema(pt); |
| 17170 | return pt.intRef(Type.comptime_int, bit_size); | 17004 | return pt.intRef(.comptime_int, bit_size); |
| 17171 | } | 17005 | } |
| 17172 | 17006 | ||
| 17173 | fn zirThis( | 17007 | fn zirThis( |
| ... | @@ -17285,7 +17119,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17285,7 +17119,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17285 | 17119 | ||
| 17286 | assert(block.is_typeof); | 17120 | assert(block.is_typeof); |
| 17287 | // We need a dummy runtime instruction with the correct type. | 17121 | // We need a dummy runtime instruction with the correct type. |
| 17288 | return block.addTy(.alloc, Type.fromInterned(capture_ty)); | 17122 | return block.addTy(.alloc, .fromInterned(capture_ty)); |
| 17289 | } | 17123 | } |
| 17290 | 17124 | ||
| 17291 | fn zirRetAddr( | 17125 | fn zirRetAddr( |
| ... | @@ -17293,10 +17127,11 @@ fn zirRetAddr( | ... | @@ -17293,10 +17127,11 @@ fn zirRetAddr( |
| 17293 | block: *Block, | 17127 | block: *Block, |
| 17294 | extended: Zir.Inst.Extended.InstData, | 17128 | extended: Zir.Inst.Extended.InstData, |
| 17295 | ) CompileError!Air.Inst.Ref { | 17129 | ) CompileError!Air.Inst.Ref { |
| 17130 | _ = sema; | ||
| 17296 | _ = extended; | 17131 | _ = extended; |
| 17297 | if (block.isComptime()) { | 17132 | if (block.isComptime()) { |
| 17298 | // TODO: we could give a meaningful lazy value here. #14938 | 17133 | // TODO: we could give a meaningful lazy value here. #14938 |
| 17299 | return sema.pt.intRef(Type.usize, 0); | 17134 | return .zero_usize; |
| 17300 | } else { | 17135 | } else { |
| 17301 | return block.addNoOp(.ret_addr); | 17136 | return block.addNoOp(.ret_addr); |
| 17302 | } | 17137 | } |
| ... | @@ -17349,7 +17184,7 @@ fn zirBuiltinSrc( | ... | @@ -17349,7 +17184,7 @@ fn zirBuiltinSrc( |
| 17349 | } }, | 17184 | } }, |
| 17350 | .byte_offset = 0, | 17185 | .byte_offset = 0, |
| 17351 | } }), | 17186 | } }), |
| 17352 | .len = (try pt.intValue(Type.usize, func_name_len)).toIntern(), | 17187 | .len = (try pt.intValue(.usize, func_name_len)).toIntern(), |
| 17353 | } }); | 17188 | } }); |
| 17354 | }; | 17189 | }; |
| 17355 | 17190 | ||
| ... | @@ -17375,7 +17210,7 @@ fn zirBuiltinSrc( | ... | @@ -17375,7 +17210,7 @@ fn zirBuiltinSrc( |
| 17375 | } }, | 17210 | } }, |
| 17376 | .byte_offset = 0, | 17211 | .byte_offset = 0, |
| 17377 | } }), | 17212 | } }), |
| 17378 | .len = (try pt.intValue(Type.usize, module_name.len)).toIntern(), | 17213 | .len = (try pt.intValue(.usize, module_name.len)).toIntern(), |
| 17379 | } }); | 17214 | } }); |
| 17380 | }; | 17215 | }; |
| 17381 | 17216 | ||
| ... | @@ -17401,7 +17236,7 @@ fn zirBuiltinSrc( | ... | @@ -17401,7 +17236,7 @@ fn zirBuiltinSrc( |
| 17401 | } }, | 17236 | } }, |
| 17402 | .byte_offset = 0, | 17237 | .byte_offset = 0, |
| 17403 | } }), | 17238 | } }), |
| 17404 | .len = (try pt.intValue(Type.usize, file_name.len)).toIntern(), | 17239 | .len = (try pt.intValue(.usize, file_name.len)).toIntern(), |
| 17405 | } }); | 17240 | } }); |
| 17406 | }; | 17241 | }; |
| 17407 | 17242 | ||
| ... | @@ -17414,9 +17249,9 @@ fn zirBuiltinSrc( | ... | @@ -17414,9 +17249,9 @@ fn zirBuiltinSrc( |
| 17414 | // fn_name: [:0]const u8, | 17249 | // fn_name: [:0]const u8, |
| 17415 | func_name_val, | 17250 | func_name_val, |
| 17416 | // line: u32, | 17251 | // line: u32, |
| 17417 | (try pt.intValue(Type.u32, extra.line + 1)).toIntern(), | 17252 | (try pt.intValue(.u32, extra.line + 1)).toIntern(), |
| 17418 | // column: u32, | 17253 | // column: u32, |
| 17419 | (try pt.intValue(Type.u32, extra.column + 1)).toIntern(), | 17254 | (try pt.intValue(.u32, extra.column + 1)).toIntern(), |
| 17420 | }; | 17255 | }; |
| 17421 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ | 17256 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 17422 | .ty = src_loc_ty.toIntern(), | 17257 | .ty = src_loc_ty.toIntern(), |
| ... | @@ -17511,7 +17346,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17511,7 +17346,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17511 | } }, | 17346 | } }, |
| 17512 | .byte_offset = 0, | 17347 | .byte_offset = 0, |
| 17513 | } }), | 17348 | } }), |
| 17514 | .len = (try pt.intValue(Type.usize, param_vals.len)).toIntern(), | 17349 | .len = (try pt.intValue(.usize, param_vals.len)).toIntern(), |
| 17515 | } }); | 17350 | } }); |
| 17516 | }; | 17351 | }; |
| 17517 | 17352 | ||
| ... | @@ -17564,7 +17399,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17564,7 +17399,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17564 | // signedness: Signedness, | 17399 | // signedness: Signedness, |
| 17565 | (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), | 17400 | (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), |
| 17566 | // bits: u16, | 17401 | // bits: u16, |
| 17567 | (try pt.intValue(Type.u16, info.bits)).toIntern(), | 17402 | (try pt.intValue(.u16, info.bits)).toIntern(), |
| 17568 | }; | 17403 | }; |
| 17569 | return Air.internedToRef((try pt.internUnion(.{ | 17404 | return Air.internedToRef((try pt.internUnion(.{ |
| 17570 | .ty = type_info_ty.toIntern(), | 17405 | .ty = type_info_ty.toIntern(), |
| ... | @@ -17580,7 +17415,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17580,7 +17415,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17580 | 17415 | ||
| 17581 | const field_vals = .{ | 17416 | const field_vals = .{ |
| 17582 | // bits: u16, | 17417 | // bits: u16, |
| 17583 | (try pt.intValue(Type.u16, ty.bitSize(zcu))).toIntern(), | 17418 | (try pt.intValue(.u16, ty.bitSize(zcu))).toIntern(), |
| 17584 | }; | 17419 | }; |
| 17585 | return Air.internedToRef((try pt.internUnion(.{ | 17420 | return Air.internedToRef((try pt.internUnion(.{ |
| 17586 | .ty = type_info_ty.toIntern(), | 17421 | .ty = type_info_ty.toIntern(), |
| ... | @@ -17594,7 +17429,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17594,7 +17429,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17594 | .pointer => { | 17429 | .pointer => { |
| 17595 | const info = ty.ptrInfo(zcu); | 17430 | const info = ty.ptrInfo(zcu); |
| 17596 | const alignment = if (info.flags.alignment.toByteUnits()) |alignment| | 17431 | const alignment = if (info.flags.alignment.toByteUnits()) |alignment| |
| 17597 | try pt.intValue(Type.comptime_int, alignment) | 17432 | try pt.intValue(.comptime_int, alignment) |
| 17598 | else | 17433 | else |
| 17599 | try Type.fromInterned(info.child).lazyAbiAlignment(pt); | 17434 | try Type.fromInterned(info.child).lazyAbiAlignment(pt); |
| 17600 | 17435 | ||
| ... | @@ -17638,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17638,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17638 | const info = ty.arrayInfo(zcu); | 17473 | const info = ty.arrayInfo(zcu); |
| 17639 | const field_values = .{ | 17474 | const field_values = .{ |
| 17640 | // len: comptime_int, | 17475 | // len: comptime_int, |
| 17641 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), | 17476 | (try pt.intValue(.comptime_int, info.len)).toIntern(), |
| 17642 | // child: type, | 17477 | // child: type, |
| 17643 | info.elem_type.toIntern(), | 17478 | info.elem_type.toIntern(), |
| 17644 | // sentinel: ?*const anyopaque, | 17479 | // sentinel: ?*const anyopaque, |
| ... | @@ -17659,7 +17494,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17659,7 +17494,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17659 | const info = ty.arrayInfo(zcu); | 17494 | const info = ty.arrayInfo(zcu); |
| 17660 | const field_values = .{ | 17495 | const field_values = .{ |
| 17661 | // len: comptime_int, | 17496 | // len: comptime_int, |
| 17662 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), | 17497 | (try pt.intValue(.comptime_int, info.len)).toIntern(), |
| 17663 | // child: type, | 17498 | // child: type, |
| 17664 | info.elem_type.toIntern(), | 17499 | info.elem_type.toIntern(), |
| 17665 | }; | 17500 | }; |
| ... | @@ -17723,7 +17558,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17723,7 +17558,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17723 | } }, | 17558 | } }, |
| 17724 | .byte_offset = 0, | 17559 | .byte_offset = 0, |
| 17725 | } }), | 17560 | } }), |
| 17726 | .len = (try pt.intValue(Type.usize, error_name_len)).toIntern(), | 17561 | .len = (try pt.intValue(.usize, error_name_len)).toIntern(), |
| 17727 | } }); | 17562 | } }); |
| 17728 | }; | 17563 | }; |
| 17729 | 17564 | ||
| ... | @@ -17770,7 +17605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17770,7 +17605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17770 | } }, | 17605 | } }, |
| 17771 | .byte_offset = 0, | 17606 | .byte_offset = 0, |
| 17772 | } }), | 17607 | } }), |
| 17773 | .len = (try pt.intValue(Type.usize, vals.len)).toIntern(), | 17608 | .len = (try pt.intValue(.usize, vals.len)).toIntern(), |
| 17774 | } }); | 17609 | } }); |
| 17775 | } else .none; | 17610 | } else .none; |
| 17776 | const errors_val = try pt.intern(.{ .opt = .{ | 17611 | const errors_val = try pt.intern(.{ .opt = .{ |
| ... | @@ -17819,7 +17654,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17819,7 +17654,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17819 | .comptime_int_type, | 17654 | .comptime_int_type, |
| 17820 | ) | 17655 | ) |
| 17821 | else | 17656 | else |
| 17822 | (try pt.intValue(Type.comptime_int, tag_index)).toIntern(); | 17657 | (try pt.intValue(.comptime_int, tag_index)).toIntern(); |
| 17823 | 17658 | ||
| 17824 | // TODO: write something like getCoercedInts to avoid needing to dupe | 17659 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 17825 | const name_val = v: { | 17660 | const name_val = v: { |
| ... | @@ -17844,7 +17679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17844,7 +17679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17844 | } }, | 17679 | } }, |
| 17845 | .byte_offset = 0, | 17680 | .byte_offset = 0, |
| 17846 | } }), | 17681 | } }), |
| 17847 | .len = (try pt.intValue(Type.usize, tag_name_len)).toIntern(), | 17682 | .len = (try pt.intValue(.usize, tag_name_len)).toIntern(), |
| 17848 | } }); | 17683 | } }); |
| 17849 | }; | 17684 | }; |
| 17850 | 17685 | ||
| ... | @@ -17887,7 +17722,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17887,7 +17722,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17887 | } }, | 17722 | } }, |
| 17888 | .byte_offset = 0, | 17723 | .byte_offset = 0, |
| 17889 | } }), | 17724 | } }), |
| 17890 | .len = (try pt.intValue(Type.usize, enum_field_vals.len)).toIntern(), | 17725 | .len = (try pt.intValue(.usize, enum_field_vals.len)).toIntern(), |
| 17891 | } }); | 17726 | } }); |
| 17892 | }; | 17727 | }; |
| 17893 | 17728 | ||
| ... | @@ -17949,7 +17784,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17949,7 +17784,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17949 | } }, | 17784 | } }, |
| 17950 | .byte_offset = 0, | 17785 | .byte_offset = 0, |
| 17951 | } }), | 17786 | } }), |
| 17952 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), | 17787 | .len = (try pt.intValue(.usize, field_name_len)).toIntern(), |
| 17953 | } }); | 17788 | } }); |
| 17954 | }; | 17789 | }; |
| 17955 | 17790 | ||
| ... | @@ -17965,7 +17800,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17965,7 +17800,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17965 | // type: type, | 17800 | // type: type, |
| 17966 | field_ty, | 17801 | field_ty, |
| 17967 | // alignment: comptime_int, | 17802 | // alignment: comptime_int, |
| 17968 | (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), | 17803 | (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), |
| 17969 | }; | 17804 | }; |
| 17970 | field_val.* = try pt.intern(.{ .aggregate = .{ | 17805 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 17971 | .ty = union_field_ty.toIntern(), | 17806 | .ty = union_field_ty.toIntern(), |
| ... | @@ -18000,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18000,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18000 | } }, | 17835 | } }, |
| 18001 | .byte_offset = 0, | 17836 | .byte_offset = 0, |
| 18002 | } }), | 17837 | } }), |
| 18003 | .len = (try pt.intValue(Type.usize, union_field_vals.len)).toIntern(), | 17838 | .len = (try pt.intValue(.usize, union_field_vals.len)).toIntern(), |
| 18004 | } }); | 17839 | } }); |
| 18005 | }; | 17840 | }; |
| 18006 | 17841 | ||
| ... | @@ -18070,7 +17905,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18070,7 +17905,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18070 | } }, | 17905 | } }, |
| 18071 | .byte_offset = 0, | 17906 | .byte_offset = 0, |
| 18072 | } }), | 17907 | } }), |
| 18073 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), | 17908 | .len = (try pt.intValue(.usize, field_name_len)).toIntern(), |
| 18074 | } }); | 17909 | } }); |
| 18075 | }; | 17910 | }; |
| 18076 | 17911 | ||
| ... | @@ -18089,7 +17924,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18089,7 +17924,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18089 | // is_comptime: bool, | 17924 | // is_comptime: bool, |
| 18090 | Value.makeBool(is_comptime).toIntern(), | 17925 | Value.makeBool(is_comptime).toIntern(), |
| 18091 | // alignment: comptime_int, | 17926 | // alignment: comptime_int, |
| 18092 | (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(zcu).toByteUnits() orelse 0)).toIntern(), | 17927 | (try pt.intValue(.comptime_int, Type.fromInterned(field_ty).abiAlignment(zcu).toByteUnits() orelse 0)).toIntern(), |
| 18093 | }; | 17928 | }; |
| 18094 | struct_field_val.* = try pt.intern(.{ .aggregate = .{ | 17929 | struct_field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18095 | .ty = struct_field_ty.toIntern(), | 17930 | .ty = struct_field_ty.toIntern(), |
| ... | @@ -18111,7 +17946,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18111,7 +17946,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18111 | else | 17946 | else |
| 18112 | try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); | 17947 | try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); |
| 18113 | const field_name_len = field_name.length(ip); | 17948 | const field_name_len = field_name.length(ip); |
| 18114 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 17949 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 18115 | const field_init = struct_type.fieldInit(ip, field_index); | 17950 | const field_init = struct_type.fieldInit(ip, field_index); |
| 18116 | const field_is_comptime = struct_type.fieldIsComptime(ip, field_index); | 17951 | const field_is_comptime = struct_type.fieldIsComptime(ip, field_index); |
| 18117 | const name_val = v: { | 17952 | const name_val = v: { |
| ... | @@ -18134,7 +17969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18134,7 +17969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18134 | } }, | 17969 | } }, |
| 18135 | .byte_offset = 0, | 17970 | .byte_offset = 0, |
| 18136 | } }), | 17971 | } }), |
| 18137 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), | 17972 | .len = (try pt.intValue(.usize, field_name_len)).toIntern(), |
| 18138 | } }); | 17973 | } }); |
| 18139 | }; | 17974 | }; |
| 18140 | 17975 | ||
| ... | @@ -18159,7 +17994,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18159,7 +17994,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18159 | // is_comptime: bool, | 17994 | // is_comptime: bool, |
| 18160 | Value.makeBool(field_is_comptime).toIntern(), | 17995 | Value.makeBool(field_is_comptime).toIntern(), |
| 18161 | // alignment: comptime_int, | 17996 | // alignment: comptime_int, |
| 18162 | (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), | 17997 | (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), |
| 18163 | }; | 17998 | }; |
| 18164 | field_val.* = try pt.intern(.{ .aggregate = .{ | 17999 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18165 | .ty = struct_field_ty.toIntern(), | 18000 | .ty = struct_field_ty.toIntern(), |
| ... | @@ -18195,7 +18030,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18195,7 +18030,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18195 | } }, | 18030 | } }, |
| 18196 | .byte_offset = 0, | 18031 | .byte_offset = 0, |
| 18197 | } }), | 18032 | } }), |
| 18198 | .len = (try pt.intValue(Type.usize, struct_field_vals.len)).toIntern(), | 18033 | .len = (try pt.intValue(.usize, struct_field_vals.len)).toIntern(), |
| 18199 | } }); | 18034 | } }); |
| 18200 | }; | 18035 | }; |
| 18201 | 18036 | ||
| ... | @@ -18304,7 +18139,7 @@ fn typeInfoDecls( | ... | @@ -18304,7 +18139,7 @@ fn typeInfoDecls( |
| 18304 | } }, | 18139 | } }, |
| 18305 | .byte_offset = 0, | 18140 | .byte_offset = 0, |
| 18306 | } }), | 18141 | } }), |
| 18307 | .len = (try pt.intValue(Type.usize, decl_vals.items.len)).toIntern(), | 18142 | .len = (try pt.intValue(.usize, decl_vals.items.len)).toIntern(), |
| 18308 | } }); | 18143 | } }); |
| 18309 | } | 18144 | } |
| 18310 | 18145 | ||
| ... | @@ -18354,7 +18189,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -18354,7 +18189,7 @@ fn typeInfoNamespaceDecls( |
| 18354 | .byte_offset = 0, | 18189 | .byte_offset = 0, |
| 18355 | }, | 18190 | }, |
| 18356 | }), | 18191 | }), |
| 18357 | .len = (try pt.intValue(Type.usize, name_len)).toIntern(), | 18192 | .len = (try pt.intValue(.usize, name_len)).toIntern(), |
| 18358 | }, | 18193 | }, |
| 18359 | }); | 18194 | }); |
| 18360 | }; | 18195 | }; |
| ... | @@ -18373,7 +18208,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -18373,7 +18208,7 @@ fn typeInfoNamespaceDecls( |
| 18373 | continue; | 18208 | continue; |
| 18374 | } | 18209 | } |
| 18375 | try sema.ensureNavResolved(block, src, nav, .fully); | 18210 | try sema.ensureNavResolved(block, src, nav, .fully); |
| 18376 | const namespace_ty = Type.fromInterned(ip.getNav(nav).status.fully_resolved.val); | 18211 | const namespace_ty: Type = .fromInterned(ip.getNav(nav).status.fully_resolved.val); |
| 18377 | try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces); | 18212 | try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces); |
| 18378 | } | 18213 | } |
| 18379 | } | 18214 | } |
| ... | @@ -18424,7 +18259,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi | ... | @@ -18424,7 +18259,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 18424 | const pt = sema.pt; | 18259 | const pt = sema.pt; |
| 18425 | const zcu = pt.zcu; | 18260 | const zcu = pt.zcu; |
| 18426 | switch (operand.zigTypeTag(zcu)) { | 18261 | switch (operand.zigTypeTag(zcu)) { |
| 18427 | .comptime_int => return Type.comptime_int, | 18262 | .comptime_int => return .comptime_int, |
| 18428 | .int => { | 18263 | .int => { |
| 18429 | const bits = operand.bitSize(zcu); | 18264 | const bits = operand.bitSize(zcu); |
| 18430 | const count = if (bits == 0) | 18265 | const count = if (bits == 0) |
| ... | @@ -18512,14 +18347,12 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18512,14 +18347,12 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18512 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); | 18347 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 18513 | const uncasted_operand = try sema.resolveInst(inst_data.operand); | 18348 | const uncasted_operand = try sema.resolveInst(inst_data.operand); |
| 18514 | 18349 | ||
| 18515 | const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src); | 18350 | const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src); |
| 18516 | if (try sema.resolveValue(operand)) |val| { | 18351 | if (try sema.resolveValue(operand)) |val| { |
| 18517 | return if (val.isUndef(zcu)) | 18352 | return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true; |
| 18518 | pt.undefRef(Type.bool) | ||
| 18519 | else if (val.toBool()) .bool_false else .bool_true; | ||
| 18520 | } | 18353 | } |
| 18521 | try sema.requireRuntimeBlock(block, src, null); | 18354 | try sema.requireRuntimeBlock(block, src, null); |
| 18522 | return block.addTyOp(.not, Type.bool, operand); | 18355 | return block.addTyOp(.not, .bool, operand); |
| 18523 | } | 18356 | } |
| 18524 | 18357 | ||
| 18525 | fn zirBoolBr( | 18358 | fn zirBoolBr( |
| ... | @@ -18544,7 +18377,7 @@ fn zirBoolBr( | ... | @@ -18544,7 +18377,7 @@ fn zirBoolBr( |
| 18544 | const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 18377 | const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| 18545 | const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 18378 | const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); |
| 18546 | 18379 | ||
| 18547 | const lhs = try sema.coerce(parent_block, Type.bool, uncoerced_lhs, lhs_src); | 18380 | const lhs = try sema.coerce(parent_block, .bool, uncoerced_lhs, lhs_src); |
| 18548 | 18381 | ||
| 18549 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { | 18382 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { |
| 18550 | if (is_bool_or and lhs_val.toBool()) { | 18383 | if (is_bool_or and lhs_val.toBool()) { |
| ... | @@ -18559,7 +18392,7 @@ fn zirBoolBr( | ... | @@ -18559,7 +18392,7 @@ fn zirBoolBr( |
| 18559 | if (sema.typeOf(rhs_result).isNoReturn(zcu)) { | 18392 | if (sema.typeOf(rhs_result).isNoReturn(zcu)) { |
| 18560 | return rhs_result; | 18393 | return rhs_result; |
| 18561 | } | 18394 | } |
| 18562 | return sema.coerce(parent_block, Type.bool, rhs_result, rhs_src); | 18395 | return sema.coerce(parent_block, .bool, rhs_result, rhs_src); |
| 18563 | } | 18396 | } |
| 18564 | 18397 | ||
| 18565 | const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); | 18398 | const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); |
| ... | @@ -18596,7 +18429,7 @@ fn zirBoolBr( | ... | @@ -18596,7 +18429,7 @@ fn zirBoolBr( |
| 18596 | const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst); | 18429 | const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst); |
| 18597 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(zcu); | 18430 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(zcu); |
| 18598 | const coerced_rhs_result = if (!rhs_noret) rhs: { | 18431 | const coerced_rhs_result = if (!rhs_noret) rhs: { |
| 18599 | const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); | 18432 | const coerced_result = try sema.coerce(rhs_block, .bool, rhs_result, rhs_src); |
| 18600 | _ = try rhs_block.addBr(block_inst, coerced_result); | 18433 | _ = try rhs_block.addBr(block_inst, coerced_result); |
| 18601 | break :rhs coerced_result; | 18434 | break :rhs coerced_result; |
| 18602 | } else rhs_result; | 18435 | } else rhs_result; |
| ... | @@ -18797,7 +18630,7 @@ fn zirCondbr( | ... | @@ -18797,7 +18630,7 @@ fn zirCondbr( |
| 18797 | const else_body = sema.code.bodySlice(extra.end + then_body.len, extra.data.else_body_len); | 18630 | const else_body = sema.code.bodySlice(extra.end + then_body.len, extra.data.else_body_len); |
| 18798 | 18631 | ||
| 18799 | const uncasted_cond = try sema.resolveInst(extra.data.condition); | 18632 | const uncasted_cond = try sema.resolveInst(extra.data.condition); |
| 18800 | const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src); | 18633 | const cond = try sema.coerce(parent_block, .bool, uncasted_cond, cond_src); |
| 18801 | 18634 | ||
| 18802 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { | 18635 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { |
| 18803 | const body = if (cond_val.toBool()) then_body else else_body; | 18636 | const body = if (cond_val.toBool()) then_body else else_body; |
| ... | @@ -19502,7 +19335,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19502,7 +19335,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19502 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { | 19335 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { |
| 19503 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); | 19336 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 19504 | extra_i += 1; | 19337 | extra_i += 1; |
| 19505 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); | 19338 | const coerced = try sema.coerce(block, .u32, try sema.resolveInst(ref), align_src); |
| 19506 | const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" }); | 19339 | const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" }); |
| 19507 | // Check if this happens to be the lazy alignment of our element type, in | 19340 | // Check if this happens to be the lazy alignment of our element type, in |
| 19508 | // which case we can make this 0 without resolving it. | 19341 | // which case we can make this 0 without resolving it. |
| ... | @@ -19526,14 +19359,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19526,14 +19359,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19526 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { | 19359 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 19527 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); | 19360 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 19528 | extra_i += 1; | 19361 | extra_i += 1; |
| 19529 | const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16, .{ .simple = .type }); | 19362 | const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, .u16, .{ .simple = .type }); |
| 19530 | break :blk @intCast(bit_offset); | 19363 | break :blk @intCast(bit_offset); |
| 19531 | } else 0; | 19364 | } else 0; |
| 19532 | 19365 | ||
| 19533 | const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { | 19366 | const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 19534 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); | 19367 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 19535 | extra_i += 1; | 19368 | extra_i += 1; |
| 19536 | const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16, .{ .simple = .type }); | 19369 | const host_size = try sema.resolveInt(block, hostsize_src, ref, .u16, .{ .simple = .type }); |
| 19537 | break :blk @intCast(host_size); | 19370 | break :blk @intCast(host_size); |
| 19538 | } else 0; | 19371 | } else 0; |
| 19539 | 19372 | ||
| ... | @@ -19767,7 +19600,7 @@ fn unionInit( | ... | @@ -19767,7 +19600,7 @@ fn unionInit( |
| 19767 | const zcu = pt.zcu; | 19600 | const zcu = pt.zcu; |
| 19768 | const ip = &zcu.intern_pool; | 19601 | const ip = &zcu.intern_pool; |
| 19769 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); | 19602 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| 19770 | const field_ty = Type.fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); | 19603 | const field_ty: Type = .fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); |
| 19771 | const init = try sema.coerce(block, field_ty, uncasted_init, init_src); | 19604 | const init = try sema.coerce(block, field_ty, uncasted_init, init_src); |
| 19772 | _ = union_ty_src; | 19605 | _ = union_ty_src; |
| 19773 | return unionInitFromEnumTag(sema, block, init_src, union_ty, field_index, init); | 19606 | return unionInitFromEnumTag(sema, block, init_src, union_ty, field_index, init); |
| ... | @@ -19902,7 +19735,7 @@ fn zirStructInit( | ... | @@ -19902,7 +19735,7 @@ fn zirStructInit( |
| 19902 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); | 19735 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 19903 | const tag_ty = resolved_ty.unionTagTypeHypothetical(zcu); | 19736 | const tag_ty = resolved_ty.unionTagTypeHypothetical(zcu); |
| 19904 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); | 19737 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 19905 | const field_ty = Type.fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); | 19738 | const field_ty: Type = .fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); |
| 19906 | 19739 | ||
| 19907 | if (field_ty.zigTypeTag(zcu) == .noreturn) { | 19740 | if (field_ty.zigTypeTag(zcu) == .noreturn) { |
| 19908 | return sema.failWithOwnedErrorMsg(block, msg: { | 19741 | return sema.failWithOwnedErrorMsg(block, msg: { |
| ... | @@ -19990,7 +19823,7 @@ fn finishStructInit( | ... | @@ -19990,7 +19823,7 @@ fn finishStructInit( |
| 19990 | .init_node_offset = init_src.offset.node_offset.x, | 19823 | .init_node_offset = init_src.offset.node_offset.x, |
| 19991 | .elem_index = @intCast(i), | 19824 | .elem_index = @intCast(i), |
| 19992 | } }); | 19825 | } }); |
| 19993 | const field_ty = Type.fromInterned(tuple.types.get(ip)[i]); | 19826 | const field_ty: Type = .fromInterned(tuple.types.get(ip)[i]); |
| 19994 | field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src); | 19827 | field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src); |
| 19995 | continue; | 19828 | continue; |
| 19996 | } | 19829 | } |
| ... | @@ -20018,7 +19851,7 @@ fn finishStructInit( | ... | @@ -20018,7 +19851,7 @@ fn finishStructInit( |
| 20018 | .init_node_offset = init_src.offset.node_offset.x, | 19851 | .init_node_offset = init_src.offset.node_offset.x, |
| 20019 | .elem_index = @intCast(i), | 19852 | .elem_index = @intCast(i), |
| 20020 | } }); | 19853 | } }); |
| 20021 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 19854 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 20022 | field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src); | 19855 | field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src); |
| 20023 | continue; | 19856 | continue; |
| 20024 | } | 19857 | } |
| ... | @@ -20183,7 +20016,7 @@ fn structInitAnon( | ... | @@ -20183,7 +20016,7 @@ fn structInitAnon( |
| 20183 | const msg = try sema.errMsg(field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 20016 | const msg = try sema.errMsg(field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 20184 | errdefer msg.destroy(sema.gpa); | 20017 | errdefer msg.destroy(sema.gpa); |
| 20185 | 20018 | ||
| 20186 | try sema.addDeclaredHereNote(msg, Type.fromInterned(field_ty.*)); | 20019 | try sema.addDeclaredHereNote(msg, .fromInterned(field_ty.*)); |
| 20187 | break :msg msg; | 20020 | break :msg msg; |
| 20188 | }; | 20021 | }; |
| 20189 | return sema.failWithOwnedErrorMsg(block, msg); | 20022 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | @@ -20317,7 +20150,7 @@ fn structInitAnon( | ... | @@ -20317,7 +20150,7 @@ fn structInitAnon( |
| 20317 | element_refs[i] = try sema.resolveInst(item.data.init); | 20150 | element_refs[i] = try sema.resolveInst(item.data.init); |
| 20318 | } | 20151 | } |
| 20319 | 20152 | ||
| 20320 | return block.addAggregateInit(Type.fromInterned(struct_ty), element_refs); | 20153 | return block.addAggregateInit(.fromInterned(struct_ty), element_refs); |
| 20321 | } | 20154 | } |
| 20322 | 20155 | ||
| 20323 | fn zirArrayInit( | 20156 | fn zirArrayInit( |
| ... | @@ -20441,7 +20274,7 @@ fn zirArrayInit( | ... | @@ -20441,7 +20274,7 @@ fn zirArrayInit( |
| 20441 | }); | 20274 | }); |
| 20442 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); | 20275 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| 20443 | 20276 | ||
| 20444 | const index = try pt.intRef(Type.usize, i); | 20277 | const index = try pt.intRef(.usize, i); |
| 20445 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); | 20278 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); |
| 20446 | _ = try block.addBinOp(.store, elem_ptr, arg); | 20279 | _ = try block.addBinOp(.store, elem_ptr, arg); |
| 20447 | } | 20280 | } |
| ... | @@ -20455,7 +20288,7 @@ fn zirArrayInit( | ... | @@ -20455,7 +20288,7 @@ fn zirArrayInit( |
| 20455 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); | 20288 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| 20456 | 20289 | ||
| 20457 | for (resolved_args, 0..) |arg, i| { | 20290 | for (resolved_args, 0..) |arg, i| { |
| 20458 | const index = try pt.intRef(Type.usize, i); | 20291 | const index = try pt.intRef(.usize, i); |
| 20459 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); | 20292 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); |
| 20460 | _ = try block.addBinOp(.store, elem_ptr, arg); | 20293 | _ = try block.addBinOp(.store, elem_ptr, arg); |
| 20461 | } | 20294 | } |
| ... | @@ -20504,7 +20337,7 @@ fn arrayInitAnon( | ... | @@ -20504,7 +20337,7 @@ fn arrayInitAnon( |
| 20504 | const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 20337 | const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 20505 | errdefer msg.destroy(gpa); | 20338 | errdefer msg.destroy(gpa); |
| 20506 | 20339 | ||
| 20507 | try sema.addDeclaredHereNote(msg, Type.fromInterned(types[i])); | 20340 | try sema.addDeclaredHereNote(msg, .fromInterned(types[i])); |
| 20508 | break :msg msg; | 20341 | break :msg msg; |
| 20509 | }; | 20342 | }; |
| 20510 | return sema.failWithOwnedErrorMsg(block, msg); | 20343 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | @@ -20561,7 +20394,7 @@ fn arrayInitAnon( | ... | @@ -20561,7 +20394,7 @@ fn arrayInitAnon( |
| 20561 | element_refs[i] = try sema.resolveInst(operand); | 20394 | element_refs[i] = try sema.resolveInst(operand); |
| 20562 | } | 20395 | } |
| 20563 | 20396 | ||
| 20564 | return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs); | 20397 | return block.addAggregateInit(.fromInterned(tuple_ty), element_refs); |
| 20565 | } | 20398 | } |
| 20566 | 20399 | ||
| 20567 | fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref { | 20400 | fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref { |
| ... | @@ -20632,7 +20465,7 @@ fn fieldType( | ... | @@ -20632,7 +20465,7 @@ fn fieldType( |
| 20632 | .optional => { | 20465 | .optional => { |
| 20633 | // Struct/array init through optional requires the child type to not be a pointer. | 20466 | // Struct/array init through optional requires the child type to not be a pointer. |
| 20634 | // If the child of .optional is a pointer it'll error on the next loop. | 20467 | // If the child of .optional is a pointer it'll error on the next loop. |
| 20635 | cur_ty = Type.fromInterned(ip.indexToKey(cur_ty.toIntern()).opt_type); | 20468 | cur_ty = .fromInterned(ip.indexToKey(cur_ty.toIntern()).opt_type); |
| 20636 | continue; | 20469 | continue; |
| 20637 | }, | 20470 | }, |
| 20638 | .error_union => { | 20471 | .error_union => { |
| ... | @@ -20710,44 +20543,32 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -20710,44 +20543,32 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 20710 | const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .u1_type, .len = len }) else .u1; | 20543 | const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .u1_type, .len = len }) else .u1; |
| 20711 | if (try sema.resolveValue(operand)) |val| { | 20544 | if (try sema.resolveValue(operand)) |val| { |
| 20712 | if (!is_vector) { | 20545 | if (!is_vector) { |
| 20713 | if (val.isUndef(zcu)) return pt.undefRef(Type.u1); | 20546 | return if (val.isUndef(zcu)) .undef_u1 else if (val.toBool()) .one_u1 else .zero_u1; |
| 20714 | if (val.toBool()) return Air.internedToRef((try pt.intValue(Type.u1, 1)).toIntern()); | ||
| 20715 | return Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); | ||
| 20716 | } | 20547 | } |
| 20717 | if (val.isUndef(zcu)) return pt.undefRef(dest_ty); | 20548 | if (val.isUndef(zcu)) return pt.undefRef(dest_ty); |
| 20718 | const new_elems = try sema.arena.alloc(InternPool.Index, len); | 20549 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 20719 | for (new_elems, 0..) |*new_elem, i| { | 20550 | for (new_elems, 0..) |*new_elem, i| { |
| 20720 | const old_elem = try val.elemValue(pt, i); | 20551 | const old_elem = try val.elemValue(pt, i); |
| 20721 | const new_val = if (old_elem.isUndef(zcu)) | 20552 | new_elem.* = if (old_elem.isUndef(zcu)) |
| 20722 | try pt.undefValue(Type.u1) | 20553 | .undef_u1 |
| 20723 | else if (old_elem.toBool()) | 20554 | else if (old_elem.toBool()) |
| 20724 | try pt.intValue(Type.u1, 1) | 20555 | .one_u1 |
| 20725 | else | 20556 | else |
| 20726 | try pt.intValue(Type.u1, 0); | 20557 | .zero_u1; |
| 20727 | new_elem.* = new_val.toIntern(); | ||
| 20728 | } | 20558 | } |
| 20729 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ | 20559 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 20730 | .ty = dest_ty.toIntern(), | 20560 | .ty = dest_ty.toIntern(), |
| 20731 | .storage = .{ .elems = new_elems }, | 20561 | .storage = .{ .elems = new_elems }, |
| 20732 | } })); | 20562 | } })); |
| 20733 | } | 20563 | } |
| 20734 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 20564 | return block.addBitCast(dest_ty, operand); |
| 20735 | return block.addBitCast(dest_ty, operand); | ||
| 20736 | } | ||
| 20737 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | ||
| 20738 | for (new_elems, 0..) |*new_elem, i| { | ||
| 20739 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 20740 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | ||
| 20741 | new_elem.* = try block.addBitCast(.u1, old_elem); | ||
| 20742 | } | ||
| 20743 | return block.addAggregateInit(dest_ty, new_elems); | ||
| 20744 | } | 20565 | } |
| 20745 | 20566 | ||
| 20746 | fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 20567 | fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 20747 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 20568 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 20748 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 20569 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 20749 | const uncoerced_operand = try sema.resolveInst(inst_data.operand); | 20570 | const uncoerced_operand = try sema.resolveInst(inst_data.operand); |
| 20750 | const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src); | 20571 | const operand = try sema.coerce(block, .anyerror, uncoerced_operand, operand_src); |
| 20751 | 20572 | ||
| 20752 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { | 20573 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 20753 | const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name; | 20574 | const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name; |
| ... | @@ -20993,12 +20814,12 @@ fn zirReify( | ... | @@ -20993,12 +20814,12 @@ fn zirReify( |
| 20993 | .float => { | 20814 | .float => { |
| 20994 | const float = try sema.interpretBuiltinType(block, operand_src, .fromInterned(union_val.val), std.builtin.Type.Float); | 20815 | const float = try sema.interpretBuiltinType(block, operand_src, .fromInterned(union_val.val), std.builtin.Type.Float); |
| 20995 | 20816 | ||
| 20996 | const ty = switch (float.bits) { | 20817 | const ty: Type = switch (float.bits) { |
| 20997 | 16 => Type.f16, | 20818 | 16 => .f16, |
| 20998 | 32 => Type.f32, | 20819 | 32 => .f32, |
| 20999 | 64 => Type.f64, | 20820 | 64 => .f64, |
| 21000 | 80 => Type.f80, | 20821 | 80 => .f80, |
| 21001 | 128 => Type.f128, | 20822 | 128 => .f128, |
| 21002 | else => return sema.fail(block, src, "{}-bit float unsupported", .{float.bits}), | 20823 | else => return sema.fail(block, src, "{}-bit float unsupported", .{float.bits}), |
| 21003 | }; | 20824 | }; |
| 21004 | return Air.internedToRef(ty.toIntern()); | 20825 | return Air.internedToRef(ty.toIntern()); |
| ... | @@ -21038,7 +20859,7 @@ fn zirReify( | ... | @@ -21038,7 +20859,7 @@ fn zirReify( |
| 21038 | try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls), | 20859 | try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls), |
| 21039 | ).?); | 20860 | ).?); |
| 21040 | 20861 | ||
| 21041 | if (!try sema.intFitsInType(alignment_val, Type.u32, null)) { | 20862 | if (!try sema.intFitsInType(alignment_val, .u32, null)) { |
| 21042 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 20863 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 21043 | } | 20864 | } |
| 21044 | 20865 | ||
| ... | @@ -21174,7 +20995,7 @@ fn zirReify( | ... | @@ -21174,7 +20995,7 @@ fn zirReify( |
| 21174 | }, | 20995 | }, |
| 21175 | .error_set => { | 20996 | .error_set => { |
| 21176 | const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse | 20997 | const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse |
| 21177 | return Air.internedToRef(Type.anyerror.toIntern()); | 20998 | return .anyerror_type; |
| 21178 | 20999 | ||
| 21179 | const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ .simple = .error_set_contents }); | 21000 | const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ .simple = .error_set_contents }); |
| 21180 | 21001 | ||
| ... | @@ -21776,7 +21597,7 @@ fn reifyUnion( | ... | @@ -21776,7 +21597,7 @@ fn reifyUnion( |
| 21776 | errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error | 21597 | errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error |
| 21777 | 21598 | ||
| 21778 | for (field_types) |field_ty_ip| { | 21599 | for (field_types) |field_ty_ip| { |
| 21779 | const field_ty = Type.fromInterned(field_ty_ip); | 21600 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 21780 | if (field_ty.zigTypeTag(zcu) == .@"opaque") { | 21601 | if (field_ty.zigTypeTag(zcu) == .@"opaque") { |
| 21781 | return sema.failWithOwnedErrorMsg(block, msg: { | 21602 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 21782 | const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); | 21603 | const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| ... | @@ -22060,7 +21881,7 @@ fn reifyStruct( | ... | @@ -22060,7 +21881,7 @@ fn reifyStruct( |
| 22060 | } | 21881 | } |
| 22061 | 21882 | ||
| 22062 | if (any_aligned_fields) { | 21883 | if (any_aligned_fields) { |
| 22063 | if (!try sema.intFitsInType(field_alignment_val, Type.u32, null)) { | 21884 | if (!try sema.intFitsInType(field_alignment_val, .u32, null)) { |
| 22064 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 21885 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 22065 | } | 21886 | } |
| 22066 | 21887 | ||
| ... | @@ -22149,7 +21970,7 @@ fn reifyStruct( | ... | @@ -22149,7 +21970,7 @@ fn reifyStruct( |
| 22149 | if (layout == .@"packed") { | 21970 | if (layout == .@"packed") { |
| 22150 | var fields_bit_sum: u64 = 0; | 21971 | var fields_bit_sum: u64 = 0; |
| 22151 | for (0..struct_type.field_types.len) |field_idx| { | 21972 | for (0..struct_type.field_types.len) |field_idx| { |
| 22152 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]); | 21973 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_idx]); |
| 22153 | field_ty.resolveLayout(pt) catch |err| switch (err) { | 21974 | field_ty.resolveLayout(pt) catch |err| switch (err) { |
| 22154 | error.AnalysisFail => { | 21975 | error.AnalysisFail => { |
| 22155 | const msg = sema.err orelse return err; | 21976 | const msg = sema.err orelse return err; |
| ... | @@ -22325,7 +22146,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22325,7 +22146,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22325 | if (block.wantSafety()) { | 22146 | if (block.wantSafety()) { |
| 22326 | const len = dest_ty.vectorLen(zcu); | 22147 | const len = dest_ty.vectorLen(zcu); |
| 22327 | for (0..len) |i| { | 22148 | for (0..len) |i| { |
| 22328 | const idx_ref = try pt.intRef(Type.usize, i); | 22149 | const idx_ref = try pt.intRef(.usize, i); |
| 22329 | const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref); | 22150 | const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 22330 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 0.0)).toIntern())); | 22151 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 0.0)).toIntern())); |
| 22331 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | 22152 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| ... | @@ -22336,42 +22157,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22336,42 +22157,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22336 | .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() }, | 22157 | .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() }, |
| 22337 | } })); | 22158 | } })); |
| 22338 | } | 22159 | } |
| 22339 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 22160 | const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_ty, operand); |
| 22340 | const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_ty, operand); | 22161 | if (block.wantSafety()) { |
| 22341 | if (block.wantSafety()) { | 22162 | const back = try block.addTyOp(.float_from_int, operand_ty, result); |
| 22342 | const back = try block.addTyOp(.float_from_int, operand_ty, result); | 22163 | const diff = try block.addBinOp(if (block.float_mode == .optimized) .sub_optimized else .sub, operand, back); |
| 22343 | const diff = try block.addBinOp(if (block.float_mode == .optimized) .sub_optimized else .sub, operand, back); | 22164 | const ok = if (is_vector) ok: { |
| 22344 | const ok = if (is_vector) ok: { | 22165 | const ok_pos = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, 1.0))).toIntern()), .lt); |
| 22345 | const ok_pos = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, 1.0))).toIntern()), .lt); | 22166 | const ok_neg = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, -1.0))).toIntern()), .gt); |
| 22346 | const ok_neg = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, -1.0))).toIntern()), .gt); | 22167 | const ok = try block.addBinOp(.bit_and, ok_pos, ok_neg); |
| 22347 | const ok = try block.addBinOp(.bit_and, ok_pos, ok_neg); | 22168 | break :ok try block.addReduce(ok, .And); |
| 22348 | break :ok try block.addReduce(ok, .And); | 22169 | } else ok: { |
| 22349 | } else ok: { | 22170 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_ty, 1.0)).toIntern())); |
| 22350 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_ty, 1.0)).toIntern())); | 22171 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_ty, -1.0)).toIntern())); |
| 22351 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_ty, -1.0)).toIntern())); | 22172 | break :ok try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 22352 | break :ok try block.addBinOp(.bool_and, ok_pos, ok_neg); | 22173 | }; |
| 22353 | }; | 22174 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| 22354 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | ||
| 22355 | } | ||
| 22356 | return result; | ||
| 22357 | } | ||
| 22358 | const len = dest_ty.vectorLen(zcu); | ||
| 22359 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | ||
| 22360 | for (new_elems, 0..) |*new_elem, i| { | ||
| 22361 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 22362 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | ||
| 22363 | const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_scalar_ty, old_elem); | ||
| 22364 | if (block.wantSafety()) { | ||
| 22365 | const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result); | ||
| 22366 | const diff = try block.addBinOp(.sub, old_elem, back); | ||
| 22367 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 1.0)).toIntern())); | ||
| 22368 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, -1.0)).toIntern())); | ||
| 22369 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); | ||
| 22370 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | ||
| 22371 | } | ||
| 22372 | new_elem.* = result; | ||
| 22373 | } | 22175 | } |
| 22374 | return block.addAggregateInit(dest_ty, new_elems); | 22176 | return result; |
| 22375 | } | 22177 | } |
| 22376 | 22178 | ||
| 22377 | fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22179 | fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -22386,7 +22188,6 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22386,7 +22188,6 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22386 | const operand_ty = sema.typeOf(operand); | 22188 | const operand_ty = sema.typeOf(operand); |
| 22387 | 22189 | ||
| 22388 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src); | 22190 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src); |
| 22389 | const is_vector = dest_ty.zigTypeTag(zcu) == .vector; | ||
| 22390 | 22191 | ||
| 22391 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 22192 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 22392 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 22193 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| ... | @@ -22402,17 +22203,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22402,17 +22203,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22402 | } | 22203 | } |
| 22403 | 22204 | ||
| 22404 | try sema.requireRuntimeBlock(block, src, operand_src); | 22205 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 22405 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 22206 | return block.addTyOp(.float_from_int, dest_ty, operand); |
| 22406 | return block.addTyOp(.float_from_int, dest_ty, operand); | ||
| 22407 | } | ||
| 22408 | const len = operand_ty.vectorLen(zcu); | ||
| 22409 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | ||
| 22410 | for (new_elems, 0..) |*new_elem, i| { | ||
| 22411 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 22412 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | ||
| 22413 | new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem); | ||
| 22414 | } | ||
| 22415 | return block.addAggregateInit(dest_ty, new_elems); | ||
| 22416 | } | 22207 | } |
| 22417 | 22208 | ||
| 22418 | fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22209 | fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -22431,10 +22222,10 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22431,10 +22222,10 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22431 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, uncoerced_operand_ty, src, operand_src); | 22222 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, uncoerced_operand_ty, src, operand_src); |
| 22432 | 22223 | ||
| 22433 | const is_vector = dest_ty.zigTypeTag(zcu) == .vector; | 22224 | const is_vector = dest_ty.zigTypeTag(zcu) == .vector; |
| 22434 | const operand_ty = if (is_vector) operand_ty: { | 22225 | const operand_ty: Type = if (is_vector) operand_ty: { |
| 22435 | const len = dest_ty.vectorLen(zcu); | 22226 | const len = dest_ty.vectorLen(zcu); |
| 22436 | break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len }); | 22227 | break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len }); |
| 22437 | } else Type.usize; | 22228 | } else .usize; |
| 22438 | 22229 | ||
| 22439 | const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src); | 22230 | const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src); |
| 22440 | 22231 | ||
| ... | @@ -22482,69 +22273,34 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22482,69 +22273,34 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22482 | } | 22273 | } |
| 22483 | try sema.requireRuntimeBlock(block, src, operand_src); | 22274 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 22484 | try sema.checkLogicalPtrOperation(block, src, ptr_ty); | 22275 | try sema.checkLogicalPtrOperation(block, src, ptr_ty); |
| 22485 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | ||
| 22486 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) { | ||
| 22487 | if (!ptr_ty.isAllowzeroPtr(zcu)) { | ||
| 22488 | const is_non_zero = if (is_vector) all_non_zero: { | ||
| 22489 | const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern()); | ||
| 22490 | const is_non_zero = try block.addCmpVector(operand_coerced, zero_usize, .neq); | ||
| 22491 | break :all_non_zero try block.addReduce(is_non_zero, .And); | ||
| 22492 | } else try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); | ||
| 22493 | try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null); | ||
| 22494 | } | ||
| 22495 | if (ptr_align.compare(.gt, .@"1")) { | ||
| 22496 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; | ||
| 22497 | const align_mask = Air.internedToRef((try sema.splat(operand_ty, try pt.intValue( | ||
| 22498 | Type.usize, | ||
| 22499 | if (elem_ty.fnPtrMaskOrNull(zcu)) |mask| | ||
| 22500 | align_bytes_minus_1 & mask | ||
| 22501 | else | ||
| 22502 | align_bytes_minus_1, | ||
| 22503 | ))).toIntern()); | ||
| 22504 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_mask); | ||
| 22505 | const is_aligned = if (is_vector) all_aligned: { | ||
| 22506 | const splat_zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern()); | ||
| 22507 | const is_aligned = try block.addCmpVector(remainder, splat_zero_usize, .eq); | ||
| 22508 | break :all_aligned try block.addReduce(is_aligned, .And); | ||
| 22509 | } else try block.addBinOp(.cmp_eq, remainder, .zero_usize); | ||
| 22510 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); | ||
| 22511 | } | ||
| 22512 | } | ||
| 22513 | return block.addBitCast(dest_ty, operand_coerced); | ||
| 22514 | } | ||
| 22515 | |||
| 22516 | const len = dest_ty.vectorLen(zcu); | ||
| 22517 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) { | 22276 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) { |
| 22518 | for (0..len) |i| { | 22277 | if (!ptr_ty.isAllowzeroPtr(zcu)) { |
| 22519 | const idx_ref = try pt.intRef(Type.usize, i); | 22278 | const is_non_zero = if (is_vector) all_non_zero: { |
| 22520 | const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); | 22279 | const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern()); |
| 22521 | if (!ptr_ty.isAllowzeroPtr(zcu)) { | 22280 | const is_non_zero = try block.addCmpVector(operand_coerced, zero_usize, .neq); |
| 22522 | const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize); | 22281 | break :all_non_zero try block.addReduce(is_non_zero, .And); |
| 22523 | try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null); | 22282 | } else try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| 22524 | } | 22283 | try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null); |
| 22525 | if (ptr_align.compare(.gt, .@"1")) { | 22284 | } |
| 22526 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; | 22285 | if (ptr_align.compare(.gt, .@"1")) { |
| 22527 | const align_mask = Air.internedToRef((try pt.intValue( | 22286 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; |
| 22528 | Type.usize, | 22287 | const align_mask = Air.internedToRef((try sema.splat(operand_ty, try pt.intValue( |
| 22529 | if (elem_ty.fnPtrMaskOrNull(zcu)) |mask| | 22288 | .usize, |
| 22530 | align_bytes_minus_1 & mask | 22289 | if (elem_ty.fnPtrMaskOrNull(zcu)) |mask| |
| 22531 | else | 22290 | align_bytes_minus_1 & mask |
| 22532 | align_bytes_minus_1, | 22291 | else |
| 22533 | )).toIntern()); | 22292 | align_bytes_minus_1, |
| 22534 | const remainder = try block.addBinOp(.bit_and, elem_coerced, align_mask); | 22293 | ))).toIntern()); |
| 22535 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); | 22294 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_mask); |
| 22536 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); | 22295 | const is_aligned = if (is_vector) all_aligned: { |
| 22537 | } | 22296 | const splat_zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern()); |
| 22297 | const is_aligned = try block.addCmpVector(remainder, splat_zero_usize, .eq); | ||
| 22298 | break :all_aligned try block.addReduce(is_aligned, .And); | ||
| 22299 | } else try block.addBinOp(.cmp_eq, remainder, .zero_usize); | ||
| 22300 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); | ||
| 22538 | } | 22301 | } |
| 22539 | } | 22302 | } |
| 22540 | 22303 | return block.addBitCast(dest_ty, operand_coerced); | |
| 22541 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | ||
| 22542 | for (new_elems, 0..) |*new_elem, i| { | ||
| 22543 | const idx_ref = try pt.intRef(Type.usize, i); | ||
| 22544 | const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); | ||
| 22545 | new_elem.* = try block.addBitCast(ptr_ty, old_elem); | ||
| 22546 | } | ||
| 22547 | return block.addAggregateInit(dest_ty, new_elems); | ||
| 22548 | } | 22304 | } |
| 22549 | 22305 | ||
| 22550 | fn ptrFromIntVal( | 22306 | fn ptrFromIntVal( |
| ... | @@ -22918,12 +22674,12 @@ fn ptrCastFull( | ... | @@ -22918,12 +22674,12 @@ fn ptrCastFull( |
| 22918 | } | 22674 | } |
| 22919 | 22675 | ||
| 22920 | check_child: { | 22676 | check_child: { |
| 22921 | const src_child = if (dest_info.flags.size == .slice and src_info.flags.size == .one) blk: { | 22677 | const src_child: Type = if (dest_info.flags.size == .slice and src_info.flags.size == .one) blk: { |
| 22922 | // *[n]T -> []T | 22678 | // *[n]T -> []T |
| 22923 | break :blk Type.fromInterned(src_info.child).childType(zcu); | 22679 | break :blk Type.fromInterned(src_info.child).childType(zcu); |
| 22924 | } else Type.fromInterned(src_info.child); | 22680 | } else .fromInterned(src_info.child); |
| 22925 | 22681 | ||
| 22926 | const dest_child = Type.fromInterned(dest_info.child); | 22682 | const dest_child: Type = .fromInterned(dest_info.child); |
| 22927 | 22683 | ||
| 22928 | const imc_res = try sema.coerceInMemoryAllowed( | 22684 | const imc_res = try sema.coerceInMemoryAllowed( |
| 22929 | block, | 22685 | block, |
| ... | @@ -22956,7 +22712,7 @@ fn ptrCastFull( | ... | @@ -22956,7 +22712,7 @@ fn ptrCastFull( |
| 22956 | } | 22712 | } |
| 22957 | if (is_array_ptr_to_slice) { | 22713 | if (is_array_ptr_to_slice) { |
| 22958 | // [*]nT -> []T | 22714 | // [*]nT -> []T |
| 22959 | const arr_ty = Type.fromInterned(src_info.child); | 22715 | const arr_ty: Type = .fromInterned(src_info.child); |
| 22960 | if (arr_ty.sentinel(zcu)) |src_sentinel| { | 22716 | if (arr_ty.sentinel(zcu)) |src_sentinel| { |
| 22961 | const coerced_sent = try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child); | 22717 | const coerced_sent = try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child); |
| 22962 | if (dest_info.sentinel == coerced_sent) break :check_sent; | 22718 | if (dest_info.sentinel == coerced_sent) break :check_sent; |
| ... | @@ -23158,7 +22914,7 @@ fn ptrCastFull( | ... | @@ -23158,7 +22914,7 @@ fn ptrCastFull( |
| 23158 | if (dest_info.flags.size == .slice) { | 22914 | if (dest_info.flags.size == .slice) { |
| 23159 | // Because the operand is comptime-known and not `null`, the slice length has already been computed: | 22915 | // Because the operand is comptime-known and not `null`, the slice length has already been computed: |
| 23160 | const len: Value = switch (dest_slice_len.?) { | 22916 | const len: Value = switch (dest_slice_len.?) { |
| 23161 | .undef => try pt.undefValue(.usize), | 22917 | .undef => .undef_usize, |
| 23162 | .constant => |n| try pt.intValue(.usize, n), | 22918 | .constant => |n| try pt.intValue(.usize, n), |
| 23163 | .equal_runtime_src_slice => unreachable, | 22919 | .equal_runtime_src_slice => unreachable, |
| 23164 | .change_runtime_src_slice => unreachable, | 22920 | .change_runtime_src_slice => unreachable, |
| ... | @@ -23267,7 +23023,7 @@ fn ptrCastFull( | ... | @@ -23267,7 +23023,7 @@ fn ptrCastFull( |
| 23267 | if (need_align_check) { | 23023 | if (need_align_check) { |
| 23268 | assert(operand_ptr_int != .none); | 23024 | assert(operand_ptr_int != .none); |
| 23269 | const align_mask = try pt.intRef(.usize, mask: { | 23025 | const align_mask = try pt.intRef(.usize, mask: { |
| 23270 | const target_ptr_mask: u64 = Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu) orelse ~@as(u64, 0); | 23026 | const target_ptr_mask = Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu) orelse ~@as(u64, 0); |
| 23271 | break :mask (dest_align.toByteUnits().? - 1) & target_ptr_mask; | 23027 | break :mask (dest_align.toByteUnits().? - 1) & target_ptr_mask; |
| 23272 | }); | 23028 | }); |
| 23273 | const ptr_masked = try block.addBinOp(.bit_and, operand_ptr_int, align_mask); | 23029 | const ptr_masked = try block.addBinOp(.bit_and, operand_ptr_int, align_mask); |
| ... | @@ -23288,7 +23044,7 @@ fn ptrCastFull( | ... | @@ -23288,7 +23044,7 @@ fn ptrCastFull( |
| 23288 | assert(need_operand_ptr); | 23044 | assert(need_operand_ptr); |
| 23289 | 23045 | ||
| 23290 | const result_len: Air.Inst.Ref = switch (dest_slice_len.?) { | 23046 | const result_len: Air.Inst.Ref = switch (dest_slice_len.?) { |
| 23291 | .undef => try pt.undefRef(.usize), | 23047 | .undef => .undef_usize, |
| 23292 | .constant => |n| try pt.intRef(.usize, n), | 23048 | .constant => |n| try pt.intRef(.usize, n), |
| 23293 | .equal_runtime_src_slice => len: { | 23049 | .equal_runtime_src_slice => len: { |
| 23294 | assert(need_operand_len); | 23050 | assert(need_operand_len); |
| ... | @@ -23658,13 +23414,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -23658,13 +23414,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23658 | 23414 | ||
| 23659 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23415 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23660 | const offset = try sema.bitOffsetOf(block, inst); | 23416 | const offset = try sema.bitOffsetOf(block, inst); |
| 23661 | return sema.pt.intRef(Type.comptime_int, offset); | 23417 | return sema.pt.intRef(.comptime_int, offset); |
| 23662 | } | 23418 | } |
| 23663 | 23419 | ||
| 23664 | fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23420 | fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23665 | const offset = try sema.bitOffsetOf(block, inst); | 23421 | const offset = try sema.bitOffsetOf(block, inst); |
| 23666 | // TODO reminder to make this a compile error for packed structs | 23422 | // TODO reminder to make this a compile error for packed structs |
| 23667 | return sema.pt.intRef(Type.comptime_int, offset / 8); | 23423 | return sema.pt.intRef(.comptime_int, offset / 8); |
| 23668 | } | 23424 | } |
| 23669 | 23425 | ||
| 23670 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { | 23426 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { |
| ... | @@ -23705,7 +23461,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -23705,7 +23461,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23705 | if (i == field_index) { | 23461 | if (i == field_index) { |
| 23706 | return bit_sum; | 23462 | return bit_sum; |
| 23707 | } | 23463 | } |
| 23708 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 23464 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 23709 | bit_sum += field_ty.bitSize(zcu); | 23465 | bit_sum += field_ty.bitSize(zcu); |
| 23710 | } else unreachable; | 23466 | } else unreachable; |
| 23711 | }, | 23467 | }, |
| ... | @@ -24497,8 +24253,8 @@ fn analyzeShuffle( | ... | @@ -24497,8 +24253,8 @@ fn analyzeShuffle( |
| 24497 | block: *Block, | 24253 | block: *Block, |
| 24498 | src_node: std.zig.Ast.Node.Offset, | 24254 | src_node: std.zig.Ast.Node.Offset, |
| 24499 | elem_ty: Type, | 24255 | elem_ty: Type, |
| 24500 | a_arg: Air.Inst.Ref, | 24256 | a_uncoerced: Air.Inst.Ref, |
| 24501 | b_arg: Air.Inst.Ref, | 24257 | b_uncoerced: Air.Inst.Ref, |
| 24502 | mask: Value, | 24258 | mask: Value, |
| 24503 | mask_len: u32, | 24259 | mask_len: u32, |
| 24504 | ) CompileError!Air.Inst.Ref { | 24260 | ) CompileError!Air.Inst.Ref { |
| ... | @@ -24507,150 +24263,154 @@ fn analyzeShuffle( | ... | @@ -24507,150 +24263,154 @@ fn analyzeShuffle( |
| 24507 | const a_src = block.builtinCallArgSrc(src_node, 1); | 24263 | const a_src = block.builtinCallArgSrc(src_node, 1); |
| 24508 | const b_src = block.builtinCallArgSrc(src_node, 2); | 24264 | const b_src = block.builtinCallArgSrc(src_node, 2); |
| 24509 | const mask_src = block.builtinCallArgSrc(src_node, 3); | 24265 | const mask_src = block.builtinCallArgSrc(src_node, 3); |
| 24510 | var a = a_arg; | ||
| 24511 | var b = b_arg; | ||
| 24512 | |||
| 24513 | const res_ty = try pt.vectorType(.{ | ||
| 24514 | .len = mask_len, | ||
| 24515 | .child = elem_ty.toIntern(), | ||
| 24516 | }); | ||
| 24517 | 24266 | ||
| 24518 | const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(zcu)) { | 24267 | // If the type of `a` is `@Type(.undefined)`, i.e. the argument is untyped, this is 0, because it is an error to index into this vector. |
| 24519 | .array, .vector => sema.typeOf(a).arrayLen(zcu), | 24268 | const a_len: u32 = switch (sema.typeOf(a_uncoerced).zigTypeTag(zcu)) { |
| 24520 | .undefined => null, | 24269 | .array, .vector => @intCast(sema.typeOf(a_uncoerced).arrayLen(zcu)), |
| 24521 | else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{ | 24270 | .undefined => 0, |
| 24522 | elem_ty.fmt(pt), | 24271 | else => return sema.fail(block, a_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(a_uncoerced).fmt(pt) }), |
| 24523 | sema.typeOf(a).fmt(pt), | 24272 | }; |
| 24524 | }), | 24273 | const a_ty = try pt.vectorType(.{ .len = a_len, .child = elem_ty.toIntern() }); |
| 24525 | }; | 24274 | const a_coerced = try sema.coerce(block, a_ty, a_uncoerced, a_src); |
| 24526 | const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(zcu)) { | 24275 | |
| 24527 | .array, .vector => sema.typeOf(b).arrayLen(zcu), | 24276 | // If the type of `b` is `@Type(.undefined)`, i.e. the argument is untyped, this is 0, because it is an error to index into this vector. |
| 24528 | .undefined => null, | 24277 | const b_len: u32 = switch (sema.typeOf(b_uncoerced).zigTypeTag(zcu)) { |
| 24529 | else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{ | 24278 | .array, .vector => @intCast(sema.typeOf(b_uncoerced).arrayLen(zcu)), |
| 24530 | elem_ty.fmt(pt), | 24279 | .undefined => 0, |
| 24531 | sema.typeOf(b).fmt(pt), | 24280 | else => return sema.fail(block, b_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(b_uncoerced).fmt(pt) }), |
| 24532 | }), | 24281 | }; |
| 24533 | }; | 24282 | const b_ty = try pt.vectorType(.{ .len = b_len, .child = elem_ty.toIntern() }); |
| 24534 | if (maybe_a_len == null and maybe_b_len == null) { | 24283 | const b_coerced = try sema.coerce(block, b_ty, b_uncoerced, b_src); |
| 24535 | return pt.undefRef(res_ty); | 24284 | |
| 24536 | } | 24285 | const result_ty = try pt.vectorType(.{ .len = mask_len, .child = elem_ty.toIntern() }); |
| 24537 | const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?); | 24286 | |
| 24538 | const b_len: u32 = @intCast(maybe_b_len orelse a_len); | 24287 | // We're going to pre-emptively reserve space in `sema.air_extra`. The reason for this is we need |
| 24539 | 24288 | // a `u32` buffer of length `mask_len` anyway, and putting it in `sema.air_extra` avoids a copy | |
| 24540 | const a_ty = try pt.vectorType(.{ | 24289 | // in the runtime case. If the result is comptime-known, we'll shrink `air_extra` back. |
| 24541 | .len = a_len, | 24290 | const air_extra_idx: u32 = @intCast(sema.air_extra.items.len); |
| 24542 | .child = elem_ty.toIntern(), | 24291 | const air_mask_buf = try sema.air_extra.addManyAsSlice(sema.gpa, mask_len); |
| 24543 | }); | 24292 | |
| 24544 | const b_ty = try pt.vectorType(.{ | 24293 | // We want to interpret that buffer in `air_extra` in a few ways. Initially, we'll consider its |
| 24545 | .len = b_len, | 24294 | // elements as `Air.Inst.ShuffleTwoMask`, essentially representing the raw mask values; then, we'll |
| 24546 | .child = elem_ty.toIntern(), | 24295 | // convert it to `InternPool.Index` or `Air.Inst.ShuffleOneMask` if there are comptime-known operands. |
| 24547 | }); | 24296 | const mask_ip_index: []InternPool.Index = @ptrCast(air_mask_buf); |
| 24548 | 24297 | const mask_shuffle_one: []Air.ShuffleOneMask = @ptrCast(air_mask_buf); | |
| 24549 | if (maybe_a_len == null) a = try pt.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src); | 24298 | const mask_shuffle_two: []Air.ShuffleTwoMask = @ptrCast(air_mask_buf); |
| 24550 | if (maybe_b_len == null) b = try pt.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src); | 24299 | |
| 24551 | 24300 | // Initial loop: check mask elements, populate `mask_shuffle_two`. | |
| 24552 | const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){ | 24301 | var a_used = false; |
| 24553 | .{ a_len, a_src, a_ty }, | 24302 | var b_used = false; |
| 24554 | .{ b_len, b_src, b_ty }, | 24303 | for (mask_shuffle_two, 0..mask_len) |*out, mask_idx| { |
| 24555 | }; | 24304 | const mask_val = try mask.elemValue(pt, mask_idx); |
| 24556 | 24305 | if (mask_val.isUndef(zcu)) { | |
| 24557 | for (0..@intCast(mask_len)) |i| { | 24306 | out.* = .undef; |
| 24558 | const elem = try mask.elemValue(pt, i); | 24307 | continue; |
| 24559 | if (elem.isUndef(zcu)) continue; | ||
| 24560 | const elem_resolved = try sema.resolveLazyValue(elem); | ||
| 24561 | const int = elem_resolved.toSignedInt(zcu); | ||
| 24562 | var unsigned: u32 = undefined; | ||
| 24563 | var chosen: u32 = undefined; | ||
| 24564 | if (int >= 0) { | ||
| 24565 | unsigned = @intCast(int); | ||
| 24566 | chosen = 0; | ||
| 24567 | } else { | ||
| 24568 | unsigned = @intCast(~int); | ||
| 24569 | chosen = 1; | ||
| 24570 | } | 24308 | } |
| 24571 | if (unsigned >= operand_info[chosen][0]) { | 24309 | // Safe because mask elements are `i32` and we already checked for undef: |
| 24572 | const msg = msg: { | 24310 | const raw = (try sema.resolveLazyValue(mask_val)).toSignedInt(zcu); |
| 24573 | const msg = try sema.errMsg(mask_src, "mask index '{d}' has out-of-bounds selection", .{i}); | 24311 | if (raw >= 0) { |
| 24312 | const idx: u32 = @intCast(raw); | ||
| 24313 | a_used = true; | ||
| 24314 | out.* = .aElem(idx); | ||
| 24315 | if (idx >= a_len) return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 24316 | const msg = try sema.errMsg(mask_src, "mask element at index '{d}' selects out-of-bounds index", .{mask_idx}); | ||
| 24574 | errdefer msg.destroy(sema.gpa); | 24317 | errdefer msg.destroy(sema.gpa); |
| 24575 | 24318 | try sema.errNote(a_src, msg, "index '{d}' exceeds bounds of '{}' given here", .{ idx, a_ty.fmt(pt) }); | |
| 24576 | try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{ | 24319 | if (idx < b_len) { |
| 24577 | unsigned, | 24320 | try sema.errNote(b_src, msg, "use '~@as(u32, {d})' to index into second vector given here", .{idx}); |
| 24578 | operand_info[chosen][2].fmt(pt), | ||
| 24579 | }); | ||
| 24580 | |||
| 24581 | if (chosen == 0) { | ||
| 24582 | try sema.errNote(b_src, msg, "selections from the second vector are specified with negative numbers", .{}); | ||
| 24583 | } | 24321 | } |
| 24584 | |||
| 24585 | break :msg msg; | 24322 | break :msg msg; |
| 24586 | }; | 24323 | }); |
| 24587 | return sema.failWithOwnedErrorMsg(block, msg); | 24324 | } else { |
| 24325 | const idx: u32 = @intCast(~raw); | ||
| 24326 | b_used = true; | ||
| 24327 | out.* = .bElem(idx); | ||
| 24328 | if (idx >= b_len) return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 24329 | const msg = try sema.errMsg(mask_src, "mask element at index '{d}' selects out-of-bounds index", .{mask_idx}); | ||
| 24330 | errdefer msg.destroy(sema.gpa); | ||
| 24331 | try sema.errNote(b_src, msg, "index '{d}' exceeds bounds of '{}' given here", .{ idx, b_ty.fmt(pt) }); | ||
| 24332 | break :msg msg; | ||
| 24333 | }); | ||
| 24588 | } | 24334 | } |
| 24589 | } | 24335 | } |
| 24590 | 24336 | ||
| 24591 | if (try sema.resolveValue(a)) |a_val| { | 24337 | const maybe_a_val = try sema.resolveValue(a_coerced); |
| 24592 | if (try sema.resolveValue(b)) |b_val| { | 24338 | const maybe_b_val = try sema.resolveValue(b_coerced); |
| 24593 | const values = try sema.arena.alloc(InternPool.Index, mask_len); | ||
| 24594 | for (values, 0..) |*value, i| { | ||
| 24595 | const mask_elem_val = try mask.elemValue(pt, i); | ||
| 24596 | if (mask_elem_val.isUndef(zcu)) { | ||
| 24597 | value.* = try pt.intern(.{ .undef = elem_ty.toIntern() }); | ||
| 24598 | continue; | ||
| 24599 | } | ||
| 24600 | const int = mask_elem_val.toSignedInt(zcu); | ||
| 24601 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); | ||
| 24602 | values[i] = (try (if (int >= 0) a_val else b_val).elemValue(pt, unsigned)).toIntern(); | ||
| 24603 | } | ||
| 24604 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ | ||
| 24605 | .ty = res_ty.toIntern(), | ||
| 24606 | .storage = .{ .elems = values }, | ||
| 24607 | } }))); | ||
| 24608 | } | ||
| 24609 | } | ||
| 24610 | 24339 | ||
| 24611 | // All static analysis passed, and not comptime. | 24340 | const a_rt = a_used and maybe_a_val == null; |
| 24612 | // For runtime codegen, vectors a and b must be the same length. Here we | 24341 | const b_rt = b_used and maybe_b_val == null; |
| 24613 | // recursively @shuffle the smaller vector to append undefined elements | ||
| 24614 | // to it up to the length of the longer vector. This recursion terminates | ||
| 24615 | // in 1 call because these calls to analyzeShuffle guarantee a_len == b_len. | ||
| 24616 | if (a_len != b_len) { | ||
| 24617 | const min_len = @min(a_len, b_len); | ||
| 24618 | const max_src = if (a_len > b_len) a_src else b_src; | ||
| 24619 | const max_len = try sema.usizeCast(block, max_src, @max(a_len, b_len)); | ||
| 24620 | 24342 | ||
| 24621 | const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len); | 24343 | if (a_rt and b_rt) { |
| 24622 | for (@intCast(0)..@intCast(min_len)) |i| { | 24344 | // Both operands are needed and runtime-known. We need a `[]ShuffleTwomask`... which is |
| 24623 | expand_mask_values[i] = (try pt.intValue(Type.comptime_int, i)).toIntern(); | 24345 | // exactly what we already have in `mask_shuffle_two`! So, we're basically done already. |
| 24346 | // We just need to append the two operands. | ||
| 24347 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, 2); | ||
| 24348 | sema.appendRefsAssumeCapacity(&.{ a_coerced, b_coerced }); | ||
| 24349 | return block.addInst(.{ | ||
| 24350 | .tag = .shuffle_two, | ||
| 24351 | .data = .{ .ty_pl = .{ | ||
| 24352 | .ty = Air.internedToRef(result_ty.toIntern()), | ||
| 24353 | .payload = air_extra_idx, | ||
| 24354 | } }, | ||
| 24355 | }); | ||
| 24356 | } else if (a_rt) { | ||
| 24357 | // We need to convert the `ShuffleTwoMask` values to `ShuffleOneMask`. | ||
| 24358 | for (mask_shuffle_two, mask_shuffle_one) |in, *out| { | ||
| 24359 | out.* = switch (in.unwrap()) { | ||
| 24360 | .undef => .value(try pt.undefValue(elem_ty)), | ||
| 24361 | .a_elem => |idx| .elem(idx), | ||
| 24362 | .b_elem => |idx| .value(try maybe_b_val.?.elemValue(pt, idx)), | ||
| 24363 | }; | ||
| 24624 | } | 24364 | } |
| 24625 | for (@intCast(min_len)..@intCast(max_len)) |i| { | 24365 | // Now just append our single runtime operand, and we're done. |
| 24626 | expand_mask_values[i] = (try pt.intValue(Type.comptime_int, -1)).toIntern(); | 24366 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, 1); |
| 24367 | sema.appendRefsAssumeCapacity(&.{a_coerced}); | ||
| 24368 | return block.addInst(.{ | ||
| 24369 | .tag = .shuffle_one, | ||
| 24370 | .data = .{ .ty_pl = .{ | ||
| 24371 | .ty = Air.internedToRef(result_ty.toIntern()), | ||
| 24372 | .payload = air_extra_idx, | ||
| 24373 | } }, | ||
| 24374 | }); | ||
| 24375 | } else if (b_rt) { | ||
| 24376 | // We need to convert the `ShuffleTwoMask` values to `ShuffleOneMask`. | ||
| 24377 | for (mask_shuffle_two, mask_shuffle_one) |in, *out| { | ||
| 24378 | out.* = switch (in.unwrap()) { | ||
| 24379 | .undef => .value(try pt.undefValue(elem_ty)), | ||
| 24380 | .a_elem => |idx| .value(try maybe_a_val.?.elemValue(pt, idx)), | ||
| 24381 | .b_elem => |idx| .elem(idx), | ||
| 24382 | }; | ||
| 24627 | } | 24383 | } |
| 24628 | const expand_mask = try pt.intern(.{ .aggregate = .{ | 24384 | // Now just append our single runtime operand, and we're done. |
| 24629 | .ty = (try pt.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(), | 24385 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, 1); |
| 24630 | .storage = .{ .elems = expand_mask_values }, | 24386 | sema.appendRefsAssumeCapacity(&.{b_coerced}); |
| 24631 | } }); | 24387 | return block.addInst(.{ |
| 24632 | 24388 | .tag = .shuffle_one, | |
| 24633 | if (a_len < b_len) { | 24389 | .data = .{ .ty_pl = .{ |
| 24634 | const undef = try pt.undefRef(a_ty); | 24390 | .ty = Air.internedToRef(result_ty.toIntern()), |
| 24635 | a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len)); | 24391 | .payload = air_extra_idx, |
| 24636 | } else { | 24392 | } }, |
| 24637 | const undef = try pt.undefRef(b_ty); | 24393 | }); |
| 24638 | b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len)); | 24394 | } else { |
| 24395 | // The result will be comptime-known. We must convert the `ShuffleTwoMask` values to | ||
| 24396 | // `InternPool.Index` values using the known operands. | ||
| 24397 | for (mask_shuffle_two, mask_ip_index) |in, *out| { | ||
| 24398 | const val: Value = switch (in.unwrap()) { | ||
| 24399 | .undef => try pt.undefValue(elem_ty), | ||
| 24400 | .a_elem => |idx| try maybe_a_val.?.elemValue(pt, idx), | ||
| 24401 | .b_elem => |idx| try maybe_b_val.?.elemValue(pt, idx), | ||
| 24402 | }; | ||
| 24403 | out.* = val.toIntern(); | ||
| 24639 | } | 24404 | } |
| 24405 | const res = try pt.intern(.{ .aggregate = .{ | ||
| 24406 | .ty = result_ty.toIntern(), | ||
| 24407 | .storage = .{ .elems = mask_ip_index }, | ||
| 24408 | } }); | ||
| 24409 | // We have a comptime-known result, so didn't need `air_mask_buf` -- remove it from `sema.air_extra`. | ||
| 24410 | assert(sema.air_extra.items.len == air_extra_idx + air_mask_buf.len); | ||
| 24411 | sema.air_extra.shrinkRetainingCapacity(air_extra_idx); | ||
| 24412 | return Air.internedToRef(res); | ||
| 24640 | } | 24413 | } |
| 24641 | |||
| 24642 | return block.addInst(.{ | ||
| 24643 | .tag = .shuffle, | ||
| 24644 | .data = .{ .ty_pl = .{ | ||
| 24645 | .ty = Air.internedToRef(res_ty.toIntern()), | ||
| 24646 | .payload = try block.sema.addExtra(Air.Shuffle{ | ||
| 24647 | .a = a, | ||
| 24648 | .b = b, | ||
| 24649 | .mask = mask.toIntern(), | ||
| 24650 | .mask_len = mask_len, | ||
| 24651 | }), | ||
| 24652 | } }, | ||
| 24653 | }); | ||
| 24654 | } | 24414 | } |
| 24655 | 24415 | ||
| 24656 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 24416 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| ... | @@ -25087,7 +24847,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -25087,7 +24847,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25087 | if (parent_ptr_info.flags.size != .one) { | 24847 | if (parent_ptr_info.flags.size != .one) { |
| 25088 | return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)}); | 24848 | return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)}); |
| 25089 | } | 24849 | } |
| 25090 | const parent_ty = Type.fromInterned(parent_ptr_info.child); | 24850 | const parent_ty: Type = .fromInterned(parent_ptr_info.child); |
| 25091 | switch (parent_ty.zigTypeTag(zcu)) { | 24851 | switch (parent_ty.zigTypeTag(zcu)) { |
| 25092 | .@"struct", .@"union" => {}, | 24852 | .@"struct", .@"union" => {}, |
| 25093 | else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}), | 24853 | else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}), |
| ... | @@ -25741,7 +25501,7 @@ fn zirMemcpy( | ... | @@ -25741,7 +25501,7 @@ fn zirMemcpy( |
| 25741 | if (try sema.resolveDefinedValue(block, dest_src, dest_len)) |dest_len_val| { | 25501 | if (try sema.resolveDefinedValue(block, dest_src, dest_len)) |dest_len_val| { |
| 25742 | len_val = dest_len_val; | 25502 | len_val = dest_len_val; |
| 25743 | if (try sema.resolveDefinedValue(block, src_src, src_len)) |src_len_val| { | 25503 | if (try sema.resolveDefinedValue(block, src_src, src_len)) |src_len_val| { |
| 25744 | if (!(try sema.valuesEqual(dest_len_val, src_len_val, Type.usize))) { | 25504 | if (!(try sema.valuesEqual(dest_len_val, src_len_val, .usize))) { |
| 25745 | const msg = msg: { | 25505 | const msg = msg: { |
| 25746 | const msg = try sema.errMsg(src, "non-matching copy lengths", .{}); | 25506 | const msg = try sema.errMsg(src, "non-matching copy lengths", .{}); |
| 25747 | errdefer msg.destroy(sema.gpa); | 25507 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -25952,7 +25712,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25952,7 +25712,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25952 | const dest_elem_ty: Type = dest_elem_ty: { | 25712 | const dest_elem_ty: Type = dest_elem_ty: { |
| 25953 | const ptr_info = dest_ptr_ty.ptrInfo(zcu); | 25713 | const ptr_info = dest_ptr_ty.ptrInfo(zcu); |
| 25954 | switch (ptr_info.flags.size) { | 25714 | switch (ptr_info.flags.size) { |
| 25955 | .slice => break :dest_elem_ty Type.fromInterned(ptr_info.child), | 25715 | .slice => break :dest_elem_ty .fromInterned(ptr_info.child), |
| 25956 | .one => { | 25716 | .one => { |
| 25957 | if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .array) { | 25717 | if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .array) { |
| 25958 | break :dest_elem_ty Type.fromInterned(ptr_info.child).childType(zcu); | 25718 | break :dest_elem_ty Type.fromInterned(ptr_info.child).childType(zcu); |
| ... | @@ -26118,7 +25878,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26118,7 +25878,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26118 | extra_index += body.len; | 25878 | extra_index += body.len; |
| 26119 | if (extra.data.bits.ret_ty_is_generic) break :blk .generic_poison; | 25879 | if (extra.data.bits.ret_ty_is_generic) break :blk .generic_poison; |
| 26120 | 25880 | ||
| 26121 | const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, .{ .simple = .function_ret_ty }); | 25881 | const val = try sema.resolveGenericBody(block, ret_src, body, inst, .type, .{ .simple = .function_ret_ty }); |
| 26122 | const ty = val.toType(); | 25882 | const ty = val.toType(); |
| 26123 | break :blk ty; | 25883 | break :blk ty; |
| 26124 | } else if (extra.data.bits.has_ret_ty_ref) blk: { | 25884 | } else if (extra.data.bits.has_ret_ty_ref) blk: { |
| ... | @@ -26129,7 +25889,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26129,7 +25889,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26129 | const ret_ty_air_ref = try sema.resolveInst(ret_ty_ref); | 25889 | const ret_ty_air_ref = try sema.resolveInst(ret_ty_ref); |
| 26130 | const ret_ty_val = try sema.resolveConstDefinedValue(block, ret_src, ret_ty_air_ref, .{ .simple = .function_ret_ty }); | 25890 | const ret_ty_val = try sema.resolveConstDefinedValue(block, ret_src, ret_ty_air_ref, .{ .simple = .function_ret_ty }); |
| 26131 | break :blk ret_ty_val.toType(); | 25891 | break :blk ret_ty_val.toType(); |
| 26132 | } else Type.void; | 25892 | } else .void; |
| 26133 | 25893 | ||
| 26134 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { | 25894 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { |
| 26135 | const x = sema.code.extra[extra_index]; | 25895 | const x = sema.code.extra[extra_index]; |
| ... | @@ -26223,7 +25983,7 @@ fn zirWasmMemorySize( | ... | @@ -26223,7 +25983,7 @@ fn zirWasmMemorySize( |
| 26223 | return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); | 25983 | return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 26224 | } | 25984 | } |
| 26225 | 25985 | ||
| 26226 | const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.operand, Type.u32, .{ .simple = .wasm_memory_index })); | 25986 | const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.operand, .u32, .{ .simple = .wasm_memory_index })); |
| 26227 | try sema.requireRuntimeBlock(block, builtin_src, null); | 25987 | try sema.requireRuntimeBlock(block, builtin_src, null); |
| 26228 | return block.addInst(.{ | 25988 | return block.addInst(.{ |
| 26229 | .tag = .wasm_memory_size, | 25989 | .tag = .wasm_memory_size, |
| ... | @@ -26248,8 +26008,8 @@ fn zirWasmMemoryGrow( | ... | @@ -26248,8 +26008,8 @@ fn zirWasmMemoryGrow( |
| 26248 | return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); | 26008 | return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 26249 | } | 26009 | } |
| 26250 | 26010 | ||
| 26251 | const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, Type.u32, .{ .simple = .wasm_memory_index })); | 26011 | const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, .u32, .{ .simple = .wasm_memory_index })); |
| 26252 | const delta = try sema.coerce(block, Type.usize, try sema.resolveInst(extra.rhs), delta_src); | 26012 | const delta = try sema.coerce(block, .usize, try sema.resolveInst(extra.rhs), delta_src); |
| 26253 | 26013 | ||
| 26254 | try sema.requireRuntimeBlock(block, builtin_src, null); | 26014 | try sema.requireRuntimeBlock(block, builtin_src, null); |
| 26255 | return block.addInst(.{ | 26015 | return block.addInst(.{ |
| ... | @@ -26484,7 +26244,7 @@ fn zirWorkItem( | ... | @@ -26484,7 +26244,7 @@ fn zirWorkItem( |
| 26484 | }, | 26244 | }, |
| 26485 | } | 26245 | } |
| 26486 | 26246 | ||
| 26487 | const dimension: u32 = @intCast(try sema.resolveInt(block, dimension_src, extra.operand, Type.u32, .{ .simple = .work_group_dim_index })); | 26247 | const dimension: u32 = @intCast(try sema.resolveInt(block, dimension_src, extra.operand, .u32, .{ .simple = .work_group_dim_index })); |
| 26488 | try sema.requireRuntimeBlock(block, builtin_src, null); | 26248 | try sema.requireRuntimeBlock(block, builtin_src, null); |
| 26489 | 26249 | ||
| 26490 | return block.addInst(.{ | 26250 | return block.addInst(.{ |
| ... | @@ -26552,7 +26312,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -26552,7 +26312,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 26552 | const inline_tag_val = try pt.enumValue( | 26312 | const inline_tag_val = try pt.enumValue( |
| 26553 | callconv_tag_ty, | 26313 | callconv_tag_ty, |
| 26554 | (try pt.intValue( | 26314 | (try pt.intValue( |
| 26555 | Type.u8, | 26315 | .u8, |
| 26556 | @intFromEnum(std.builtin.CallingConvention.@"inline"), | 26316 | @intFromEnum(std.builtin.CallingConvention.@"inline"), |
| 26557 | )).toIntern(), | 26317 | )).toIntern(), |
| 26558 | ); | 26318 | ); |
| ... | @@ -26760,7 +26520,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26760,7 +26520,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26760 | 26520 | ||
| 26761 | if (zcu.typeToStruct(ty)) |struct_type| { | 26521 | if (zcu.typeToStruct(ty)) |struct_type| { |
| 26762 | for (0..struct_type.field_types.len) |i| { | 26522 | for (0..struct_type.field_types.len) |i| { |
| 26763 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 26523 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 26764 | const field_src: LazySrcLoc = .{ | 26524 | const field_src: LazySrcLoc = .{ |
| 26765 | .base_node_inst = struct_type.zir_index, | 26525 | .base_node_inst = struct_type.zir_index, |
| 26766 | .offset = .{ .container_field_type = @intCast(i) }, | 26526 | .offset = .{ .container_field_type = @intCast(i) }, |
| ... | @@ -26780,7 +26540,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26780,7 +26540,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26780 | 26540 | ||
| 26781 | if (zcu.typeToUnion(ty)) |union_obj| { | 26541 | if (zcu.typeToUnion(ty)) |union_obj| { |
| 26782 | for (0..union_obj.field_types.len) |i| { | 26542 | for (0..union_obj.field_types.len) |i| { |
| 26783 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[i]); | 26543 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]); |
| 26784 | const field_src: LazySrcLoc = .{ | 26544 | const field_src: LazySrcLoc = .{ |
| 26785 | .base_node_inst = union_obj.zir_index, | 26545 | .base_node_inst = union_obj.zir_index, |
| 26786 | .offset = .{ .container_field_type = @intCast(i) }, | 26546 | .offset = .{ .container_field_type = @intCast(i) }, |
| ... | @@ -27171,7 +26931,7 @@ fn addSafetyCheckUnwrapError( | ... | @@ -27171,7 +26931,7 @@ fn addSafetyCheckUnwrapError( |
| 27171 | 26931 | ||
| 27172 | defer fail_block.instructions.deinit(gpa); | 26932 | defer fail_block.instructions.deinit(gpa); |
| 27173 | 26933 | ||
| 27174 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); | 26934 | const err = try fail_block.addTyOp(unwrap_err_tag, .anyerror, operand); |
| 27175 | try safetyPanicUnwrapError(sema, &fail_block, src, err); | 26935 | try safetyPanicUnwrapError(sema, &fail_block, src, err); |
| 27176 | 26936 | ||
| 27177 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 26937 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | @@ -27344,7 +27104,7 @@ fn fieldVal( | ... | @@ -27344,7 +27104,7 @@ fn fieldVal( |
| 27344 | switch (inner_ty.zigTypeTag(zcu)) { | 27104 | switch (inner_ty.zigTypeTag(zcu)) { |
| 27345 | .array => { | 27105 | .array => { |
| 27346 | if (field_name.eqlSlice("len", ip)) { | 27106 | if (field_name.eqlSlice("len", ip)) { |
| 27347 | return Air.internedToRef((try pt.intValue(Type.usize, inner_ty.arrayLen(zcu))).toIntern()); | 27107 | return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern()); |
| 27348 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { | 27108 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27349 | const ptr_info = object_ty.ptrInfo(zcu); | 27109 | const ptr_info = object_ty.ptrInfo(zcu); |
| 27350 | const result_ty = try pt.ptrTypeSema(.{ | 27110 | const result_ty = try pt.ptrTypeSema(.{ |
| ... | @@ -27527,7 +27287,7 @@ fn fieldPtr( | ... | @@ -27527,7 +27287,7 @@ fn fieldPtr( |
| 27527 | switch (inner_ty.zigTypeTag(zcu)) { | 27287 | switch (inner_ty.zigTypeTag(zcu)) { |
| 27528 | .array => { | 27288 | .array => { |
| 27529 | if (field_name.eqlSlice("len", ip)) { | 27289 | if (field_name.eqlSlice("len", ip)) { |
| 27530 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(zcu)); | 27290 | const int_val = try pt.intValue(.usize, inner_ty.arrayLen(zcu)); |
| 27531 | return uavRef(sema, int_val.toIntern()); | 27291 | return uavRef(sema, int_val.toIntern()); |
| 27532 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { | 27292 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27533 | const ptr_info = object_ty.ptrInfo(zcu); | 27293 | const ptr_info = object_ty.ptrInfo(zcu); |
| ... | @@ -27769,12 +27529,12 @@ fn fieldCallBind( | ... | @@ -27769,12 +27529,12 @@ fn fieldCallBind( |
| 27769 | if (zcu.typeToStruct(concrete_ty)) |struct_type| { | 27529 | if (zcu.typeToStruct(concrete_ty)) |struct_type| { |
| 27770 | const field_index = struct_type.nameIndex(ip, field_name) orelse | 27530 | const field_index = struct_type.nameIndex(ip, field_name) orelse |
| 27771 | break :find_field; | 27531 | break :find_field; |
| 27772 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 27532 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 27773 | 27533 | ||
| 27774 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); | 27534 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); |
| 27775 | } else if (concrete_ty.isTuple(zcu)) { | 27535 | } else if (concrete_ty.isTuple(zcu)) { |
| 27776 | if (field_name.eqlSlice("len", ip)) { | 27536 | if (field_name.eqlSlice("len", ip)) { |
| 27777 | return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(zcu)) }; | 27537 | return .{ .direct = try pt.intRef(.usize, concrete_ty.structFieldCount(zcu)) }; |
| 27778 | } | 27538 | } |
| 27779 | if (field_name.toUnsigned(ip)) |field_index| { | 27539 | if (field_name.toUnsigned(ip)) |field_index| { |
| 27780 | if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field; | 27540 | if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field; |
| ... | @@ -27817,7 +27577,7 @@ fn fieldCallBind( | ... | @@ -27817,7 +27577,7 @@ fn fieldCallBind( |
| 27817 | if (zcu.typeToFunc(decl_type)) |func_type| f: { | 27577 | if (zcu.typeToFunc(decl_type)) |func_type| f: { |
| 27818 | if (func_type.param_types.len == 0) break :f; | 27578 | if (func_type.param_types.len == 0) break :f; |
| 27819 | 27579 | ||
| 27820 | const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]); | 27580 | const first_param_type: Type = .fromInterned(func_type.param_types.get(ip)[0]); |
| 27821 | if (first_param_type.isGenericPoison() or | 27581 | if (first_param_type.isGenericPoison() or |
| 27822 | (first_param_type.zigTypeTag(zcu) == .pointer and | 27582 | (first_param_type.zigTypeTag(zcu) == .pointer and |
| 27823 | (first_param_type.ptrSize(zcu) == .one or | 27583 | (first_param_type.ptrSize(zcu) == .one or |
| ... | @@ -28003,7 +27763,7 @@ fn structFieldPtr( | ... | @@ -28003,7 +27763,7 @@ fn structFieldPtr( |
| 28003 | 27763 | ||
| 28004 | if (struct_ty.isTuple(zcu)) { | 27764 | if (struct_ty.isTuple(zcu)) { |
| 28005 | if (field_name.eqlSlice("len", ip)) { | 27765 | if (field_name.eqlSlice("len", ip)) { |
| 28006 | const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(zcu)); | 27766 | const len_inst = try pt.intRef(.usize, struct_ty.structFieldCount(zcu)); |
| 28007 | return sema.analyzeRef(block, src, len_inst); | 27767 | return sema.analyzeRef(block, src, len_inst); |
| 28008 | } | 27768 | } |
| 28009 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); | 27769 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); |
| ... | @@ -28134,7 +27894,7 @@ fn structFieldVal( | ... | @@ -28134,7 +27894,7 @@ fn structFieldVal( |
| 28134 | return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]); | 27894 | return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]); |
| 28135 | } | 27895 | } |
| 28136 | 27896 | ||
| 28137 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 27897 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 28138 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_val| | 27898 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_val| |
| 28139 | return Air.internedToRef(field_val.toIntern()); | 27899 | return Air.internedToRef(field_val.toIntern()); |
| 28140 | 27900 | ||
| ... | @@ -28167,7 +27927,7 @@ fn tupleFieldVal( | ... | @@ -28167,7 +27927,7 @@ fn tupleFieldVal( |
| 28167 | const pt = sema.pt; | 27927 | const pt = sema.pt; |
| 28168 | const zcu = pt.zcu; | 27928 | const zcu = pt.zcu; |
| 28169 | if (field_name.eqlSlice("len", &zcu.intern_pool)) { | 27929 | if (field_name.eqlSlice("len", &zcu.intern_pool)) { |
| 28170 | return pt.intRef(Type.usize, tuple_ty.structFieldCount(zcu)); | 27930 | return pt.intRef(.usize, tuple_ty.structFieldCount(zcu)); |
| 28171 | } | 27931 | } |
| 28172 | const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src); | 27932 | const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src); |
| 28173 | return sema.tupleFieldValByIndex(block, tuple_byval, field_index, tuple_ty); | 27933 | return sema.tupleFieldValByIndex(block, tuple_byval, field_index, tuple_ty); |
| ... | @@ -28220,7 +27980,7 @@ fn tupleFieldValByIndex( | ... | @@ -28220,7 +27980,7 @@ fn tupleFieldValByIndex( |
| 28220 | return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) { | 27980 | return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) { |
| 28221 | .undef => pt.undefRef(field_ty), | 27981 | .undef => pt.undefRef(field_ty), |
| 28222 | .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) { | 27982 | .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) { |
| 28223 | .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &zcu.intern_pool)), | 27983 | .bytes => |bytes| try pt.intValue(.u8, bytes.at(field_index, &zcu.intern_pool)), |
| 28224 | .elems => |elems| Value.fromInterned(elems[field_index]), | 27984 | .elems => |elems| Value.fromInterned(elems[field_index]), |
| 28225 | .repeated_elem => |elem| Value.fromInterned(elem), | 27985 | .repeated_elem => |elem| Value.fromInterned(elem), |
| 28226 | }.toIntern()), | 27986 | }.toIntern()), |
| ... | @@ -28253,7 +28013,7 @@ fn unionFieldPtr( | ... | @@ -28253,7 +28013,7 @@ fn unionFieldPtr( |
| 28253 | try union_ty.resolveFields(pt); | 28013 | try union_ty.resolveFields(pt); |
| 28254 | const union_obj = zcu.typeToUnion(union_ty).?; | 28014 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 28255 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); | 28015 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 28256 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28016 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28257 | const ptr_field_ty = try pt.ptrTypeSema(.{ | 28017 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 28258 | .child = field_ty.toIntern(), | 28018 | .child = field_ty.toIntern(), |
| 28259 | .flags = .{ | 28019 | .flags = .{ |
| ... | @@ -28295,8 +28055,8 @@ fn unionFieldPtr( | ... | @@ -28295,8 +28055,8 @@ fn unionFieldPtr( |
| 28295 | break :ct; | 28055 | break :ct; |
| 28296 | } | 28056 | } |
| 28297 | // Store to the union to initialize the tag. | 28057 | // Store to the union to initialize the tag. |
| 28298 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28058 | const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28299 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28059 | const payload_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28300 | const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty)); | 28060 | const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty)); |
| 28301 | try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty); | 28061 | try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty); |
| 28302 | } else { | 28062 | } else { |
| ... | @@ -28306,7 +28066,7 @@ fn unionFieldPtr( | ... | @@ -28306,7 +28066,7 @@ fn unionFieldPtr( |
| 28306 | return sema.failWithUseOfUndef(block, src); | 28066 | return sema.failWithUseOfUndef(block, src); |
| 28307 | } | 28067 | } |
| 28308 | const un = ip.indexToKey(union_val.toIntern()).un; | 28068 | const un = ip.indexToKey(union_val.toIntern()).un; |
| 28309 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28069 | const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28310 | const tag_matches = un.tag == field_tag.toIntern(); | 28070 | const tag_matches = un.tag == field_tag.toIntern(); |
| 28311 | if (!tag_matches) { | 28071 | if (!tag_matches) { |
| 28312 | const msg = msg: { | 28072 | const msg = msg: { |
| ... | @@ -28332,11 +28092,11 @@ fn unionFieldPtr( | ... | @@ -28332,11 +28092,11 @@ fn unionFieldPtr( |
| 28332 | if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and | 28092 | if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and |
| 28333 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) | 28093 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) |
| 28334 | { | 28094 | { |
| 28335 | const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28095 | const wanted_tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28336 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); | 28096 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); |
| 28337 | // TODO would it be better if get_union_tag supported pointers to unions? | 28097 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 28338 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); | 28098 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| 28339 | const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_val); | 28099 | const active_tag = try block.addTyOp(.get_union_tag, .fromInterned(union_obj.enum_tag_ty), union_val); |
| 28340 | try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag); | 28100 | try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag); |
| 28341 | } | 28101 | } |
| 28342 | if (field_ty.zigTypeTag(zcu) == .noreturn) { | 28102 | if (field_ty.zigTypeTag(zcu) == .noreturn) { |
| ... | @@ -28363,14 +28123,14 @@ fn unionFieldVal( | ... | @@ -28363,14 +28123,14 @@ fn unionFieldVal( |
| 28363 | try union_ty.resolveFields(pt); | 28123 | try union_ty.resolveFields(pt); |
| 28364 | const union_obj = zcu.typeToUnion(union_ty).?; | 28124 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 28365 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); | 28125 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 28366 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28126 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28367 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?); | 28127 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?); |
| 28368 | 28128 | ||
| 28369 | if (try sema.resolveValue(union_byval)) |union_val| { | 28129 | if (try sema.resolveValue(union_byval)) |union_val| { |
| 28370 | if (union_val.isUndef(zcu)) return pt.undefRef(field_ty); | 28130 | if (union_val.isUndef(zcu)) return pt.undefRef(field_ty); |
| 28371 | 28131 | ||
| 28372 | const un = ip.indexToKey(union_val.toIntern()).un; | 28132 | const un = ip.indexToKey(union_val.toIntern()).un; |
| 28373 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28133 | const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28374 | const tag_matches = un.tag == field_tag.toIntern(); | 28134 | const tag_matches = un.tag == field_tag.toIntern(); |
| 28375 | switch (union_obj.flagsUnordered(ip).layout) { | 28135 | switch (union_obj.flagsUnordered(ip).layout) { |
| 28376 | .auto => { | 28136 | .auto => { |
| ... | @@ -28408,9 +28168,9 @@ fn unionFieldVal( | ... | @@ -28408,9 +28168,9 @@ fn unionFieldVal( |
| 28408 | if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and | 28168 | if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and |
| 28409 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) | 28169 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) |
| 28410 | { | 28170 | { |
| 28411 | const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28171 | const wanted_tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28412 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); | 28172 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); |
| 28413 | const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval); | 28173 | const active_tag = try block.addTyOp(.get_union_tag, .fromInterned(union_obj.enum_tag_ty), union_byval); |
| 28414 | try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag); | 28174 | try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag); |
| 28415 | } | 28175 | } |
| 28416 | if (field_ty.zigTypeTag(zcu) == .noreturn) { | 28176 | if (field_ty.zigTypeTag(zcu) == .noreturn) { |
| ... | @@ -28540,7 +28300,7 @@ fn elemVal( | ... | @@ -28540,7 +28300,7 @@ fn elemVal( |
| 28540 | 28300 | ||
| 28541 | // TODO in case of a vector of pointers, we need to detect whether the element | 28301 | // TODO in case of a vector of pointers, we need to detect whether the element |
| 28542 | // index is a scalar or vector instead of unconditionally casting to usize. | 28302 | // index is a scalar or vector instead of unconditionally casting to usize. |
| 28543 | const elem_index = try sema.coerce(block, Type.usize, elem_index_uncasted, elem_index_src); | 28303 | const elem_index = try sema.coerce(block, .usize, elem_index_uncasted, elem_index_src); |
| 28544 | 28304 | ||
| 28545 | switch (indexable_ty.zigTypeTag(zcu)) { | 28305 | switch (indexable_ty.zigTypeTag(zcu)) { |
| 28546 | .pointer => switch (indexable_ty.ptrSize(zcu)) { | 28306 | .pointer => switch (indexable_ty.ptrSize(zcu)) { |
| ... | @@ -28795,7 +28555,7 @@ fn elemValArray( | ... | @@ -28795,7 +28555,7 @@ fn elemValArray( |
| 28795 | if (oob_safety and block.wantSafety()) { | 28555 | if (oob_safety and block.wantSafety()) { |
| 28796 | // Runtime check is only needed if unable to comptime check. | 28556 | // Runtime check is only needed if unable to comptime check. |
| 28797 | if (maybe_index_val == null) { | 28557 | if (maybe_index_val == null) { |
| 28798 | const len_inst = try pt.intRef(Type.usize, array_len); | 28558 | const len_inst = try pt.intRef(.usize, array_len); |
| 28799 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; | 28559 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; |
| 28800 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); | 28560 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); |
| 28801 | } | 28561 | } |
| ... | @@ -28860,7 +28620,7 @@ fn elemPtrArray( | ... | @@ -28860,7 +28620,7 @@ fn elemPtrArray( |
| 28860 | 28620 | ||
| 28861 | // Runtime check is only needed if unable to comptime check. | 28621 | // Runtime check is only needed if unable to comptime check. |
| 28862 | if (oob_safety and block.wantSafety() and offset == null) { | 28622 | if (oob_safety and block.wantSafety() and offset == null) { |
| 28863 | const len_inst = try pt.intRef(Type.usize, array_len); | 28623 | const len_inst = try pt.intRef(.usize, array_len); |
| 28864 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; | 28624 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; |
| 28865 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); | 28625 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); |
| 28866 | } | 28626 | } |
| ... | @@ -28917,9 +28677,9 @@ fn elemValSlice( | ... | @@ -28917,9 +28677,9 @@ fn elemValSlice( |
| 28917 | 28677 | ||
| 28918 | if (oob_safety and block.wantSafety()) { | 28678 | if (oob_safety and block.wantSafety()) { |
| 28919 | const len_inst = if (maybe_slice_val) |slice_val| | 28679 | const len_inst = if (maybe_slice_val) |slice_val| |
| 28920 | try pt.intRef(Type.usize, try slice_val.sliceLen(pt)) | 28680 | try pt.intRef(.usize, try slice_val.sliceLen(pt)) |
| 28921 | else | 28681 | else |
| 28922 | try block.addTyOp(.slice_len, Type.usize, slice); | 28682 | try block.addTyOp(.slice_len, .usize, slice); |
| 28923 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 28683 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 28924 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); | 28684 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); |
| 28925 | } | 28685 | } |
| ... | @@ -28976,8 +28736,8 @@ fn elemPtrSlice( | ... | @@ -28976,8 +28736,8 @@ fn elemPtrSlice( |
| 28976 | const len_inst = len: { | 28736 | const len_inst = len: { |
| 28977 | if (maybe_undef_slice_val) |slice_val| | 28737 | if (maybe_undef_slice_val) |slice_val| |
| 28978 | if (!slice_val.isUndef(zcu)) | 28738 | if (!slice_val.isUndef(zcu)) |
| 28979 | break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt)); | 28739 | break :len try pt.intRef(.usize, try slice_val.sliceLen(pt)); |
| 28980 | break :len try block.addTyOp(.slice_len, Type.usize, slice); | 28740 | break :len try block.addTyOp(.slice_len, .usize, slice); |
| 28981 | }; | 28741 | }; |
| 28982 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 28742 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 28983 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); | 28743 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); |
| ... | @@ -29142,7 +28902,7 @@ fn coerceExtra( | ... | @@ -29142,7 +28902,7 @@ fn coerceExtra( |
| 29142 | if (!inst_ty.isSinglePointer(zcu)) break :single_item; | 28902 | if (!inst_ty.isSinglePointer(zcu)) break :single_item; |
| 29143 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; | 28903 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; |
| 29144 | const ptr_elem_ty = inst_ty.childType(zcu); | 28904 | const ptr_elem_ty = inst_ty.childType(zcu); |
| 29145 | const array_ty = Type.fromInterned(dest_info.child); | 28905 | const array_ty: Type = .fromInterned(dest_info.child); |
| 29146 | if (array_ty.zigTypeTag(zcu) != .array) break :single_item; | 28906 | if (array_ty.zigTypeTag(zcu) != .array) break :single_item; |
| 29147 | const array_elem_ty = array_ty.childType(zcu); | 28907 | const array_elem_ty = array_ty.childType(zcu); |
| 29148 | if (array_ty.arrayLen(zcu) != 1) break :single_item; | 28908 | if (array_ty.arrayLen(zcu) != 1) break :single_item; |
| ... | @@ -29164,7 +28924,7 @@ fn coerceExtra( | ... | @@ -29164,7 +28924,7 @@ fn coerceExtra( |
| 29164 | const array_elem_type = array_ty.childType(zcu); | 28924 | const array_elem_type = array_ty.childType(zcu); |
| 29165 | const dest_is_mut = !dest_info.flags.is_const; | 28925 | const dest_is_mut = !dest_info.flags.is_const; |
| 29166 | 28926 | ||
| 29167 | const dst_elem_type = Type.fromInterned(dest_info.child); | 28927 | const dst_elem_type: Type = .fromInterned(dest_info.child); |
| 29168 | const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val); | 28928 | const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val); |
| 29169 | switch (elem_res) { | 28929 | switch (elem_res) { |
| 29170 | .ok => {}, | 28930 | .ok => {}, |
| ... | @@ -29225,7 +28985,7 @@ fn coerceExtra( | ... | @@ -29225,7 +28985,7 @@ fn coerceExtra( |
| 29225 | // could be null. | 28985 | // could be null. |
| 29226 | const src_elem_ty = inst_ty.childType(zcu); | 28986 | const src_elem_ty = inst_ty.childType(zcu); |
| 29227 | const dest_is_mut = !dest_info.flags.is_const; | 28987 | const dest_is_mut = !dest_info.flags.is_const; |
| 29228 | const dst_elem_type = Type.fromInterned(dest_info.child); | 28988 | const dst_elem_type: Type = .fromInterned(dest_info.child); |
| 29229 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) { | 28989 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) { |
| 29230 | .ok => {}, | 28990 | .ok => {}, |
| 29231 | else => break :src_c_ptr, | 28991 | else => break :src_c_ptr, |
| ... | @@ -29265,16 +29025,16 @@ fn coerceExtra( | ... | @@ -29265,16 +29025,16 @@ fn coerceExtra( |
| 29265 | .byte_offset = 0, | 29025 | .byte_offset = 0, |
| 29266 | } })), | 29026 | } })), |
| 29267 | .comptime_int => { | 29027 | .comptime_int => { |
| 29268 | const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { | 29028 | const addr = sema.coerceExtra(block, .usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { |
| 29269 | error.NotCoercible => break :pointer, | 29029 | error.NotCoercible => break :pointer, |
| 29270 | else => |e| return e, | 29030 | else => |e| return e, |
| 29271 | }; | 29031 | }; |
| 29272 | return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src); | 29032 | return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src); |
| 29273 | }, | 29033 | }, |
| 29274 | .int => { | 29034 | .int => { |
| 29275 | const ptr_size_ty = switch (inst_ty.intInfo(zcu).signedness) { | 29035 | const ptr_size_ty: Type = switch (inst_ty.intInfo(zcu).signedness) { |
| 29276 | .signed => Type.isize, | 29036 | .signed => .isize, |
| 29277 | .unsigned => Type.usize, | 29037 | .unsigned => .usize, |
| 29278 | }; | 29038 | }; |
| 29279 | const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { | 29039 | const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { |
| 29280 | error.NotCoercible => { | 29040 | error.NotCoercible => { |
| ... | @@ -29291,8 +29051,8 @@ fn coerceExtra( | ... | @@ -29291,8 +29051,8 @@ fn coerceExtra( |
| 29291 | const inst_info = inst_ty.ptrInfo(zcu); | 29051 | const inst_info = inst_ty.ptrInfo(zcu); |
| 29292 | switch (try sema.coerceInMemoryAllowed( | 29052 | switch (try sema.coerceInMemoryAllowed( |
| 29293 | block, | 29053 | block, |
| 29294 | Type.fromInterned(dest_info.child), | 29054 | .fromInterned(dest_info.child), |
| 29295 | Type.fromInterned(inst_info.child), | 29055 | .fromInterned(inst_info.child), |
| 29296 | !dest_info.flags.is_const, | 29056 | !dest_info.flags.is_const, |
| 29297 | target, | 29057 | target, |
| 29298 | dest_ty_src, | 29058 | dest_ty_src, |
| ... | @@ -29305,7 +29065,7 @@ fn coerceExtra( | ... | @@ -29305,7 +29065,7 @@ fn coerceExtra( |
| 29305 | if (inst_info.flags.size == .slice) { | 29065 | if (inst_info.flags.size == .slice) { |
| 29306 | assert(dest_info.sentinel == .none); | 29066 | assert(dest_info.sentinel == .none); |
| 29307 | if (inst_info.sentinel == .none or | 29067 | if (inst_info.sentinel == .none or |
| 29308 | inst_info.sentinel != (try pt.intValue(Type.fromInterned(inst_info.child), 0)).toIntern()) | 29068 | inst_info.sentinel != (try pt.intValue(.fromInterned(inst_info.child), 0)).toIntern()) |
| 29309 | break :p; | 29069 | break :p; |
| 29310 | 29070 | ||
| 29311 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 29071 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -29364,8 +29124,8 @@ fn coerceExtra( | ... | @@ -29364,8 +29124,8 @@ fn coerceExtra( |
| 29364 | 29124 | ||
| 29365 | switch (try sema.coerceInMemoryAllowed( | 29125 | switch (try sema.coerceInMemoryAllowed( |
| 29366 | block, | 29126 | block, |
| 29367 | Type.fromInterned(dest_info.child), | 29127 | .fromInterned(dest_info.child), |
| 29368 | Type.fromInterned(inst_info.child), | 29128 | .fromInterned(inst_info.child), |
| 29369 | !dest_info.flags.is_const, | 29129 | !dest_info.flags.is_const, |
| 29370 | target, | 29130 | target, |
| 29371 | dest_ty_src, | 29131 | dest_ty_src, |
| ... | @@ -29378,7 +29138,7 @@ fn coerceExtra( | ... | @@ -29378,7 +29138,7 @@ fn coerceExtra( |
| 29378 | 29138 | ||
| 29379 | if (dest_info.sentinel == .none or inst_info.sentinel == .none or | 29139 | if (dest_info.sentinel == .none or inst_info.sentinel == .none or |
| 29380 | Air.internedToRef(dest_info.sentinel) != | 29140 | Air.internedToRef(dest_info.sentinel) != |
| 29381 | try sema.coerceInMemory(Value.fromInterned(inst_info.sentinel), Type.fromInterned(dest_info.child))) | 29141 | try sema.coerceInMemory(Value.fromInterned(inst_info.sentinel), .fromInterned(dest_info.child))) |
| 29382 | break :p; | 29142 | break :p; |
| 29383 | 29143 | ||
| 29384 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 29144 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -30658,8 +30418,8 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -30658,8 +30418,8 @@ fn coerceInMemoryAllowedPtrs( |
| 30658 | } }; | 30418 | } }; |
| 30659 | } | 30419 | } |
| 30660 | 30420 | ||
| 30661 | const dest_child = Type.fromInterned(dest_info.child); | 30421 | const dest_child: Type = .fromInterned(dest_info.child); |
| 30662 | const src_child = Type.fromInterned(src_info.child); | 30422 | const src_child: Type = .fromInterned(src_info.child); |
| 30663 | const child = try sema.coerceInMemoryAllowed( | 30423 | const child = try sema.coerceInMemoryAllowed( |
| 30664 | block, | 30424 | block, |
| 30665 | dest_child, | 30425 | dest_child, |
| ... | @@ -30731,7 +30491,7 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -30731,7 +30491,7 @@ fn coerceInMemoryAllowedPtrs( |
| 30731 | .none => Value.@"unreachable", | 30491 | .none => Value.@"unreachable", |
| 30732 | else => Value.fromInterned(dest_info.sentinel), | 30492 | else => Value.fromInterned(dest_info.sentinel), |
| 30733 | }, | 30493 | }, |
| 30734 | .ty = Type.fromInterned(dest_info.child), | 30494 | .ty = .fromInterned(dest_info.child), |
| 30735 | } }; | 30495 | } }; |
| 30736 | } | 30496 | } |
| 30737 | 30497 | ||
| ... | @@ -30794,8 +30554,8 @@ fn coerceVarArgParam( | ... | @@ -30794,8 +30554,8 @@ fn coerceVarArgParam( |
| 30794 | const inst_bits = uncasted_ty.floatBits(target); | 30554 | const inst_bits = uncasted_ty.floatBits(target); |
| 30795 | if (inst_bits >= double_bits) break :float inst; | 30555 | if (inst_bits >= double_bits) break :float inst; |
| 30796 | switch (double_bits) { | 30556 | switch (double_bits) { |
| 30797 | 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src), | 30557 | 32 => break :float try sema.coerce(block, .f32, inst, inst_src), |
| 30798 | 64 => break :float try sema.coerce(block, Type.f64, inst, inst_src), | 30558 | 64 => break :float try sema.coerce(block, .f64, inst, inst_src), |
| 30799 | else => unreachable, | 30559 | else => unreachable, |
| 30800 | } | 30560 | } |
| 30801 | }, | 30561 | }, |
| ... | @@ -30807,22 +30567,22 @@ fn coerceVarArgParam( | ... | @@ -30807,22 +30567,22 @@ fn coerceVarArgParam( |
| 30807 | .signed => .int, | 30567 | .signed => .int, |
| 30808 | .unsigned => .uint, | 30568 | .unsigned => .uint, |
| 30809 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 30569 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 30810 | .signed => Type.c_int, | 30570 | .signed => .c_int, |
| 30811 | .unsigned => Type.c_uint, | 30571 | .unsigned => .c_uint, |
| 30812 | }, inst, inst_src); | 30572 | }, inst, inst_src); |
| 30813 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { | 30573 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { |
| 30814 | .signed => .long, | 30574 | .signed => .long, |
| 30815 | .unsigned => .ulong, | 30575 | .unsigned => .ulong, |
| 30816 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 30576 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 30817 | .signed => Type.c_long, | 30577 | .signed => .c_long, |
| 30818 | .unsigned => Type.c_ulong, | 30578 | .unsigned => .c_ulong, |
| 30819 | }, inst, inst_src); | 30579 | }, inst, inst_src); |
| 30820 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { | 30580 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { |
| 30821 | .signed => .longlong, | 30581 | .signed => .longlong, |
| 30822 | .unsigned => .ulonglong, | 30582 | .unsigned => .ulonglong, |
| 30823 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 30583 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 30824 | .signed => Type.c_longlong, | 30584 | .signed => .c_longlong, |
| 30825 | .unsigned => Type.c_ulonglong, | 30585 | .unsigned => .c_ulonglong, |
| 30826 | }, inst, inst_src); | 30586 | }, inst, inst_src); |
| 30827 | break :int inst; | 30587 | break :int inst; |
| 30828 | } else inst, | 30588 | } else inst, |
| ... | @@ -30889,7 +30649,7 @@ fn storePtr2( | ... | @@ -30889,7 +30649,7 @@ fn storePtr2( |
| 30889 | while (i < field_count) : (i += 1) { | 30649 | while (i < field_count) : (i += 1) { |
| 30890 | const elem_src = operand_src; // TODO better source location | 30650 | const elem_src = operand_src; // TODO better source location |
| 30891 | const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i); | 30651 | const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i); |
| 30892 | const elem_index = try pt.intRef(Type.usize, i); | 30652 | const elem_index = try pt.intRef(.usize, i); |
| 30893 | const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true); | 30653 | const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true); |
| 30894 | try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store); | 30654 | try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store); |
| 30895 | } | 30655 | } |
| ... | @@ -31216,7 +30976,7 @@ fn coerceArrayPtrToSlice( | ... | @@ -31216,7 +30976,7 @@ fn coerceArrayPtrToSlice( |
| 31216 | const slice_val = try pt.intern(.{ .slice = .{ | 30976 | const slice_val = try pt.intern(.{ .slice = .{ |
| 31217 | .ty = dest_ty.toIntern(), | 30977 | .ty = dest_ty.toIntern(), |
| 31218 | .ptr = slice_ptr.toIntern(), | 30978 | .ptr = slice_ptr.toIntern(), |
| 31219 | .len = (try pt.intValue(Type.usize, array_ty.arrayLen(zcu))).toIntern(), | 30979 | .len = (try pt.intValue(.usize, array_ty.arrayLen(zcu))).toIntern(), |
| 31220 | } }); | 30980 | } }); |
| 31221 | return Air.internedToRef(slice_val); | 30981 | return Air.internedToRef(slice_val); |
| 31222 | } | 30982 | } |
| ... | @@ -31358,7 +31118,7 @@ fn coerceEnumToUnion( | ... | @@ -31358,7 +31118,7 @@ fn coerceEnumToUnion( |
| 31358 | }; | 31118 | }; |
| 31359 | 31119 | ||
| 31360 | const union_obj = zcu.typeToUnion(union_ty).?; | 31120 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 31361 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 31121 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31362 | try field_ty.resolveFields(pt); | 31122 | try field_ty.resolveFields(pt); |
| 31363 | if (field_ty.zigTypeTag(zcu) == .noreturn) { | 31123 | if (field_ty.zigTypeTag(zcu) == .noreturn) { |
| 31364 | const msg = msg: { | 31124 | const msg = msg: { |
| ... | @@ -31448,7 +31208,7 @@ fn coerceEnumToUnion( | ... | @@ -31448,7 +31208,7 @@ fn coerceEnumToUnion( |
| 31448 | 31208 | ||
| 31449 | for (0..union_obj.field_types.len) |field_index| { | 31209 | for (0..union_obj.field_types.len) |field_index| { |
| 31450 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; | 31210 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; |
| 31451 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 31211 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31452 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; | 31212 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; |
| 31453 | try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ | 31213 | try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ |
| 31454 | field_name.fmt(ip), | 31214 | field_name.fmt(ip), |
| ... | @@ -31536,7 +31296,7 @@ fn coerceArrayLike( | ... | @@ -31536,7 +31296,7 @@ fn coerceArrayLike( |
| 31536 | var runtime_src: ?LazySrcLoc = null; | 31296 | var runtime_src: ?LazySrcLoc = null; |
| 31537 | 31297 | ||
| 31538 | for (element_vals, element_refs, 0..) |*val, *ref, i| { | 31298 | for (element_vals, element_refs, 0..) |*val, *ref, i| { |
| 31539 | const index_ref = Air.internedToRef((try pt.intValue(Type.usize, i)).toIntern()); | 31299 | const index_ref = Air.internedToRef((try pt.intValue(.usize, i)).toIntern()); |
| 31540 | const src = inst_src; // TODO better source location | 31300 | const src = inst_src; // TODO better source location |
| 31541 | const elem_src = inst_src; // TODO better source location | 31301 | const elem_src = inst_src; // TODO better source location |
| 31542 | const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true); | 31302 | const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true); |
| ... | @@ -31668,7 +31428,7 @@ fn coerceTupleToArrayPtrs( | ... | @@ -31668,7 +31428,7 @@ fn coerceTupleToArrayPtrs( |
| 31668 | const zcu = pt.zcu; | 31428 | const zcu = pt.zcu; |
| 31669 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); | 31429 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 31670 | const ptr_info = ptr_array_ty.ptrInfo(zcu); | 31430 | const ptr_info = ptr_array_ty.ptrInfo(zcu); |
| 31671 | const array_ty = Type.fromInterned(ptr_info.child); | 31431 | const array_ty: Type = .fromInterned(ptr_info.child); |
| 31672 | const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); | 31432 | const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); |
| 31673 | if (ptr_info.flags.alignment != .none) { | 31433 | if (ptr_info.flags.alignment != .none) { |
| 31674 | return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{}); | 31434 | return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{}); |
| ... | @@ -31721,14 +31481,14 @@ fn coerceTupleToTuple( | ... | @@ -31721,14 +31481,14 @@ fn coerceTupleToTuple( |
| 31721 | const field_index: u32 = @intCast(field_index_usize); | 31481 | const field_index: u32 = @intCast(field_index_usize); |
| 31722 | 31482 | ||
| 31723 | const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i); | 31483 | const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i); |
| 31724 | const coerced = try sema.coerce(block, Type.fromInterned(field_ty), elem_ref, field_src); | 31484 | const coerced = try sema.coerce(block, .fromInterned(field_ty), elem_ref, field_src); |
| 31725 | field_refs[field_index] = coerced; | 31485 | field_refs[field_index] = coerced; |
| 31726 | if (default_val != .none) { | 31486 | if (default_val != .none) { |
| 31727 | const init_val = (try sema.resolveValue(coerced)) orelse { | 31487 | const init_val = (try sema.resolveValue(coerced)) orelse { |
| 31728 | return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field }); | 31488 | return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field }); |
| 31729 | }; | 31489 | }; |
| 31730 | 31490 | ||
| 31731 | if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), pt.zcu)) { | 31491 | if (!init_val.eql(Value.fromInterned(default_val), .fromInterned(field_ty), pt.zcu)) { |
| 31732 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i); | 31492 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i); |
| 31733 | } | 31493 | } |
| 31734 | } | 31494 | } |
| ... | @@ -31885,7 +31645,7 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: | ... | @@ -31885,7 +31645,7 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: |
| 31885 | 31645 | ||
| 31886 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | 31646 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| 31887 | const pt = sema.pt; | 31647 | const pt = sema.pt; |
| 31888 | const ptr_anyopaque_ty = try pt.singleConstPtrType(Type.anyopaque); | 31648 | const ptr_anyopaque_ty = try pt.singleConstPtrType(.anyopaque); |
| 31889 | return Value.fromInterned(try pt.intern(.{ .opt = .{ | 31649 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 31890 | .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), | 31650 | .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), |
| 31891 | .val = if (opt_val) |val| (try pt.getCoerced( | 31651 | .val = if (opt_val) |val| (try pt.getCoerced( |
| ... | @@ -32140,12 +31900,12 @@ fn analyzeSliceLen( | ... | @@ -32140,12 +31900,12 @@ fn analyzeSliceLen( |
| 32140 | const zcu = pt.zcu; | 31900 | const zcu = pt.zcu; |
| 32141 | if (try sema.resolveValue(slice_inst)) |slice_val| { | 31901 | if (try sema.resolveValue(slice_inst)) |slice_val| { |
| 32142 | if (slice_val.isUndef(zcu)) { | 31902 | if (slice_val.isUndef(zcu)) { |
| 32143 | return pt.undefRef(Type.usize); | 31903 | return .undef_usize; |
| 32144 | } | 31904 | } |
| 32145 | return pt.intRef(Type.usize, try slice_val.sliceLen(pt)); | 31905 | return pt.intRef(.usize, try slice_val.sliceLen(pt)); |
| 32146 | } | 31906 | } |
| 32147 | try sema.requireRuntimeBlock(block, src, null); | 31907 | try sema.requireRuntimeBlock(block, src, null); |
| 32148 | return block.addTyOp(.slice_len, Type.usize, slice_inst); | 31908 | return block.addTyOp(.slice_len, .usize, slice_inst); |
| 32149 | } | 31909 | } |
| 32150 | 31910 | ||
| 32151 | fn analyzeIsNull( | 31911 | fn analyzeIsNull( |
| ... | @@ -32156,7 +31916,7 @@ fn analyzeIsNull( | ... | @@ -32156,7 +31916,7 @@ fn analyzeIsNull( |
| 32156 | ) CompileError!Air.Inst.Ref { | 31916 | ) CompileError!Air.Inst.Ref { |
| 32157 | const pt = sema.pt; | 31917 | const pt = sema.pt; |
| 32158 | const zcu = pt.zcu; | 31918 | const zcu = pt.zcu; |
| 32159 | const result_ty = Type.bool; | 31919 | const result_ty: Type = .bool; |
| 32160 | if (try sema.resolveValue(operand)) |opt_val| { | 31920 | if (try sema.resolveValue(operand)) |opt_val| { |
| 32161 | if (opt_val.isUndef(zcu)) { | 31921 | if (opt_val.isUndef(zcu)) { |
| 32162 | return pt.undefRef(result_ty); | 31922 | return pt.undefRef(result_ty); |
| ... | @@ -32224,7 +31984,7 @@ fn analyzeIsNonErrComptimeOnly( | ... | @@ -32224,7 +31984,7 @@ fn analyzeIsNonErrComptimeOnly( |
| 32224 | else => {}, | 31984 | else => {}, |
| 32225 | } | 31985 | } |
| 32226 | } else if (operand == .undef) { | 31986 | } else if (operand == .undef) { |
| 32227 | return pt.undefRef(Type.bool); | 31987 | return .undef_bool; |
| 32228 | } else if (@intFromEnum(operand) < InternPool.static_len) { | 31988 | } else if (@intFromEnum(operand) < InternPool.static_len) { |
| 32229 | // None of the ref tags can be errors. | 31989 | // None of the ref tags can be errors. |
| 32230 | return .bool_true; | 31990 | return .bool_true; |
| ... | @@ -32308,14 +32068,7 @@ fn analyzeIsNonErrComptimeOnly( | ... | @@ -32308,14 +32068,7 @@ fn analyzeIsNonErrComptimeOnly( |
| 32308 | } | 32068 | } |
| 32309 | 32069 | ||
| 32310 | if (maybe_operand_val) |err_union| { | 32070 | if (maybe_operand_val) |err_union| { |
| 32311 | if (err_union.isUndef(zcu)) { | 32071 | return if (err_union.isUndef(zcu)) .undef_bool else if (err_union.getErrorName(zcu) == .none) .bool_true else .bool_false; |
| 32312 | return pt.undefRef(Type.bool); | ||
| 32313 | } | ||
| 32314 | if (err_union.getErrorName(zcu) == .none) { | ||
| 32315 | return .bool_true; | ||
| 32316 | } else { | ||
| 32317 | return .bool_false; | ||
| 32318 | } | ||
| 32319 | } | 32072 | } |
| 32320 | return .none; | 32073 | return .none; |
| 32321 | } | 32074 | } |
| ... | @@ -32412,8 +32165,8 @@ fn analyzeSlice( | ... | @@ -32412,8 +32165,8 @@ fn analyzeSlice( |
| 32412 | ); | 32165 | ); |
| 32413 | 32166 | ||
| 32414 | const bounds_error_message = "slice of single-item pointer must have bounds [0..0], [0..1], or [1..1]"; | 32167 | const bounds_error_message = "slice of single-item pointer must have bounds [0..0], [0..1], or [1..1]"; |
| 32415 | if (try sema.compareScalar(start_value, .neq, end_value, Type.comptime_int)) { | 32168 | if (try sema.compareScalar(start_value, .neq, end_value, .comptime_int)) { |
| 32416 | if (try sema.compareScalar(start_value, .neq, Value.zero_comptime_int, Type.comptime_int)) { | 32169 | if (try sema.compareScalar(start_value, .neq, Value.zero_comptime_int, .comptime_int)) { |
| 32417 | const msg = msg: { | 32170 | const msg = msg: { |
| 32418 | const msg = try sema.errMsg(start_src, bounds_error_message, .{}); | 32171 | const msg = try sema.errMsg(start_src, bounds_error_message, .{}); |
| 32419 | errdefer msg.destroy(sema.gpa); | 32172 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -32429,7 +32182,7 @@ fn analyzeSlice( | ... | @@ -32429,7 +32182,7 @@ fn analyzeSlice( |
| 32429 | break :msg msg; | 32182 | break :msg msg; |
| 32430 | }; | 32183 | }; |
| 32431 | return sema.failWithOwnedErrorMsg(block, msg); | 32184 | return sema.failWithOwnedErrorMsg(block, msg); |
| 32432 | } else if (try sema.compareScalar(end_value, .neq, Value.one_comptime_int, Type.comptime_int)) { | 32185 | } else if (try sema.compareScalar(end_value, .neq, Value.one_comptime_int, .comptime_int)) { |
| 32433 | const msg = msg: { | 32186 | const msg = msg: { |
| 32434 | const msg = try sema.errMsg(end_src, bounds_error_message, .{}); | 32187 | const msg = try sema.errMsg(end_src, bounds_error_message, .{}); |
| 32435 | errdefer msg.destroy(sema.gpa); | 32188 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -32447,7 +32200,7 @@ fn analyzeSlice( | ... | @@ -32447,7 +32200,7 @@ fn analyzeSlice( |
| 32447 | return sema.failWithOwnedErrorMsg(block, msg); | 32200 | return sema.failWithOwnedErrorMsg(block, msg); |
| 32448 | } | 32201 | } |
| 32449 | } else { | 32202 | } else { |
| 32450 | if (try sema.compareScalar(end_value, .gt, Value.one_comptime_int, Type.comptime_int)) { | 32203 | if (try sema.compareScalar(end_value, .gt, Value.one_comptime_int, .comptime_int)) { |
| 32451 | return sema.fail( | 32204 | return sema.fail( |
| 32452 | block, | 32205 | block, |
| 32453 | end_src, | 32206 | end_src, |
| ... | @@ -32512,7 +32265,7 @@ fn analyzeSlice( | ... | @@ -32512,7 +32265,7 @@ fn analyzeSlice( |
| 32512 | break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src); | 32265 | break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src); |
| 32513 | } else ptr_or_slice; | 32266 | } else ptr_or_slice; |
| 32514 | 32267 | ||
| 32515 | const start = try sema.coerce(block, Type.usize, uncasted_start, start_src); | 32268 | const start = try sema.coerce(block, .usize, uncasted_start, start_src); |
| 32516 | const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); | 32269 | const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); |
| 32517 | const new_ptr_ty = sema.typeOf(new_ptr); | 32270 | const new_ptr_ty = sema.typeOf(new_ptr); |
| 32518 | 32271 | ||
| ... | @@ -32523,20 +32276,20 @@ fn analyzeSlice( | ... | @@ -32523,20 +32276,20 @@ fn analyzeSlice( |
| 32523 | var end_is_len = uncasted_end_opt == .none; | 32276 | var end_is_len = uncasted_end_opt == .none; |
| 32524 | const end = e: { | 32277 | const end = e: { |
| 32525 | if (array_ty.zigTypeTag(zcu) == .array) { | 32278 | if (array_ty.zigTypeTag(zcu) == .array) { |
| 32526 | const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(zcu)); | 32279 | const len_val = try pt.intValue(.usize, array_ty.arrayLen(zcu)); |
| 32527 | 32280 | ||
| 32528 | if (!end_is_len) { | 32281 | if (!end_is_len) { |
| 32529 | const end = if (by_length) end: { | 32282 | const end = if (by_length) end: { |
| 32530 | const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32283 | const len = try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32531 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); | 32284 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); |
| 32532 | break :end try sema.coerce(block, Type.usize, uncasted_end, end_src); | 32285 | break :end try sema.coerce(block, .usize, uncasted_end, end_src); |
| 32533 | } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32286 | } else try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32534 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { | 32287 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32535 | const len_s_val = try pt.intValue( | 32288 | const len_s_val = try pt.intValue( |
| 32536 | Type.usize, | 32289 | .usize, |
| 32537 | array_ty.arrayLenIncludingSentinel(zcu), | 32290 | array_ty.arrayLenIncludingSentinel(zcu), |
| 32538 | ); | 32291 | ); |
| 32539 | if (!(try sema.compareAll(end_val, .lte, len_s_val, Type.usize))) { | 32292 | if (!(try sema.compareAll(end_val, .lte, len_s_val, .usize))) { |
| 32540 | const sentinel_label: []const u8 = if (array_ty.sentinel(zcu) != null) | 32293 | const sentinel_label: []const u8 = if (array_ty.sentinel(zcu) != null) |
| 32541 | " +1 (sentinel)" | 32294 | " +1 (sentinel)" |
| 32542 | else | 32295 | else |
| ... | @@ -32557,7 +32310,7 @@ fn analyzeSlice( | ... | @@ -32557,7 +32310,7 @@ fn analyzeSlice( |
| 32557 | // end_is_len is only true if we are NOT using the sentinel | 32310 | // end_is_len is only true if we are NOT using the sentinel |
| 32558 | // length. For sentinel-length, we don't want the type to | 32311 | // length. For sentinel-length, we don't want the type to |
| 32559 | // contain the sentinel. | 32312 | // contain the sentinel. |
| 32560 | if (end_val.eql(len_val, Type.usize, zcu)) { | 32313 | if (end_val.eql(len_val, .usize, zcu)) { |
| 32561 | end_is_len = true; | 32314 | end_is_len = true; |
| 32562 | } | 32315 | } |
| 32563 | } | 32316 | } |
| ... | @@ -32568,10 +32321,10 @@ fn analyzeSlice( | ... | @@ -32568,10 +32321,10 @@ fn analyzeSlice( |
| 32568 | } else if (slice_ty.isSlice(zcu)) { | 32321 | } else if (slice_ty.isSlice(zcu)) { |
| 32569 | if (!end_is_len) { | 32322 | if (!end_is_len) { |
| 32570 | const end = if (by_length) end: { | 32323 | const end = if (by_length) end: { |
| 32571 | const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32324 | const len = try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32572 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); | 32325 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); |
| 32573 | break :end try sema.coerce(block, Type.usize, uncasted_end, end_src); | 32326 | break :end try sema.coerce(block, .usize, uncasted_end, end_src); |
| 32574 | } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32327 | } else try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32575 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { | 32328 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32576 | if (try sema.resolveValue(ptr_or_slice)) |slice_val| { | 32329 | if (try sema.resolveValue(ptr_or_slice)) |slice_val| { |
| 32577 | if (slice_val.isUndef(zcu)) { | 32330 | if (slice_val.isUndef(zcu)) { |
| ... | @@ -32580,8 +32333,8 @@ fn analyzeSlice( | ... | @@ -32580,8 +32333,8 @@ fn analyzeSlice( |
| 32580 | const has_sentinel = slice_ty.sentinel(zcu) != null; | 32333 | const has_sentinel = slice_ty.sentinel(zcu) != null; |
| 32581 | const slice_len = try slice_val.sliceLen(pt); | 32334 | const slice_len = try slice_val.sliceLen(pt); |
| 32582 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); | 32335 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); |
| 32583 | const slice_len_val_with_sentinel = try pt.intValue(Type.usize, len_plus_sent); | 32336 | const slice_len_val_with_sentinel = try pt.intValue(.usize, len_plus_sent); |
| 32584 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) { | 32337 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, .usize))) { |
| 32585 | const sentinel_label: []const u8 = if (has_sentinel) | 32338 | const sentinel_label: []const u8 = if (has_sentinel) |
| 32586 | " +1 (sentinel)" | 32339 | " +1 (sentinel)" |
| 32587 | else | 32340 | else |
| ... | @@ -32602,8 +32355,8 @@ fn analyzeSlice( | ... | @@ -32602,8 +32355,8 @@ fn analyzeSlice( |
| 32602 | // If the slice has a sentinel, we consider end_is_len | 32355 | // If the slice has a sentinel, we consider end_is_len |
| 32603 | // is only true if it equals the length WITHOUT the | 32356 | // is only true if it equals the length WITHOUT the |
| 32604 | // sentinel, so we don't add a sentinel type. | 32357 | // sentinel, so we don't add a sentinel type. |
| 32605 | const slice_len_val = try pt.intValue(Type.usize, slice_len); | 32358 | const slice_len_val = try pt.intValue(.usize, slice_len); |
| 32606 | if (end_val.eql(slice_len_val, Type.usize, zcu)) { | 32359 | if (end_val.eql(slice_len_val, .usize, zcu)) { |
| 32607 | end_is_len = true; | 32360 | end_is_len = true; |
| 32608 | } | 32361 | } |
| 32609 | } | 32362 | } |
| ... | @@ -32614,10 +32367,10 @@ fn analyzeSlice( | ... | @@ -32614,10 +32367,10 @@ fn analyzeSlice( |
| 32614 | } | 32367 | } |
| 32615 | if (!end_is_len) { | 32368 | if (!end_is_len) { |
| 32616 | if (by_length) { | 32369 | if (by_length) { |
| 32617 | const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32370 | const len = try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32618 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); | 32371 | const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false); |
| 32619 | break :e try sema.coerce(block, Type.usize, uncasted_end, end_src); | 32372 | break :e try sema.coerce(block, .usize, uncasted_end, end_src); |
| 32620 | } else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32373 | } else break :e try sema.coerce(block, .usize, uncasted_end_opt, end_src); |
| 32621 | } | 32374 | } |
| 32622 | return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); | 32375 | return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); |
| 32623 | }; | 32376 | }; |
| ... | @@ -32645,7 +32398,7 @@ fn analyzeSlice( | ... | @@ -32645,7 +32398,7 @@ fn analyzeSlice( |
| 32645 | // requirement: start <= end | 32398 | // requirement: start <= end |
| 32646 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { | 32399 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32647 | if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { | 32400 | if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { |
| 32648 | if (!by_length and !(try sema.compareAll(start_val, .lte, end_val, Type.usize))) { | 32401 | if (!by_length and !(try sema.compareAll(start_val, .lte, end_val, .usize))) { |
| 32649 | return sema.fail( | 32402 | return sema.fail( |
| 32650 | block, | 32403 | block, |
| 32651 | start_src, | 32404 | start_src, |
| ... | @@ -32715,7 +32468,7 @@ fn analyzeSlice( | ... | @@ -32715,7 +32468,7 @@ fn analyzeSlice( |
| 32715 | try sema.addSafetyCheckCall(block, src, ok, .@"panic.startGreaterThanEnd", &.{ start, end }); | 32468 | try sema.addSafetyCheckCall(block, src, ok, .@"panic.startGreaterThanEnd", &.{ start, end }); |
| 32716 | } | 32469 | } |
| 32717 | const new_len = if (by_length) | 32470 | const new_len = if (by_length) |
| 32718 | try sema.coerce(block, Type.usize, uncasted_end_opt, end_src) | 32471 | try sema.coerce(block, .usize, uncasted_end_opt, end_src) |
| 32719 | else | 32472 | else |
| 32720 | try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); | 32473 | try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); |
| 32721 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); | 32474 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| ... | @@ -32753,9 +32506,9 @@ fn analyzeSlice( | ... | @@ -32753,9 +32506,9 @@ fn analyzeSlice( |
| 32753 | 32506 | ||
| 32754 | bounds_check: { | 32507 | bounds_check: { |
| 32755 | const actual_len = if (array_ty.zigTypeTag(zcu) == .array) | 32508 | const actual_len = if (array_ty.zigTypeTag(zcu) == .array) |
| 32756 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(zcu)) | 32509 | try pt.intRef(.usize, array_ty.arrayLenIncludingSentinel(zcu)) |
| 32757 | else if (slice_ty.isSlice(zcu)) l: { | 32510 | else if (slice_ty.isSlice(zcu)) l: { |
| 32758 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | 32511 | const slice_len_inst = try block.addTyOp(.slice_len, .usize, ptr_or_slice); |
| 32759 | break :l if (slice_ty.sentinel(zcu) == null) | 32512 | break :l if (slice_ty.sentinel(zcu) == null) |
| 32760 | slice_len_inst | 32513 | slice_len_inst |
| 32761 | else | 32514 | else |
| ... | @@ -32811,15 +32564,15 @@ fn analyzeSlice( | ... | @@ -32811,15 +32564,15 @@ fn analyzeSlice( |
| 32811 | 32564 | ||
| 32812 | // requirement: end <= len | 32565 | // requirement: end <= len |
| 32813 | const opt_len_inst = if (array_ty.zigTypeTag(zcu) == .array) | 32566 | const opt_len_inst = if (array_ty.zigTypeTag(zcu) == .array) |
| 32814 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(zcu)) | 32567 | try pt.intRef(.usize, array_ty.arrayLenIncludingSentinel(zcu)) |
| 32815 | else if (slice_ty.isSlice(zcu)) blk: { | 32568 | else if (slice_ty.isSlice(zcu)) blk: { |
| 32816 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { | 32569 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { |
| 32817 | // we don't need to add one for sentinels because the | 32570 | // we don't need to add one for sentinels because the |
| 32818 | // underlying value data includes the sentinel | 32571 | // underlying value data includes the sentinel |
| 32819 | break :blk try pt.intRef(Type.usize, try slice_val.sliceLen(pt)); | 32572 | break :blk try pt.intRef(.usize, try slice_val.sliceLen(pt)); |
| 32820 | } | 32573 | } |
| 32821 | 32574 | ||
| 32822 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | 32575 | const slice_len_inst = try block.addTyOp(.slice_len, .usize, ptr_or_slice); |
| 32823 | if (slice_ty.sentinel(zcu) == null) break :blk slice_len_inst; | 32576 | if (slice_ty.sentinel(zcu) == null) break :blk slice_len_inst; |
| 32824 | 32577 | ||
| 32825 | // we have to add one because slice lengths don't include the sentinel | 32578 | // we have to add one because slice lengths don't include the sentinel |
| ... | @@ -32935,8 +32688,8 @@ fn cmpNumeric( | ... | @@ -32935,8 +32688,8 @@ fn cmpNumeric( |
| 32935 | } | 32688 | } |
| 32936 | 32689 | ||
| 32937 | // Any other comparison depends on both values, so the result is undef if either is undef. | 32690 | // Any other comparison depends on both values, so the result is undef if either is undef. |
| 32938 | if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool); | 32691 | if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool; |
| 32939 | if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool); | 32692 | if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool; |
| 32940 | 32693 | ||
| 32941 | const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: { | 32694 | const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: { |
| 32942 | if (maybe_rhs_val) |rhs_val| { | 32695 | if (maybe_rhs_val) |rhs_val| { |
| ... | @@ -33646,7 +33399,7 @@ fn resolvePeerTypes( | ... | @@ -33646,7 +33399,7 @@ fn resolvePeerTypes( |
| 33646 | candidate_srcs: PeerTypeCandidateSrc, | 33399 | candidate_srcs: PeerTypeCandidateSrc, |
| 33647 | ) !Type { | 33400 | ) !Type { |
| 33648 | switch (instructions.len) { | 33401 | switch (instructions.len) { |
| 33649 | 0 => return Type.noreturn, | 33402 | 0 => return .noreturn, |
| 33650 | 1 => return sema.typeOf(instructions[0]), | 33403 | 1 => return sema.typeOf(instructions[0]), |
| 33651 | else => {}, | 33404 | else => {}, |
| 33652 | } | 33405 | } |
| ... | @@ -33780,12 +33533,12 @@ fn resolvePeerTypesInner( | ... | @@ -33780,12 +33533,12 @@ fn resolvePeerTypesInner( |
| 33780 | .nullable => { | 33533 | .nullable => { |
| 33781 | for (peer_tys, 0..) |opt_ty, i| { | 33534 | for (peer_tys, 0..) |opt_ty, i| { |
| 33782 | const ty = opt_ty orelse continue; | 33535 | const ty = opt_ty orelse continue; |
| 33783 | if (!ty.eql(Type.null, zcu)) return .{ .conflict = .{ | 33536 | if (!ty.eql(.null, zcu)) return .{ .conflict = .{ |
| 33784 | .peer_idx_a = strat_reason, | 33537 | .peer_idx_a = strat_reason, |
| 33785 | .peer_idx_b = i, | 33538 | .peer_idx_b = i, |
| 33786 | } }; | 33539 | } }; |
| 33787 | } | 33540 | } |
| 33788 | return .{ .success = Type.null }; | 33541 | return .{ .success = .null }; |
| 33789 | }, | 33542 | }, |
| 33790 | 33543 | ||
| 33791 | .optional => { | 33544 | .optional => { |
| ... | @@ -34006,7 +33759,7 @@ fn resolvePeerTypesInner( | ... | @@ -34006,7 +33759,7 @@ fn resolvePeerTypesInner( |
| 34006 | }; | 33759 | }; |
| 34007 | 33760 | ||
| 34008 | // Try peer -> cur, then cur -> peer | 33761 | // Try peer -> cur, then cur -> peer |
| 34009 | ptr_info.child = ((try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), Type.fromInterned(peer_info.child))) orelse { | 33762 | ptr_info.child = ((try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), .fromInterned(peer_info.child))) orelse { |
| 34010 | return .{ .conflict = .{ | 33763 | return .{ .conflict = .{ |
| 34011 | .peer_idx_a = first_idx, | 33764 | .peer_idx_a = first_idx, |
| 34012 | .peer_idx_b = i, | 33765 | .peer_idx_b = i, |
| ... | @@ -34153,8 +33906,8 @@ fn resolvePeerTypesInner( | ... | @@ -34153,8 +33906,8 @@ fn resolvePeerTypesInner( |
| 34153 | }; | 33906 | }; |
| 34154 | 33907 | ||
| 34155 | // We abstract array handling slightly so that tuple pointers can work like array pointers | 33908 | // We abstract array handling slightly so that tuple pointers can work like array pointers |
| 34156 | const peer_pointee_array = sema.typeIsArrayLike(Type.fromInterned(peer_info.child)); | 33909 | const peer_pointee_array = sema.typeIsArrayLike(.fromInterned(peer_info.child)); |
| 34157 | const cur_pointee_array = sema.typeIsArrayLike(Type.fromInterned(ptr_info.child)); | 33910 | const cur_pointee_array = sema.typeIsArrayLike(.fromInterned(ptr_info.child)); |
| 34158 | 33911 | ||
| 34159 | // This switch is just responsible for deciding the size and pointee (not including | 33912 | // This switch is just responsible for deciding the size and pointee (not including |
| 34160 | // single-pointer array sentinel). | 33913 | // single-pointer array sentinel). |
| ... | @@ -34162,7 +33915,7 @@ fn resolvePeerTypesInner( | ... | @@ -34162,7 +33915,7 @@ fn resolvePeerTypesInner( |
| 34162 | switch (peer_info.flags.size) { | 33915 | switch (peer_info.flags.size) { |
| 34163 | .one => switch (ptr_info.flags.size) { | 33916 | .one => switch (ptr_info.flags.size) { |
| 34164 | .one => { | 33917 | .one => { |
| 34165 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), Type.fromInterned(peer_info.child))) |pointee| { | 33918 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), .fromInterned(peer_info.child))) |pointee| { |
| 34166 | ptr_info.child = pointee.toIntern(); | 33919 | ptr_info.child = pointee.toIntern(); |
| 34167 | break :good; | 33920 | break :good; |
| 34168 | } | 33921 | } |
| ... | @@ -34204,7 +33957,7 @@ fn resolvePeerTypesInner( | ... | @@ -34204,7 +33957,7 @@ fn resolvePeerTypesInner( |
| 34204 | .many => { | 33957 | .many => { |
| 34205 | // Only works for *[n]T + [*]T -> [*]T | 33958 | // Only works for *[n]T + [*]T -> [*]T |
| 34206 | const arr = peer_pointee_array orelse return generic_err; | 33959 | const arr = peer_pointee_array orelse return generic_err; |
| 34207 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), arr.elem_ty)) |pointee| { | 33960 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), arr.elem_ty)) |pointee| { |
| 34208 | ptr_info.child = pointee.toIntern(); | 33961 | ptr_info.child = pointee.toIntern(); |
| 34209 | break :good; | 33962 | break :good; |
| 34210 | } | 33963 | } |
| ... | @@ -34217,7 +33970,7 @@ fn resolvePeerTypesInner( | ... | @@ -34217,7 +33970,7 @@ fn resolvePeerTypesInner( |
| 34217 | .slice => { | 33970 | .slice => { |
| 34218 | // Only works for *[n]T + []T -> []T | 33971 | // Only works for *[n]T + []T -> []T |
| 34219 | const arr = peer_pointee_array orelse return generic_err; | 33972 | const arr = peer_pointee_array orelse return generic_err; |
| 34220 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), arr.elem_ty)) |pointee| { | 33973 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), arr.elem_ty)) |pointee| { |
| 34221 | ptr_info.child = pointee.toIntern(); | 33974 | ptr_info.child = pointee.toIntern(); |
| 34222 | break :good; | 33975 | break :good; |
| 34223 | } | 33976 | } |
| ... | @@ -34233,7 +33986,7 @@ fn resolvePeerTypesInner( | ... | @@ -34233,7 +33986,7 @@ fn resolvePeerTypesInner( |
| 34233 | .one => { | 33986 | .one => { |
| 34234 | // Only works for [*]T + *[n]T -> [*]T | 33987 | // Only works for [*]T + *[n]T -> [*]T |
| 34235 | const arr = cur_pointee_array orelse return generic_err; | 33988 | const arr = cur_pointee_array orelse return generic_err; |
| 34236 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, Type.fromInterned(peer_info.child))) |pointee| { | 33989 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, .fromInterned(peer_info.child))) |pointee| { |
| 34237 | ptr_info.flags.size = .many; | 33990 | ptr_info.flags.size = .many; |
| 34238 | ptr_info.child = pointee.toIntern(); | 33991 | ptr_info.child = pointee.toIntern(); |
| 34239 | break :good; | 33992 | break :good; |
| ... | @@ -34247,7 +34000,7 @@ fn resolvePeerTypesInner( | ... | @@ -34247,7 +34000,7 @@ fn resolvePeerTypesInner( |
| 34247 | return generic_err; | 34000 | return generic_err; |
| 34248 | }, | 34001 | }, |
| 34249 | .many => { | 34002 | .many => { |
| 34250 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), Type.fromInterned(peer_info.child))) |pointee| { | 34003 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), .fromInterned(peer_info.child))) |pointee| { |
| 34251 | ptr_info.child = pointee.toIntern(); | 34004 | ptr_info.child = pointee.toIntern(); |
| 34252 | break :good; | 34005 | break :good; |
| 34253 | } | 34006 | } |
| ... | @@ -34262,7 +34015,7 @@ fn resolvePeerTypesInner( | ... | @@ -34262,7 +34015,7 @@ fn resolvePeerTypesInner( |
| 34262 | } }; | 34015 | } }; |
| 34263 | } | 34016 | } |
| 34264 | // Okay, then works for [*]T + "[]T" -> [*]T | 34017 | // Okay, then works for [*]T + "[]T" -> [*]T |
| 34265 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), Type.fromInterned(peer_info.child))) |pointee| { | 34018 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), .fromInterned(peer_info.child))) |pointee| { |
| 34266 | ptr_info.flags.size = .many; | 34019 | ptr_info.flags.size = .many; |
| 34267 | ptr_info.child = pointee.toIntern(); | 34020 | ptr_info.child = pointee.toIntern(); |
| 34268 | break :good; | 34021 | break :good; |
| ... | @@ -34275,7 +34028,7 @@ fn resolvePeerTypesInner( | ... | @@ -34275,7 +34028,7 @@ fn resolvePeerTypesInner( |
| 34275 | .one => { | 34028 | .one => { |
| 34276 | // Only works for []T + *[n]T -> []T | 34029 | // Only works for []T + *[n]T -> []T |
| 34277 | const arr = cur_pointee_array orelse return generic_err; | 34030 | const arr = cur_pointee_array orelse return generic_err; |
| 34278 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, Type.fromInterned(peer_info.child))) |pointee| { | 34031 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, .fromInterned(peer_info.child))) |pointee| { |
| 34279 | ptr_info.flags.size = .slice; | 34032 | ptr_info.flags.size = .slice; |
| 34280 | ptr_info.child = pointee.toIntern(); | 34033 | ptr_info.child = pointee.toIntern(); |
| 34281 | break :good; | 34034 | break :good; |
| ... | @@ -34293,7 +34046,7 @@ fn resolvePeerTypesInner( | ... | @@ -34293,7 +34046,7 @@ fn resolvePeerTypesInner( |
| 34293 | return generic_err; | 34046 | return generic_err; |
| 34294 | }, | 34047 | }, |
| 34295 | .slice => { | 34048 | .slice => { |
| 34296 | if (try sema.resolvePairInMemoryCoercible(block, src, Type.fromInterned(ptr_info.child), Type.fromInterned(peer_info.child))) |pointee| { | 34049 | if (try sema.resolvePairInMemoryCoercible(block, src, .fromInterned(ptr_info.child), .fromInterned(peer_info.child))) |pointee| { |
| 34297 | ptr_info.child = pointee.toIntern(); | 34050 | ptr_info.child = pointee.toIntern(); |
| 34298 | break :good; | 34051 | break :good; |
| 34299 | } | 34052 | } |
| ... | @@ -34479,7 +34232,7 @@ fn resolvePeerTypesInner( | ... | @@ -34479,7 +34232,7 @@ fn resolvePeerTypesInner( |
| 34479 | } }, | 34232 | } }, |
| 34480 | } | 34233 | } |
| 34481 | } | 34234 | } |
| 34482 | return .{ .success = Type.comptime_int }; | 34235 | return .{ .success = .comptime_int }; |
| 34483 | }, | 34236 | }, |
| 34484 | 34237 | ||
| 34485 | .comptime_float => { | 34238 | .comptime_float => { |
| ... | @@ -34493,7 +34246,7 @@ fn resolvePeerTypesInner( | ... | @@ -34493,7 +34246,7 @@ fn resolvePeerTypesInner( |
| 34493 | } }, | 34246 | } }, |
| 34494 | } | 34247 | } |
| 34495 | } | 34248 | } |
| 34496 | return .{ .success = Type.comptime_float }; | 34249 | return .{ .success = .comptime_float }; |
| 34497 | }, | 34250 | }, |
| 34498 | 34251 | ||
| 34499 | .fixed_int => { | 34252 | .fixed_int => { |
| ... | @@ -34601,11 +34354,11 @@ fn resolvePeerTypesInner( | ... | @@ -34601,11 +34354,11 @@ fn resolvePeerTypesInner( |
| 34601 | // Recreate the type so we eliminate any c_longdouble | 34354 | // Recreate the type so we eliminate any c_longdouble |
| 34602 | const bits = @max(cur_ty.floatBits(target), ty.floatBits(target)); | 34355 | const bits = @max(cur_ty.floatBits(target), ty.floatBits(target)); |
| 34603 | opt_cur_ty = switch (bits) { | 34356 | opt_cur_ty = switch (bits) { |
| 34604 | 16 => Type.f16, | 34357 | 16 => .f16, |
| 34605 | 32 => Type.f32, | 34358 | 32 => .f32, |
| 34606 | 64 => Type.f64, | 34359 | 64 => .f64, |
| 34607 | 80 => Type.f80, | 34360 | 80 => .f80, |
| 34608 | 128 => Type.f128, | 34361 | 128 => .f128, |
| 34609 | else => unreachable, | 34362 | else => unreachable, |
| 34610 | }; | 34363 | }; |
| 34611 | } else { | 34364 | } else { |
| ... | @@ -34716,7 +34469,7 @@ fn resolvePeerTypesInner( | ... | @@ -34716,7 +34469,7 @@ fn resolvePeerTypesInner( |
| 34716 | break; | 34469 | break; |
| 34717 | }; | 34470 | }; |
| 34718 | const uncoerced_field = Air.internedToRef(uncoerced_field_val.toIntern()); | 34471 | const uncoerced_field = Air.internedToRef(uncoerced_field_val.toIntern()); |
| 34719 | const coerced_inst = sema.coerceExtra(block, Type.fromInterned(field_ty.*), uncoerced_field, src, .{ .report_err = false }) catch |err| switch (err) { | 34472 | const coerced_inst = sema.coerceExtra(block, .fromInterned(field_ty.*), uncoerced_field, src, .{ .report_err = false }) catch |err| switch (err) { |
| 34720 | // It's possible for PTR to give false positives. Just give up on making this a comptime field, we'll get an error later anyway | 34473 | // It's possible for PTR to give false positives. Just give up on making this a comptime field, we'll get an error later anyway |
| 34721 | error.NotCoercible => { | 34474 | error.NotCoercible => { |
| 34722 | comptime_val = null; | 34475 | comptime_val = null; |
| ... | @@ -34729,7 +34482,7 @@ fn resolvePeerTypesInner( | ... | @@ -34729,7 +34482,7 @@ fn resolvePeerTypesInner( |
| 34729 | comptime_val = coerced_val; | 34482 | comptime_val = coerced_val; |
| 34730 | continue; | 34483 | continue; |
| 34731 | }; | 34484 | }; |
| 34732 | if (!coerced_val.eql(existing, Type.fromInterned(field_ty.*), zcu)) { | 34485 | if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) { |
| 34733 | comptime_val = null; | 34486 | comptime_val = null; |
| 34734 | break; | 34487 | break; |
| 34735 | } | 34488 | } |
| ... | @@ -34743,7 +34496,7 @@ fn resolvePeerTypesInner( | ... | @@ -34743,7 +34496,7 @@ fn resolvePeerTypesInner( |
| 34743 | .values = field_vals, | 34496 | .values = field_vals, |
| 34744 | }); | 34497 | }); |
| 34745 | 34498 | ||
| 34746 | return .{ .success = Type.fromInterned(final_ty) }; | 34499 | return .{ .success = .fromInterned(final_ty) }; |
| 34747 | }, | 34500 | }, |
| 34748 | 34501 | ||
| 34749 | .exact => { | 34502 | .exact => { |
| ... | @@ -34813,7 +34566,7 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { | ... | @@ -34813,7 +34566,7 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { |
| 34813 | const field_count = ty.structFieldCount(zcu); | 34566 | const field_count = ty.structFieldCount(zcu); |
| 34814 | if (field_count == 0) return .{ | 34567 | if (field_count == 0) return .{ |
| 34815 | .len = 0, | 34568 | .len = 0, |
| 34816 | .elem_ty = Type.noreturn, | 34569 | .elem_ty = .noreturn, |
| 34817 | }; | 34570 | }; |
| 34818 | if (!ty.isTuple(zcu)) return null; | 34571 | if (!ty.isTuple(zcu)) return null; |
| 34819 | const elem_ty = ty.fieldType(0, zcu); | 34572 | const elem_ty = ty.fieldType(0, zcu); |
| ... | @@ -34902,7 +34655,7 @@ pub fn resolveStructAlignment( | ... | @@ -34902,7 +34655,7 @@ pub fn resolveStructAlignment( |
| 34902 | var alignment: Alignment = .@"1"; | 34655 | var alignment: Alignment = .@"1"; |
| 34903 | 34656 | ||
| 34904 | for (0..struct_type.field_types.len) |i| { | 34657 | for (0..struct_type.field_types.len) |i| { |
| 34905 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 34658 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 34906 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) | 34659 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) |
| 34907 | continue; | 34660 | continue; |
| 34908 | const field_align = try field_ty.structFieldAlignmentSema( | 34661 | const field_align = try field_ty.structFieldAlignmentSema( |
| ... | @@ -34953,7 +34706,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -34953,7 +34706,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34953 | var big_align: Alignment = .@"1"; | 34706 | var big_align: Alignment = .@"1"; |
| 34954 | 34707 | ||
| 34955 | for (aligns, sizes, 0..) |*field_align, *field_size, i| { | 34708 | for (aligns, sizes, 0..) |*field_align, *field_size, i| { |
| 34956 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 34709 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 34957 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { | 34710 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { |
| 34958 | struct_type.offsets.get(ip)[i] = 0; | 34711 | struct_type.offsets.get(ip)[i] = 0; |
| 34959 | field_size.* = 0; | 34712 | field_size.* = 0; |
| ... | @@ -35001,7 +34754,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35001,7 +34754,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35001 | const runtime_order = struct_type.runtime_order.get(ip); | 34754 | const runtime_order = struct_type.runtime_order.get(ip); |
| 35002 | 34755 | ||
| 35003 | for (runtime_order, 0..) |*ro, i| { | 34756 | for (runtime_order, 0..) |*ro, i| { |
| 35004 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 34757 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 35005 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { | 34758 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { |
| 35006 | ro.* = .omitted; | 34759 | ro.* = .omitted; |
| 35007 | } else { | 34760 | } else { |
| ... | @@ -35095,7 +34848,7 @@ fn backingIntType( | ... | @@ -35095,7 +34848,7 @@ fn backingIntType( |
| 35095 | const fields_bit_sum = blk: { | 34848 | const fields_bit_sum = blk: { |
| 35096 | var accumulator: u64 = 0; | 34849 | var accumulator: u64 = 0; |
| 35097 | for (0..struct_type.field_types.len) |i| { | 34850 | for (0..struct_type.field_types.len) |i| { |
| 35098 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 34851 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 35099 | accumulator += try field_ty.bitSizeSema(pt); | 34852 | accumulator += try field_ty.bitSizeSema(pt); |
| 35100 | } | 34853 | } |
| 35101 | break :blk accumulator; | 34854 | break :blk accumulator; |
| ... | @@ -35234,7 +34987,7 @@ pub fn resolveUnionAlignment( | ... | @@ -35234,7 +34987,7 @@ pub fn resolveUnionAlignment( |
| 35234 | 34987 | ||
| 35235 | var max_align: Alignment = .@"1"; | 34988 | var max_align: Alignment = .@"1"; |
| 35236 | for (0..union_type.field_types.len) |field_index| { | 34989 | for (0..union_type.field_types.len) |field_index| { |
| 35237 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); | 34990 | const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]); |
| 35238 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; | 34991 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; |
| 35239 | 34992 | ||
| 35240 | const explicit_align = union_type.fieldAlign(ip, field_index); | 34993 | const explicit_align = union_type.fieldAlign(ip, field_index); |
| ... | @@ -35282,7 +35035,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35282,7 +35035,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35282 | var max_size: u64 = 0; | 35035 | var max_size: u64 = 0; |
| 35283 | var max_align: Alignment = .@"1"; | 35036 | var max_align: Alignment = .@"1"; |
| 35284 | for (0..union_type.field_types.len) |field_index| { | 35037 | for (0..union_type.field_types.len) |field_index| { |
| 35285 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); | 35038 | const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]); |
| 35286 | 35039 | ||
| 35287 | if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .noreturn) continue; // TODO: should this affect alignment? | 35040 | if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .noreturn) continue; // TODO: should this affect alignment? |
| 35288 | 35041 | ||
| ... | @@ -35307,7 +35060,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35307,7 +35060,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35307 | const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and | 35060 | const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and |
| 35308 | try Type.fromInterned(union_type.enum_tag_ty).hasRuntimeBitsSema(pt); | 35061 | try Type.fromInterned(union_type.enum_tag_ty).hasRuntimeBitsSema(pt); |
| 35309 | const size, const alignment, const padding = if (has_runtime_tag) layout: { | 35062 | const size, const alignment, const padding = if (has_runtime_tag) layout: { |
| 35310 | const enum_tag_type = Type.fromInterned(union_type.enum_tag_ty); | 35063 | const enum_tag_type: Type = .fromInterned(union_type.enum_tag_ty); |
| 35311 | const tag_align = try enum_tag_type.abiAlignmentSema(pt); | 35064 | const tag_align = try enum_tag_type.abiAlignmentSema(pt); |
| 35312 | const tag_size = try enum_tag_type.abiSizeSema(pt); | 35065 | const tag_size = try enum_tag_type.abiSizeSema(pt); |
| 35313 | 35066 | ||
| ... | @@ -35392,7 +35145,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35392,7 +35145,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { |
| 35392 | // See also similar code for unions. | 35145 | // See also similar code for unions. |
| 35393 | 35146 | ||
| 35394 | for (0..struct_type.field_types.len) |i| { | 35147 | for (0..struct_type.field_types.len) |i| { |
| 35395 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 35148 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 35396 | try field_ty.resolveFully(pt); | 35149 | try field_ty.resolveFully(pt); |
| 35397 | } | 35150 | } |
| 35398 | } | 35151 | } |
| ... | @@ -35421,7 +35174,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35421,7 +35174,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35421 | 35174 | ||
| 35422 | union_obj.setStatus(ip, .fully_resolved_wip); | 35175 | union_obj.setStatus(ip, .fully_resolved_wip); |
| 35423 | for (0..union_obj.field_types.len) |field_index| { | 35176 | for (0..union_obj.field_types.len) |field_index| { |
| 35424 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 35177 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 35425 | try field_ty.resolveFully(pt); | 35178 | try field_ty.resolveFully(pt); |
| 35426 | } | 35179 | } |
| 35427 | union_obj.setStatus(ip, .fully_resolved); | 35180 | union_obj.setStatus(ip, .fully_resolved); |
| ... | @@ -35553,7 +35306,7 @@ fn resolveInferredErrorSet( | ... | @@ -35553,7 +35306,7 @@ fn resolveInferredErrorSet( |
| 35553 | // set. However, in the case of comptime/inline function calls with | 35306 | // set. However, in the case of comptime/inline function calls with |
| 35554 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which | 35307 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which |
| 35555 | // has no corresponding function body. | 35308 | // has no corresponding function body. |
| 35556 | const ies_func_info = zcu.typeToFunc(Type.fromInterned(func.ty)).?; | 35309 | const ies_func_info = zcu.typeToFunc(.fromInterned(func.ty)).?; |
| 35557 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, | 35310 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, |
| 35558 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, | 35311 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, |
| 35559 | // so here we can simply skip this case. | 35312 | // so here we can simply skip this case. |
| ... | @@ -36008,7 +35761,7 @@ fn structFieldInits( | ... | @@ -36008,7 +35761,7 @@ fn structFieldInits( |
| 36008 | // In init bodies, the zir index of the struct itself is used | 35761 | // In init bodies, the zir index of the struct itself is used |
| 36009 | // to refer to the current field type. | 35762 | // to refer to the current field type. |
| 36010 | 35763 | ||
| 36011 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_i]); | 35764 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_i]); |
| 36012 | const type_ref = Air.internedToRef(field_ty.toIntern()); | 35765 | const type_ref = Air.internedToRef(field_ty.toIntern()); |
| 36013 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index}); | 35766 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index}); |
| 36014 | sema.inst_map.putAssumeCapacity(zir_index, type_ref); | 35767 | sema.inst_map.putAssumeCapacity(zir_index, type_ref); |
| ... | @@ -36135,7 +35888,7 @@ fn unionFields( | ... | @@ -36135,7 +35888,7 @@ fn unionFields( |
| 36135 | } | 35888 | } |
| 36136 | 35889 | ||
| 36137 | if (fields_len > 0) { | 35890 | if (fields_len > 0) { |
| 36138 | const field_count_val = try pt.intValue(Type.comptime_int, fields_len - 1); | 35891 | const field_count_val = try pt.intValue(.comptime_int, fields_len - 1); |
| 36139 | if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) { | 35892 | if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) { |
| 36140 | const msg = msg: { | 35893 | const msg = msg: { |
| 36141 | const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); | 35894 | const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); |
| ... | @@ -36288,9 +36041,9 @@ fn unionFields( | ... | @@ -36288,9 +36041,9 @@ fn unionFields( |
| 36288 | } | 36041 | } |
| 36289 | 36042 | ||
| 36290 | const field_ty: Type = if (!has_type) | 36043 | const field_ty: Type = if (!has_type) |
| 36291 | Type.void | 36044 | .void |
| 36292 | else if (field_type_ref == .none) | 36045 | else if (field_type_ref == .none) |
| 36293 | Type.noreturn | 36046 | .noreturn |
| 36294 | else | 36047 | else |
| 36295 | try sema.resolveType(&block_scope, type_src, field_type_ref); | 36048 | try sema.resolveType(&block_scope, type_src, field_type_ref); |
| 36296 | 36049 | ||
| ... | @@ -36388,11 +36141,11 @@ fn unionFields( | ... | @@ -36388,11 +36141,11 @@ fn unionFields( |
| 36388 | 36141 | ||
| 36389 | for (tag_info.names.get(ip), 0..) |field_name, field_index| { | 36142 | for (tag_info.names.get(ip), 0..) |field_name, field_index| { |
| 36390 | if (explicit_tags_seen[field_index]) continue; | 36143 | if (explicit_tags_seen[field_index]) continue; |
| 36391 | try sema.addFieldErrNote(Type.fromInterned(tag_ty), field_index, msg, "field '{}' missing, declared here", .{ | 36144 | try sema.addFieldErrNote(.fromInterned(tag_ty), field_index, msg, "field '{}' missing, declared here", .{ |
| 36392 | field_name.fmt(ip), | 36145 | field_name.fmt(ip), |
| 36393 | }); | 36146 | }); |
| 36394 | } | 36147 | } |
| 36395 | try sema.addDeclaredHereNote(msg, Type.fromInterned(tag_ty)); | 36148 | try sema.addDeclaredHereNote(msg, .fromInterned(tag_ty)); |
| 36396 | break :msg msg; | 36149 | break :msg msg; |
| 36397 | }; | 36150 | }; |
| 36398 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 36151 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| ... | @@ -36530,10 +36283,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36530,10 +36283,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36530 | .comptime_int_type, | 36283 | .comptime_int_type, |
| 36531 | .comptime_float_type, | 36284 | .comptime_float_type, |
| 36532 | .enum_literal_type, | 36285 | .enum_literal_type, |
| 36286 | .ptr_usize_type, | ||
| 36287 | .ptr_const_comptime_int_type, | ||
| 36533 | .manyptr_u8_type, | 36288 | .manyptr_u8_type, |
| 36534 | .manyptr_const_u8_type, | 36289 | .manyptr_const_u8_type, |
| 36535 | .manyptr_const_u8_sentinel_0_type, | 36290 | .manyptr_const_u8_sentinel_0_type, |
| 36536 | .single_const_pointer_to_comptime_int_type, | ||
| 36537 | .slice_const_u8_type, | 36291 | .slice_const_u8_type, |
| 36538 | .slice_const_u8_sentinel_0_type, | 36292 | .slice_const_u8_sentinel_0_type, |
| 36539 | .vector_8_i8_type, | 36293 | .vector_8_i8_type, |
| ... | @@ -36595,11 +36349,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36595,11 +36349,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36595 | .empty_tuple_type => Value.empty_tuple, | 36349 | .empty_tuple_type => Value.empty_tuple, |
| 36596 | // values, not types | 36350 | // values, not types |
| 36597 | .undef, | 36351 | .undef, |
| 36352 | .undef_bool, | ||
| 36353 | .undef_usize, | ||
| 36354 | .undef_u1, | ||
| 36598 | .zero, | 36355 | .zero, |
| 36599 | .zero_usize, | 36356 | .zero_usize, |
| 36357 | .zero_u1, | ||
| 36600 | .zero_u8, | 36358 | .zero_u8, |
| 36601 | .one, | 36359 | .one, |
| 36602 | .one_usize, | 36360 | .one_usize, |
| 36361 | .one_u1, | ||
| 36603 | .one_u8, | 36362 | .one_u8, |
| 36604 | .four_u8, | 36363 | .four_u8, |
| 36605 | .negative_one, | 36364 | .negative_one, |
| ... | @@ -36705,7 +36464,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36705,7 +36464,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36705 | .storage = .{ .elems = &.{} }, | 36464 | .storage = .{ .elems = &.{} }, |
| 36706 | } })); | 36465 | } })); |
| 36707 | 36466 | ||
| 36708 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| { | 36467 | if (try sema.typeHasOnePossibleValue(.fromInterned(seq_type.child))) |opv| { |
| 36709 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 36468 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36710 | .ty = ty.toIntern(), | 36469 | .ty = ty.toIntern(), |
| 36711 | .storage = .{ .repeated_elem = opv.toIntern() }, | 36470 | .storage = .{ .repeated_elem = opv.toIntern() }, |
| ... | @@ -36740,7 +36499,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36740,7 +36499,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36740 | field_val.* = struct_type.field_inits.get(ip)[i]; | 36499 | field_val.* = struct_type.field_inits.get(ip)[i]; |
| 36741 | continue; | 36500 | continue; |
| 36742 | } | 36501 | } |
| 36743 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 36502 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); |
| 36744 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| { | 36503 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| { |
| 36745 | field_val.* = field_opv.toIntern(); | 36504 | field_val.* = field_opv.toIntern(); |
| 36746 | } else return null; | 36505 | } else return null; |
| ... | @@ -36773,13 +36532,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36773,13 +36532,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36773 | try ty.resolveLayout(pt); | 36532 | try ty.resolveLayout(pt); |
| 36774 | 36533 | ||
| 36775 | const union_obj = ip.loadUnionType(ty.toIntern()); | 36534 | const union_obj = ip.loadUnionType(ty.toIntern()); |
| 36776 | const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse | 36535 | const tag_val = (try sema.typeHasOnePossibleValue(.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse |
| 36777 | return null; | 36536 | return null; |
| 36778 | if (union_obj.field_types.len == 0) { | 36537 | if (union_obj.field_types.len == 0) { |
| 36779 | const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() }); | 36538 | const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() }); |
| 36780 | return Value.fromInterned(only); | 36539 | return Value.fromInterned(only); |
| 36781 | } | 36540 | } |
| 36782 | const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 36541 | const only_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[0]); |
| 36783 | const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse | 36542 | const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse |
| 36784 | return null; | 36543 | return null; |
| 36785 | const only = try pt.internUnion(.{ | 36544 | const only = try pt.internUnion(.{ |
| ... | @@ -36796,7 +36555,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36796,7 +36555,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36796 | .nonexhaustive => { | 36555 | .nonexhaustive => { |
| 36797 | if (enum_type.tag_ty == .comptime_int_type) return null; | 36556 | if (enum_type.tag_ty == .comptime_int_type) return null; |
| 36798 | 36557 | ||
| 36799 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| { | 36558 | if (try sema.typeHasOnePossibleValue(.fromInterned(enum_type.tag_ty))) |int_opv| { |
| 36800 | const only = try pt.intern(.{ .enum_tag = .{ | 36559 | const only = try pt.intern(.{ .enum_tag = .{ |
| 36801 | .ty = ty.toIntern(), | 36560 | .ty = ty.toIntern(), |
| 36802 | .int = int_opv.toIntern(), | 36561 | .int = int_opv.toIntern(), |
| ... | @@ -36814,7 +36573,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36814,7 +36573,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36814 | 1 => try pt.intern(.{ .enum_tag = .{ | 36573 | 1 => try pt.intern(.{ .enum_tag = .{ |
| 36815 | .ty = ty.toIntern(), | 36574 | .ty = ty.toIntern(), |
| 36816 | .int = if (enum_type.values.len == 0) | 36575 | .int = if (enum_type.values.len == 0) |
| 36817 | (try pt.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern() | 36576 | (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern() |
| 36818 | else | 36577 | else |
| 36819 | try ip.getCoercedInts( | 36578 | try ip.getCoercedInts( |
| 36820 | zcu.gpa, | 36579 | zcu.gpa, |
| ... | @@ -37041,7 +36800,7 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { | ... | @@ -37041,7 +36800,7 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 37041 | if (ptr_type.flags.is_allowzero) return null; | 36800 | if (ptr_type.flags.is_allowzero) return null; |
| 37042 | 36801 | ||
| 37043 | // optionals of zero sized types behave like bools, not pointers | 36802 | // optionals of zero sized types behave like bools, not pointers |
| 37044 | const payload_ty = Type.fromInterned(opt_child); | 36803 | const payload_ty: Type = .fromInterned(opt_child); |
| 37045 | if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) { | 36804 | if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) { |
| 37046 | return null; | 36805 | return null; |
| 37047 | } | 36806 | } |
| ... | @@ -37175,7 +36934,7 @@ fn intFromFloatScalar( | ... | @@ -37175,7 +36934,7 @@ fn intFromFloatScalar( |
| 37175 | var big_int = try float128IntPartToBigInt(sema.arena, float); | 36934 | var big_int = try float128IntPartToBigInt(sema.arena, float); |
| 37176 | defer big_int.deinit(); | 36935 | defer big_int.deinit(); |
| 37177 | 36936 | ||
| 37178 | const cti_result = try pt.intValue_big(Type.comptime_int, big_int.toConst()); | 36937 | const cti_result = try pt.intValue_big(.comptime_int, big_int.toConst()); |
| 37179 | 36938 | ||
| 37180 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { | 36939 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { |
| 37181 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ | 36940 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ |
| ... | @@ -37278,8 +37037,8 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { | ... | @@ -37278,8 +37037,8 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { |
| 37278 | assert(enum_type.tag_mode != .nonexhaustive); | 37037 | assert(enum_type.tag_mode != .nonexhaustive); |
| 37279 | // The `tagValueIndex` function call below relies on the type being the integer tag type. | 37038 | // The `tagValueIndex` function call below relies on the type being the integer tag type. |
| 37280 | // `getCoerced` assumes the value will fit the new type. | 37039 | // `getCoerced` assumes the value will fit the new type. |
| 37281 | if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false; | 37040 | if (!(try sema.intFitsInType(int, .fromInterned(enum_type.tag_ty), null))) return false; |
| 37282 | const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty)); | 37041 | const int_coerced = try pt.getCoerced(int, .fromInterned(enum_type.tag_ty)); |
| 37283 | 37042 | ||
| 37284 | return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null; | 37043 | return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null; |
| 37285 | } | 37044 | } |
| ... | @@ -37359,7 +37118,7 @@ fn compareVector( | ... | @@ -37359,7 +37118,7 @@ fn compareVector( |
| 37359 | const lhs_elem = try lhs.elemValue(pt, i); | 37118 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37360 | const rhs_elem = try rhs.elemValue(pt, i); | 37119 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37361 | if (lhs_elem.isUndef(zcu) or rhs_elem.isUndef(zcu)) { | 37120 | if (lhs_elem.isUndef(zcu) or rhs_elem.isUndef(zcu)) { |
| 37362 | scalar.* = try pt.intern(.{ .undef = .bool_type }); | 37121 | scalar.* = .undef_bool; |
| 37363 | } else { | 37122 | } else { |
| 37364 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(zcu)); | 37123 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(zcu)); |
| 37365 | scalar.* = Value.makeBool(res_bool).toIntern(); | 37124 | scalar.* = Value.makeBool(res_bool).toIntern(); |
| ... | @@ -37826,7 +37585,7 @@ pub fn resolveDeclaredEnum( | ... | @@ -37826,7 +37585,7 @@ pub fn resolveDeclaredEnum( |
| 37826 | .owner = .wrap(.{ .type = wip_ty.index }), | 37585 | .owner = .wrap(.{ .type = wip_ty.index }), |
| 37827 | .func_index = .none, | 37586 | .func_index = .none, |
| 37828 | .func_is_naked = false, | 37587 | .func_is_naked = false, |
| 37829 | .fn_ret_ty = Type.void, | 37588 | .fn_ret_ty = .void, |
| 37830 | .fn_ret_ty_ies = null, | 37589 | .fn_ret_ty_ies = null, |
| 37831 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 37590 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 37832 | }; | 37591 | }; |
| ... | @@ -37999,7 +37758,7 @@ fn resolveDeclaredEnumInner( | ... | @@ -37999,7 +37758,7 @@ fn resolveDeclaredEnumInner( |
| 37999 | break :overflow false; | 37758 | break :overflow false; |
| 38000 | } else overflow: { | 37759 | } else overflow: { |
| 38001 | assert(wip_ty.nextField(ip, field_name, .none) == null); | 37760 | assert(wip_ty.nextField(ip, field_name, .none) == null); |
| 38002 | last_tag_val = try pt.intValue(Type.comptime_int, field_i); | 37761 | last_tag_val = try pt.intValue(.comptime_int, field_i); |
| 38003 | if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true; | 37762 | if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true; |
| 38004 | last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty); | 37763 | last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty); |
| 38005 | break :overflow false; | 37764 | break :overflow false; |
| ... | @@ -38222,8 +37981,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ | ... | @@ -38222,8 +37981,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 38222 | .@"panic.castToNull", | 37981 | .@"panic.castToNull", |
| 38223 | .@"panic.incorrectAlignment", | 37982 | .@"panic.incorrectAlignment", |
| 38224 | .@"panic.invalidErrorCode", | 37983 | .@"panic.invalidErrorCode", |
| 38225 | .@"panic.castTruncatedData", | 37984 | .@"panic.integerOutOfBounds", |
| 38226 | .@"panic.negativeToUnsigned", | ||
| 38227 | .@"panic.integerOverflow", | 37985 | .@"panic.integerOverflow", |
| 38228 | .@"panic.shlOverflow", | 37986 | .@"panic.shlOverflow", |
| 38229 | .@"panic.shrOverflow", | 37987 | .@"panic.shrOverflow", |
src/Sema/arith.zig+6-6| ... | @@ -168,7 +168,7 @@ fn addWithOverflowScalar( | ... | @@ -168,7 +168,7 @@ fn addWithOverflowScalar( |
| 168 | else => unreachable, | 168 | else => unreachable, |
| 169 | } | 169 | } |
| 170 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ | 170 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ |
| 171 | .overflow_bit = try pt.undefValue(.u1), | 171 | .overflow_bit = .undef_u1, |
| 172 | .wrapped_result = try pt.undefValue(ty), | 172 | .wrapped_result = try pt.undefValue(ty), |
| 173 | }; | 173 | }; |
| 174 | return intAddWithOverflow(sema, lhs, rhs, ty); | 174 | return intAddWithOverflow(sema, lhs, rhs, ty); |
| ... | @@ -229,7 +229,7 @@ fn subWithOverflowScalar( | ... | @@ -229,7 +229,7 @@ fn subWithOverflowScalar( |
| 229 | else => unreachable, | 229 | else => unreachable, |
| 230 | } | 230 | } |
| 231 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ | 231 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ |
| 232 | .overflow_bit = try pt.undefValue(.u1), | 232 | .overflow_bit = .undef_u1, |
| 233 | .wrapped_result = try pt.undefValue(ty), | 233 | .wrapped_result = try pt.undefValue(ty), |
| 234 | }; | 234 | }; |
| 235 | return intSubWithOverflow(sema, lhs, rhs, ty); | 235 | return intSubWithOverflow(sema, lhs, rhs, ty); |
| ... | @@ -290,7 +290,7 @@ fn mulWithOverflowScalar( | ... | @@ -290,7 +290,7 @@ fn mulWithOverflowScalar( |
| 290 | else => unreachable, | 290 | else => unreachable, |
| 291 | } | 291 | } |
| 292 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ | 292 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{ |
| 293 | .overflow_bit = try pt.undefValue(.u1), | 293 | .overflow_bit = .undef_u1, |
| 294 | .wrapped_result = try pt.undefValue(ty), | 294 | .wrapped_result = try pt.undefValue(ty), |
| 295 | }; | 295 | }; |
| 296 | return intMulWithOverflow(sema, lhs, rhs, ty); | 296 | return intMulWithOverflow(sema, lhs, rhs, ty); |
| ... | @@ -1043,7 +1043,7 @@ fn comptimeIntAdd(sema: *Sema, lhs: Value, rhs: Value) !Value { | ... | @@ -1043,7 +1043,7 @@ fn comptimeIntAdd(sema: *Sema, lhs: Value, rhs: Value) !Value { |
| 1043 | fn intAddWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { | 1043 | fn intAddWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { |
| 1044 | switch (ty.toIntern()) { | 1044 | switch (ty.toIntern()) { |
| 1045 | .comptime_int_type => return .{ | 1045 | .comptime_int_type => return .{ |
| 1046 | .overflow_bit = try sema.pt.intValue(.u1, 0), | 1046 | .overflow_bit = .zero_u1, |
| 1047 | .wrapped_result = try comptimeIntAdd(sema, lhs, rhs), | 1047 | .wrapped_result = try comptimeIntAdd(sema, lhs, rhs), |
| 1048 | }, | 1048 | }, |
| 1049 | else => return intAddWithOverflowInner(sema, lhs, rhs, ty), | 1049 | else => return intAddWithOverflowInner(sema, lhs, rhs, ty), |
| ... | @@ -1125,7 +1125,7 @@ fn comptimeIntSub(sema: *Sema, lhs: Value, rhs: Value) !Value { | ... | @@ -1125,7 +1125,7 @@ fn comptimeIntSub(sema: *Sema, lhs: Value, rhs: Value) !Value { |
| 1125 | fn intSubWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { | 1125 | fn intSubWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { |
| 1126 | switch (ty.toIntern()) { | 1126 | switch (ty.toIntern()) { |
| 1127 | .comptime_int_type => return .{ | 1127 | .comptime_int_type => return .{ |
| 1128 | .overflow_bit = try sema.pt.intValue(.u1, 0), | 1128 | .overflow_bit = .zero_u1, |
| 1129 | .wrapped_result = try comptimeIntSub(sema, lhs, rhs), | 1129 | .wrapped_result = try comptimeIntSub(sema, lhs, rhs), |
| 1130 | }, | 1130 | }, |
| 1131 | else => return intSubWithOverflowInner(sema, lhs, rhs, ty), | 1131 | else => return intSubWithOverflowInner(sema, lhs, rhs, ty), |
| ... | @@ -1211,7 +1211,7 @@ fn comptimeIntMul(sema: *Sema, lhs: Value, rhs: Value) !Value { | ... | @@ -1211,7 +1211,7 @@ fn comptimeIntMul(sema: *Sema, lhs: Value, rhs: Value) !Value { |
| 1211 | fn intMulWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { | 1211 | fn intMulWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult { |
| 1212 | switch (ty.toIntern()) { | 1212 | switch (ty.toIntern()) { |
| 1213 | .comptime_int_type => return .{ | 1213 | .comptime_int_type => return .{ |
| 1214 | .overflow_bit = try sema.pt.intValue(.u1, 0), | 1214 | .overflow_bit = .zero_u1, |
| 1215 | .wrapped_result = try comptimeIntMul(sema, lhs, rhs), | 1215 | .wrapped_result = try comptimeIntMul(sema, lhs, rhs), |
| 1216 | }, | 1216 | }, |
| 1217 | else => return intMulWithOverflowInner(sema, lhs, rhs, ty), | 1217 | else => return intMulWithOverflowInner(sema, lhs, rhs, ty), |
src/Type.zig+7-6| ... | @@ -2641,10 +2641,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { | ... | @@ -2641,10 +2641,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2641 | if (enum_type.values.len == 0) { | 2641 | if (enum_type.values.len == 0) { |
| 2642 | const only = try pt.intern(.{ .enum_tag = .{ | 2642 | const only = try pt.intern(.{ .enum_tag = .{ |
| 2643 | .ty = ty.toIntern(), | 2643 | .ty = ty.toIntern(), |
| 2644 | .int = try pt.intern(.{ .int = .{ | 2644 | .int = (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern(), |
| 2645 | .ty = enum_type.tag_ty, | ||
| 2646 | .storage = .{ .u64 = 0 }, | ||
| 2647 | } }), | ||
| 2648 | } }); | 2645 | } }); |
| 2649 | return Value.fromInterned(only); | 2646 | return Value.fromInterned(only); |
| 2650 | } else { | 2647 | } else { |
| ... | @@ -3676,10 +3673,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { | ... | @@ -3676,10 +3673,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3676 | .null_type, | 3673 | .null_type, |
| 3677 | .undefined_type, | 3674 | .undefined_type, |
| 3678 | .enum_literal_type, | 3675 | .enum_literal_type, |
| 3676 | .ptr_usize_type, | ||
| 3677 | .ptr_const_comptime_int_type, | ||
| 3679 | .manyptr_u8_type, | 3678 | .manyptr_u8_type, |
| 3680 | .manyptr_const_u8_type, | 3679 | .manyptr_const_u8_type, |
| 3681 | .manyptr_const_u8_sentinel_0_type, | 3680 | .manyptr_const_u8_sentinel_0_type, |
| 3682 | .single_const_pointer_to_comptime_int_type, | ||
| 3683 | .slice_const_u8_type, | 3681 | .slice_const_u8_type, |
| 3684 | .slice_const_u8_sentinel_0_type, | 3682 | .slice_const_u8_sentinel_0_type, |
| 3685 | .optional_noreturn_type, | 3683 | .optional_noreturn_type, |
| ... | @@ -3691,9 +3689,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { | ... | @@ -3691,9 +3689,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3691 | .undef => unreachable, | 3689 | .undef => unreachable, |
| 3692 | .zero => unreachable, | 3690 | .zero => unreachable, |
| 3693 | .zero_usize => unreachable, | 3691 | .zero_usize => unreachable, |
| 3692 | .zero_u1 => unreachable, | ||
| 3694 | .zero_u8 => unreachable, | 3693 | .zero_u8 => unreachable, |
| 3695 | .one => unreachable, | 3694 | .one => unreachable, |
| 3696 | .one_usize => unreachable, | 3695 | .one_usize => unreachable, |
| 3696 | .one_u1 => unreachable, | ||
| 3697 | .one_u8 => unreachable, | 3697 | .one_u8 => unreachable, |
| 3698 | .four_u8 => unreachable, | 3698 | .four_u8 => unreachable, |
| 3699 | .negative_one => unreachable, | 3699 | .negative_one => unreachable, |
| ... | @@ -4100,10 +4100,11 @@ pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type }; | ... | @@ -4100,10 +4100,11 @@ pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type }; |
| 4100 | pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type }; | 4100 | pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type }; |
| 4101 | pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type }; | 4101 | pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type }; |
| 4102 | 4102 | ||
| 4103 | pub const ptr_usize: Type = .{ .ip_index = .ptr_usize_type }; | ||
| 4104 | pub const ptr_const_comptime_int: Type = .{ .ip_index = .ptr_const_comptime_int_type }; | ||
| 4103 | pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type }; | 4105 | pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type }; |
| 4104 | pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type }; | 4106 | pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type }; |
| 4105 | pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type }; | 4107 | pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type }; |
| 4106 | pub const single_const_pointer_to_comptime_int: Type = .{ .ip_index = .single_const_pointer_to_comptime_int_type }; | ||
| 4107 | pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type }; | 4108 | pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type }; |
| 4108 | pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type }; | 4109 | pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type }; |
| 4109 | 4110 |
src/Value.zig+12-6| ... | @@ -2895,19 +2895,25 @@ pub fn intValueBounds(val: Value, pt: Zcu.PerThread) !?[2]Value { | ... | @@ -2895,19 +2895,25 @@ pub fn intValueBounds(val: Value, pt: Zcu.PerThread) !?[2]Value { |
| 2895 | 2895 | ||
| 2896 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; | 2896 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 2897 | 2897 | ||
| 2898 | pub const undef: Value = .{ .ip_index = .undef }; | ||
| 2899 | pub const undef_bool: Value = .{ .ip_index = .undef_bool }; | ||
| 2900 | pub const undef_usize: Value = .{ .ip_index = .undef_usize }; | ||
| 2901 | pub const undef_u1: Value = .{ .ip_index = .undef_u1 }; | ||
| 2902 | pub const zero_comptime_int: Value = .{ .ip_index = .zero }; | ||
| 2898 | pub const zero_usize: Value = .{ .ip_index = .zero_usize }; | 2903 | pub const zero_usize: Value = .{ .ip_index = .zero_usize }; |
| 2904 | pub const zero_u1: Value = .{ .ip_index = .zero_u1 }; | ||
| 2899 | pub const zero_u8: Value = .{ .ip_index = .zero_u8 }; | 2905 | pub const zero_u8: Value = .{ .ip_index = .zero_u8 }; |
| 2900 | pub const zero_comptime_int: Value = .{ .ip_index = .zero }; | ||
| 2901 | pub const one_comptime_int: Value = .{ .ip_index = .one }; | 2906 | pub const one_comptime_int: Value = .{ .ip_index = .one }; |
| 2907 | pub const one_usize: Value = .{ .ip_index = .one_usize }; | ||
| 2908 | pub const one_u1: Value = .{ .ip_index = .one_u1 }; | ||
| 2909 | pub const one_u8: Value = .{ .ip_index = .one_u8 }; | ||
| 2910 | pub const four_u8: Value = .{ .ip_index = .four_u8 }; | ||
| 2902 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one }; | 2911 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one }; |
| 2903 | pub const undef: Value = .{ .ip_index = .undef }; | ||
| 2904 | pub const @"void": Value = .{ .ip_index = .void_value }; | 2912 | pub const @"void": Value = .{ .ip_index = .void_value }; |
| 2913 | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value }; | ||
| 2905 | pub const @"null": Value = .{ .ip_index = .null_value }; | 2914 | pub const @"null": Value = .{ .ip_index = .null_value }; |
| 2906 | pub const @"false": Value = .{ .ip_index = .bool_false }; | ||
| 2907 | pub const @"true": Value = .{ .ip_index = .bool_true }; | 2915 | pub const @"true": Value = .{ .ip_index = .bool_true }; |
| 2908 | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value }; | 2916 | pub const @"false": Value = .{ .ip_index = .bool_false }; |
| 2909 | |||
| 2910 | pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type }; | ||
| 2911 | pub const empty_tuple: Value = .{ .ip_index = .empty_tuple }; | 2917 | pub const empty_tuple: Value = .{ .ip_index = .empty_tuple }; |
| 2912 | 2918 | ||
| 2913 | pub fn makeBool(x: bool) Value { | 2919 | pub fn makeBool(x: bool) Value { |
src/Zcu.zig+4-26| ... | @@ -441,8 +441,7 @@ pub const BuiltinDecl = enum { | ... | @@ -441,8 +441,7 @@ pub const BuiltinDecl = enum { |
| 441 | @"panic.castToNull", | 441 | @"panic.castToNull", |
| 442 | @"panic.incorrectAlignment", | 442 | @"panic.incorrectAlignment", |
| 443 | @"panic.invalidErrorCode", | 443 | @"panic.invalidErrorCode", |
| 444 | @"panic.castTruncatedData", | 444 | @"panic.integerOutOfBounds", |
| 445 | @"panic.negativeToUnsigned", | ||
| 446 | @"panic.integerOverflow", | 445 | @"panic.integerOverflow", |
| 447 | @"panic.shlOverflow", | 446 | @"panic.shlOverflow", |
| 448 | @"panic.shrOverflow", | 447 | @"panic.shrOverflow", |
| ... | @@ -518,8 +517,7 @@ pub const BuiltinDecl = enum { | ... | @@ -518,8 +517,7 @@ pub const BuiltinDecl = enum { |
| 518 | .@"panic.castToNull", | 517 | .@"panic.castToNull", |
| 519 | .@"panic.incorrectAlignment", | 518 | .@"panic.incorrectAlignment", |
| 520 | .@"panic.invalidErrorCode", | 519 | .@"panic.invalidErrorCode", |
| 521 | .@"panic.castTruncatedData", | 520 | .@"panic.integerOutOfBounds", |
| 522 | .@"panic.negativeToUnsigned", | ||
| 523 | .@"panic.integerOverflow", | 521 | .@"panic.integerOverflow", |
| 524 | .@"panic.shlOverflow", | 522 | .@"panic.shlOverflow", |
| 525 | .@"panic.shrOverflow", | 523 | .@"panic.shrOverflow", |
| ... | @@ -585,8 +583,7 @@ pub const SimplePanicId = enum { | ... | @@ -585,8 +583,7 @@ pub const SimplePanicId = enum { |
| 585 | cast_to_null, | 583 | cast_to_null, |
| 586 | incorrect_alignment, | 584 | incorrect_alignment, |
| 587 | invalid_error_code, | 585 | invalid_error_code, |
| 588 | cast_truncated_data, | 586 | integer_out_of_bounds, |
| 589 | negative_to_unsigned, | ||
| 590 | integer_overflow, | 587 | integer_overflow, |
| 591 | shl_overflow, | 588 | shl_overflow, |
| 592 | shr_overflow, | 589 | shr_overflow, |
| ... | @@ -609,8 +606,7 @@ pub const SimplePanicId = enum { | ... | @@ -609,8 +606,7 @@ pub const SimplePanicId = enum { |
| 609 | .cast_to_null => .@"panic.castToNull", | 606 | .cast_to_null => .@"panic.castToNull", |
| 610 | .incorrect_alignment => .@"panic.incorrectAlignment", | 607 | .incorrect_alignment => .@"panic.incorrectAlignment", |
| 611 | .invalid_error_code => .@"panic.invalidErrorCode", | 608 | .invalid_error_code => .@"panic.invalidErrorCode", |
| 612 | .cast_truncated_data => .@"panic.castTruncatedData", | 609 | .integer_out_of_bounds => .@"panic.integerOutOfBounds", |
| 613 | .negative_to_unsigned => .@"panic.negativeToUnsigned", | ||
| 614 | .integer_overflow => .@"panic.integerOverflow", | 610 | .integer_overflow => .@"panic.integerOverflow", |
| 615 | .shl_overflow => .@"panic.shlOverflow", | 611 | .shl_overflow => .@"panic.shlOverflow", |
| 616 | .shr_overflow => .@"panic.shrOverflow", | 612 | .shr_overflow => .@"panic.shrOverflow", |
| ... | @@ -3829,26 +3825,8 @@ pub const Feature = enum { | ... | @@ -3829,26 +3825,8 @@ pub const Feature = enum { |
| 3829 | is_named_enum_value, | 3825 | is_named_enum_value, |
| 3830 | error_set_has_value, | 3826 | error_set_has_value, |
| 3831 | field_reordering, | 3827 | field_reordering, |
| 3832 | /// When this feature is supported, the backend supports the following AIR instructions: | ||
| 3833 | /// * `Air.Inst.Tag.add_safe` | ||
| 3834 | /// * `Air.Inst.Tag.sub_safe` | ||
| 3835 | /// * `Air.Inst.Tag.mul_safe` | ||
| 3836 | /// * `Air.Inst.Tag.intcast_safe` | ||
| 3837 | /// The motivation for this feature is that it makes AIR smaller, and makes it easier | ||
| 3838 | /// to generate better machine code in the backends. All backends should migrate to | ||
| 3839 | /// enabling this feature. | ||
| 3840 | safety_checked_instructions, | ||
| 3841 | /// If the backend supports running from another thread. | 3828 | /// If the backend supports running from another thread. |
| 3842 | separate_thread, | 3829 | separate_thread, |
| 3843 | /// If the backend supports the following AIR instructions with vector types: | ||
| 3844 | /// * `Air.Inst.Tag.bit_and` | ||
| 3845 | /// * `Air.Inst.Tag.bit_or` | ||
| 3846 | /// * `Air.Inst.Tag.bitcast` | ||
| 3847 | /// * `Air.Inst.Tag.float_from_int` | ||
| 3848 | /// * `Air.Inst.Tag.fptrunc` | ||
| 3849 | /// * `Air.Inst.Tag.int_from_float` | ||
| 3850 | /// If not supported, Sema will scalarize the operation. | ||
| 3851 | all_vector_instructions, | ||
| 3852 | }; | 3830 | }; |
| 3853 | 3831 | ||
| 3854 | pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool { | 3832 | pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool { |
src/Zcu/PerThread.zig+21-4| ... | @@ -1741,10 +1741,11 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A | ... | @@ -1741,10 +1741,11 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A |
| 1741 | return; | 1741 | return; |
| 1742 | } | 1742 | } |
| 1743 | 1743 | ||
| 1744 | const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm); | 1744 | legalize: { |
| 1745 | try air.legalize(backend, zcu); | 1745 | try air.legalize(pt, @import("../codegen.zig").legalizeFeatures(pt, nav_index) orelse break :legalize); |
| 1746 | } | ||
| 1746 | 1747 | ||
| 1747 | var liveness = try Air.Liveness.analyze(gpa, air.*, ip); | 1748 | var liveness = try Air.Liveness.analyze(zcu, air.*, ip); |
| 1748 | defer liveness.deinit(gpa); | 1749 | defer liveness.deinit(gpa); |
| 1749 | 1750 | ||
| 1750 | if (build_options.enable_debug_extensions and comp.verbose_air) { | 1751 | if (build_options.enable_debug_extensions and comp.verbose_air) { |
| ... | @@ -1756,6 +1757,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A | ... | @@ -1756,6 +1757,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A |
| 1756 | if (std.debug.runtime_safety) { | 1757 | if (std.debug.runtime_safety) { |
| 1757 | var verify: Air.Liveness.Verify = .{ | 1758 | var verify: Air.Liveness.Verify = .{ |
| 1758 | .gpa = gpa, | 1759 | .gpa = gpa, |
| 1760 | .zcu = zcu, | ||
| 1759 | .air = air.*, | 1761 | .air = air.*, |
| 1760 | .liveness = liveness, | 1762 | .liveness = liveness, |
| 1761 | .intern_pool = ip, | 1763 | .intern_pool = ip, |
| ... | @@ -3022,7 +3024,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE | ... | @@ -3022,7 +3024,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE |
| 3022 | // is unused so it just has to be a no-op. | 3024 | // is unused so it just has to be a no-op. |
| 3023 | sema.air_instructions.set(@intFromEnum(ptr_inst), .{ | 3025 | sema.air_instructions.set(@intFromEnum(ptr_inst), .{ |
| 3024 | .tag = .alloc, | 3026 | .tag = .alloc, |
| 3025 | .data = .{ .ty = Type.single_const_pointer_to_comptime_int }, | 3027 | .data = .{ .ty = .ptr_const_comptime_int }, |
| 3026 | }); | 3028 | }); |
| 3027 | } | 3029 | } |
| 3028 | 3030 | ||
| ... | @@ -3843,6 +3845,21 @@ pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value { | ... | @@ -3843,6 +3845,21 @@ pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value { |
| 3843 | } })); | 3845 | } })); |
| 3844 | } | 3846 | } |
| 3845 | 3847 | ||
| 3848 | /// `ty` is an integer or a vector of integers. | ||
| 3849 | pub fn overflowArithmeticTupleType(pt: Zcu.PerThread, ty: Type) !Type { | ||
| 3850 | const zcu = pt.zcu; | ||
| 3851 | const ip = &zcu.intern_pool; | ||
| 3852 | const ov_ty: Type = if (ty.zigTypeTag(zcu) == .vector) try pt.vectorType(.{ | ||
| 3853 | .len = ty.vectorLen(zcu), | ||
| 3854 | .child = .u1_type, | ||
| 3855 | }) else .u1; | ||
| 3856 | const tuple_ty = try ip.getTupleType(zcu.gpa, pt.tid, .{ | ||
| 3857 | .types = &.{ ty.toIntern(), ov_ty.toIntern() }, | ||
| 3858 | .values = &.{ .none, .none }, | ||
| 3859 | }); | ||
| 3860 | return .fromInterned(tuple_ty); | ||
| 3861 | } | ||
| 3862 | |||
| 3846 | pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type { | 3863 | pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type { |
| 3847 | return pt.intType(.unsigned, Type.smallestUnsignedBits(max)); | 3864 | return pt.intType(.unsigned, Type.smallestUnsignedBits(max)); |
| 3848 | } | 3865 | } |
src/arch/aarch64/CodeGen.zig+33-12| ... | @@ -40,6 +40,10 @@ const gp = abi.RegisterClass.gp; | ... | @@ -40,6 +40,10 @@ const gp = abi.RegisterClass.gp; |
| 40 | 40 | ||
| 41 | const InnerError = CodeGenError || error{OutOfRegisters}; | 41 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 42 | 42 | ||
| 43 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 44 | return null; | ||
| 45 | } | ||
| 46 | |||
| 43 | gpa: Allocator, | 47 | gpa: Allocator, |
| 44 | pt: Zcu.PerThread, | 48 | pt: Zcu.PerThread, |
| 45 | air: Air, | 49 | air: Air, |
| ... | @@ -774,7 +778,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -774,7 +778,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 774 | .error_name => try self.airErrorName(inst), | 778 | .error_name => try self.airErrorName(inst), |
| 775 | .splat => try self.airSplat(inst), | 779 | .splat => try self.airSplat(inst), |
| 776 | .select => try self.airSelect(inst), | 780 | .select => try self.airSelect(inst), |
| 777 | .shuffle => try self.airShuffle(inst), | 781 | .shuffle_one => try self.airShuffleOne(inst), |
| 782 | .shuffle_two => try self.airShuffleTwo(inst), | ||
| 778 | .reduce => try self.airReduce(inst), | 783 | .reduce => try self.airReduce(inst), |
| 779 | .aggregate_init => try self.airAggregateInit(inst), | 784 | .aggregate_init => try self.airAggregateInit(inst), |
| 780 | .union_init => try self.airUnionInit(inst), | 785 | .union_init => try self.airUnionInit(inst), |
| ... | @@ -2261,12 +2266,13 @@ fn shiftExact( | ... | @@ -2261,12 +2266,13 @@ fn shiftExact( |
| 2261 | rhs_ty: Type, | 2266 | rhs_ty: Type, |
| 2262 | maybe_inst: ?Air.Inst.Index, | 2267 | maybe_inst: ?Air.Inst.Index, |
| 2263 | ) InnerError!MCValue { | 2268 | ) InnerError!MCValue { |
| 2264 | _ = rhs_ty; | ||
| 2265 | |||
| 2266 | const pt = self.pt; | 2269 | const pt = self.pt; |
| 2267 | const zcu = pt.zcu; | 2270 | const zcu = pt.zcu; |
| 2268 | switch (lhs_ty.zigTypeTag(zcu)) { | 2271 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 2269 | .vector => return self.fail("TODO binary operations on vectors", .{}), | 2272 | .vector => if (!rhs_ty.isVector(zcu)) |
| 2273 | return self.fail("TODO vector shift with scalar rhs", .{}) | ||
| 2274 | else | ||
| 2275 | return self.fail("TODO binary operations on vectors", .{}), | ||
| 2270 | .int => { | 2276 | .int => { |
| 2271 | const int_info = lhs_ty.intInfo(zcu); | 2277 | const int_info = lhs_ty.intInfo(zcu); |
| 2272 | if (int_info.bits <= 64) { | 2278 | if (int_info.bits <= 64) { |
| ... | @@ -2317,7 +2323,10 @@ fn shiftNormal( | ... | @@ -2317,7 +2323,10 @@ fn shiftNormal( |
| 2317 | const pt = self.pt; | 2323 | const pt = self.pt; |
| 2318 | const zcu = pt.zcu; | 2324 | const zcu = pt.zcu; |
| 2319 | switch (lhs_ty.zigTypeTag(zcu)) { | 2325 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 2320 | .vector => return self.fail("TODO binary operations on vectors", .{}), | 2326 | .vector => if (!rhs_ty.isVector(zcu)) |
| 2327 | return self.fail("TODO vector shift with scalar rhs", .{}) | ||
| 2328 | else | ||
| 2329 | return self.fail("TODO binary operations on vectors", .{}), | ||
| 2321 | .int => { | 2330 | .int => { |
| 2322 | const int_info = lhs_ty.intInfo(zcu); | 2331 | const int_info = lhs_ty.intInfo(zcu); |
| 2323 | if (int_info.bits <= 64) { | 2332 | if (int_info.bits <= 64) { |
| ... | @@ -2874,7 +2883,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2874,7 +2883,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2874 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu))); | 2883 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu))); |
| 2875 | 2884 | ||
| 2876 | switch (lhs_ty.zigTypeTag(zcu)) { | 2885 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 2877 | .vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), | 2886 | .vector => if (!rhs_ty.isVector(zcu)) |
| 2887 | return self.fail("TODO implement vector shl_with_overflow with scalar rhs", .{}) | ||
| 2888 | else | ||
| 2889 | return self.fail("TODO implement shl_with_overflow for vectors", .{}), | ||
| 2878 | .int => { | 2890 | .int => { |
| 2879 | const int_info = lhs_ty.intInfo(zcu); | 2891 | const int_info = lhs_ty.intInfo(zcu); |
| 2880 | if (int_info.bits <= 64) { | 2892 | if (int_info.bits <= 64) { |
| ... | @@ -2993,8 +3005,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2993,8 +3005,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2993 | } | 3005 | } |
| 2994 | 3006 | ||
| 2995 | fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { | 3007 | fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3008 | const zcu = self.pt.zcu; | ||
| 2996 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3009 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2997 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | 3010 | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 3011 | .dead | ||
| 3012 | else if (self.typeOf(bin_op.lhs).isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 3013 | return self.fail("TODO implement vector shl_sat with scalar rhs for {}", .{self.target.cpu.arch}) | ||
| 3014 | else | ||
| 3015 | return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | ||
| 2998 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 3016 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2999 | } | 3017 | } |
| 3000 | 3018 | ||
| ... | @@ -6032,11 +6050,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6032,11 +6050,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 6032 | return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); | 6050 | return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); |
| 6033 | } | 6051 | } |
| 6034 | 6052 | ||
| 6035 | fn airShuffle(self: *Self, inst: Air.Inst.Index) InnerError!void { | 6053 | fn airShuffleOne(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 6036 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6054 | _ = inst; |
| 6037 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 6055 | return self.fail("TODO implement airShuffleOne for {}", .{self.target.cpu.arch}); |
| 6038 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for {}", .{self.target.cpu.arch}); | 6056 | } |
| 6039 | return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); | 6057 | |
| 6058 | fn airShuffleTwo(self: *Self, inst: Air.Inst.Index) InnerError!void { | ||
| 6059 | _ = inst; | ||
| 6060 | return self.fail("TODO implement airShuffleTwo for {}", .{self.target.cpu.arch}); | ||
| 6040 | } | 6061 | } |
| 6041 | 6062 | ||
| 6042 | fn airReduce(self: *Self, inst: Air.Inst.Index) InnerError!void { | 6063 | fn airReduce(self: *Self, inst: Air.Inst.Index) InnerError!void { |
src/arch/arm/CodeGen.zig+33-9| ... | @@ -41,6 +41,10 @@ const gp = abi.RegisterClass.gp; | ... | @@ -41,6 +41,10 @@ const gp = abi.RegisterClass.gp; |
| 41 | 41 | ||
| 42 | const InnerError = CodeGenError || error{OutOfRegisters}; | 42 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 43 | 43 | ||
| 44 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 45 | return null; | ||
| 46 | } | ||
| 47 | |||
| 44 | gpa: Allocator, | 48 | gpa: Allocator, |
| 45 | pt: Zcu.PerThread, | 49 | pt: Zcu.PerThread, |
| 46 | air: Air, | 50 | air: Air, |
| ... | @@ -763,7 +767,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -763,7 +767,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 763 | .error_name => try self.airErrorName(inst), | 767 | .error_name => try self.airErrorName(inst), |
| 764 | .splat => try self.airSplat(inst), | 768 | .splat => try self.airSplat(inst), |
| 765 | .select => try self.airSelect(inst), | 769 | .select => try self.airSelect(inst), |
| 766 | .shuffle => try self.airShuffle(inst), | 770 | .shuffle_one => try self.airShuffleOne(inst), |
| 771 | .shuffle_two => try self.airShuffleTwo(inst), | ||
| 767 | .reduce => try self.airReduce(inst), | 772 | .reduce => try self.airReduce(inst), |
| 768 | .aggregate_init => try self.airAggregateInit(inst), | 773 | .aggregate_init => try self.airAggregateInit(inst), |
| 769 | .union_init => try self.airUnionInit(inst), | 774 | .union_init => try self.airUnionInit(inst), |
| ... | @@ -1857,7 +1862,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1857,7 +1862,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1857 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | 1862 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); |
| 1858 | 1863 | ||
| 1859 | switch (lhs_ty.zigTypeTag(zcu)) { | 1864 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 1860 | .vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), | 1865 | .vector => if (!rhs_ty.isVector(zcu)) |
| 1866 | return self.fail("TODO implement vector shl_with_overflow with scalar rhs", .{}) | ||
| 1867 | else | ||
| 1868 | return self.fail("TODO implement shl_with_overflow for vectors", .{}), | ||
| 1861 | .int => { | 1869 | .int => { |
| 1862 | const int_info = lhs_ty.intInfo(zcu); | 1870 | const int_info = lhs_ty.intInfo(zcu); |
| 1863 | if (int_info.bits <= 32) { | 1871 | if (int_info.bits <= 32) { |
| ... | @@ -1978,8 +1986,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1978,8 +1986,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1978 | } | 1986 | } |
| 1979 | 1987 | ||
| 1980 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | 1988 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1989 | const zcu = self.pt.zcu; | ||
| 1981 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 1990 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1982 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | 1991 | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 1992 | .dead | ||
| 1993 | else if (self.typeOf(bin_op.lhs).isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 1994 | return self.fail("TODO implement vector shl_sat with scalar rhs for {}", .{self.target.cpu.arch}) | ||
| 1995 | else | ||
| 1996 | return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | ||
| 1983 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1997 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1984 | } | 1998 | } |
| 1985 | 1999 | ||
| ... | @@ -3788,7 +3802,10 @@ fn shiftExact( | ... | @@ -3788,7 +3802,10 @@ fn shiftExact( |
| 3788 | const pt = self.pt; | 3802 | const pt = self.pt; |
| 3789 | const zcu = pt.zcu; | 3803 | const zcu = pt.zcu; |
| 3790 | switch (lhs_ty.zigTypeTag(zcu)) { | 3804 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 3791 | .vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3805 | .vector => if (!rhs_ty.isVector(zcu)) |
| 3806 | return self.fail("TODO ARM vector shift with scalar rhs", .{}) | ||
| 3807 | else | ||
| 3808 | return self.fail("TODO ARM binary operations on vectors", .{}), | ||
| 3792 | .int => { | 3809 | .int => { |
| 3793 | const int_info = lhs_ty.intInfo(zcu); | 3810 | const int_info = lhs_ty.intInfo(zcu); |
| 3794 | if (int_info.bits <= 32) { | 3811 | if (int_info.bits <= 32) { |
| ... | @@ -3828,7 +3845,10 @@ fn shiftNormal( | ... | @@ -3828,7 +3845,10 @@ fn shiftNormal( |
| 3828 | const pt = self.pt; | 3845 | const pt = self.pt; |
| 3829 | const zcu = pt.zcu; | 3846 | const zcu = pt.zcu; |
| 3830 | switch (lhs_ty.zigTypeTag(zcu)) { | 3847 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 3831 | .vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3848 | .vector => if (!rhs_ty.isVector(zcu)) |
| 3849 | return self.fail("TODO ARM vector shift with scalar rhs", .{}) | ||
| 3850 | else | ||
| 3851 | return self.fail("TODO ARM binary operations on vectors", .{}), | ||
| 3832 | .int => { | 3852 | .int => { |
| 3833 | const int_info = lhs_ty.intInfo(zcu); | 3853 | const int_info = lhs_ty.intInfo(zcu); |
| 3834 | if (int_info.bits <= 32) { | 3854 | if (int_info.bits <= 32) { |
| ... | @@ -6002,10 +6022,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6002,10 +6022,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 6002 | return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); | 6022 | return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); |
| 6003 | } | 6023 | } |
| 6004 | 6024 | ||
| 6005 | fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | 6025 | fn airShuffleOne(self: *Self, inst: Air.Inst.Index) !void { |
| 6006 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6026 | _ = inst; |
| 6007 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for arm", .{}); | 6027 | return self.fail("TODO implement airShuffleOne for arm", .{}); |
| 6008 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 6028 | } |
| 6029 | |||
| 6030 | fn airShuffleTwo(self: *Self, inst: Air.Inst.Index) !void { | ||
| 6031 | _ = inst; | ||
| 6032 | return self.fail("TODO implement airShuffleTwo for arm", .{}); | ||
| 6009 | } | 6033 | } |
| 6010 | 6034 | ||
| 6011 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | 6035 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
src/arch/powerpc/CodeGen.zig+4| ... | @@ -10,6 +10,10 @@ const Zcu = @import("../../Zcu.zig"); | ... | @@ -10,6 +10,10 @@ const Zcu = @import("../../Zcu.zig"); |
| 10 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 11 | const log = std.log.scoped(.codegen); | 11 | const log = std.log.scoped(.codegen); |
| 12 | 12 | ||
| 13 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 14 | return null; | ||
| 15 | } | ||
| 16 | |||
| 13 | pub fn generate( | 17 | pub fn generate( |
| 14 | bin_file: *link.File, | 18 | bin_file: *link.File, |
| 15 | pt: Zcu.PerThread, | 19 | pt: Zcu.PerThread, |
src/arch/riscv64/CodeGen.zig+34-7| ... | @@ -51,6 +51,15 @@ const Instruction = encoding.Instruction; | ... | @@ -51,6 +51,15 @@ const Instruction = encoding.Instruction; |
| 51 | 51 | ||
| 52 | const InnerError = CodeGenError || error{OutOfRegisters}; | 52 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 53 | 53 | ||
| 54 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | ||
| 55 | return comptime &.initMany(&.{ | ||
| 56 | .expand_intcast_safe, | ||
| 57 | .expand_add_safe, | ||
| 58 | .expand_sub_safe, | ||
| 59 | .expand_mul_safe, | ||
| 60 | }); | ||
| 61 | } | ||
| 62 | |||
| 54 | pt: Zcu.PerThread, | 63 | pt: Zcu.PerThread, |
| 55 | air: Air, | 64 | air: Air, |
| 56 | liveness: Air.Liveness, | 65 | liveness: Air.Liveness, |
| ... | @@ -1577,7 +1586,8 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1577,7 +1586,8 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1577 | .error_name => try func.airErrorName(inst), | 1586 | .error_name => try func.airErrorName(inst), |
| 1578 | .splat => try func.airSplat(inst), | 1587 | .splat => try func.airSplat(inst), |
| 1579 | .select => try func.airSelect(inst), | 1588 | .select => try func.airSelect(inst), |
| 1580 | .shuffle => try func.airShuffle(inst), | 1589 | .shuffle_one => try func.airShuffleOne(inst), |
| 1590 | .shuffle_two => try func.airShuffleTwo(inst), | ||
| 1581 | .reduce => try func.airReduce(inst), | 1591 | .reduce => try func.airReduce(inst), |
| 1582 | .aggregate_init => try func.airAggregateInit(inst), | 1592 | .aggregate_init => try func.airAggregateInit(inst), |
| 1583 | .union_init => try func.airUnionInit(inst), | 1593 | .union_init => try func.airUnionInit(inst), |
| ... | @@ -2764,6 +2774,7 @@ fn genBinOp( | ... | @@ -2764,6 +2774,7 @@ fn genBinOp( |
| 2764 | .shl, | 2774 | .shl, |
| 2765 | .shl_exact, | 2775 | .shl_exact, |
| 2766 | => { | 2776 | => { |
| 2777 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) return func.fail("TODO: vector shift with scalar rhs", .{}); | ||
| 2767 | if (bit_size > 64) return func.fail("TODO: genBinOp shift > 64 bits, {}", .{bit_size}); | 2778 | if (bit_size > 64) return func.fail("TODO: genBinOp shift > 64 bits, {}", .{bit_size}); |
| 2768 | try func.truncateRegister(rhs_ty, rhs_reg); | 2779 | try func.truncateRegister(rhs_ty, rhs_reg); |
| 2769 | 2780 | ||
| ... | @@ -3248,8 +3259,14 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3248,8 +3259,14 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3248 | } | 3259 | } |
| 3249 | 3260 | ||
| 3250 | fn airShlWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | 3261 | fn airShlWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3262 | const zcu = func.pt.zcu; | ||
| 3251 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3263 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3252 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement airShlWithOverflow", .{}); | 3264 | const result: MCValue = if (func.liveness.isUnused(inst)) |
| 3265 | .unreach | ||
| 3266 | else if (func.typeOf(bin_op.lhs).isVector(zcu) and !func.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 3267 | return func.fail("TODO implement vector airShlWithOverflow with scalar rhs", .{}) | ||
| 3268 | else | ||
| 3269 | return func.fail("TODO implement airShlWithOverflow", .{}); | ||
| 3253 | return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 3270 | return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 3254 | } | 3271 | } |
| 3255 | 3272 | ||
| ... | @@ -3266,8 +3283,14 @@ fn airMulSat(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3266,8 +3283,14 @@ fn airMulSat(func: *Func, inst: Air.Inst.Index) !void { |
| 3266 | } | 3283 | } |
| 3267 | 3284 | ||
| 3268 | fn airShlSat(func: *Func, inst: Air.Inst.Index) !void { | 3285 | fn airShlSat(func: *Func, inst: Air.Inst.Index) !void { |
| 3286 | const zcu = func.pt.zcu; | ||
| 3269 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3287 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3270 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement airShlSat", .{}); | 3288 | const result: MCValue = if (func.liveness.isUnused(inst)) |
| 3289 | .unreach | ||
| 3290 | else if (func.typeOf(bin_op.lhs).isVector(zcu) and !func.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 3291 | return func.fail("TODO implement vector airShlSat with scalar rhs", .{}) | ||
| 3292 | else | ||
| 3293 | return func.fail("TODO implement airShlSat", .{}); | ||
| 3271 | return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 3294 | return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 3272 | } | 3295 | } |
| 3273 | 3296 | ||
| ... | @@ -8008,10 +8031,14 @@ fn airSelect(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -8008,10 +8031,14 @@ fn airSelect(func: *Func, inst: Air.Inst.Index) !void { |
| 8008 | return func.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); | 8031 | return func.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs }); |
| 8009 | } | 8032 | } |
| 8010 | 8033 | ||
| 8011 | fn airShuffle(func: *Func, inst: Air.Inst.Index) !void { | 8034 | fn airShuffleOne(func: *Func, inst: Air.Inst.Index) !void { |
| 8012 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 8035 | _ = inst; |
| 8013 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement airShuffle for riscv64", .{}); | 8036 | return func.fail("TODO implement airShuffleOne for riscv64", .{}); |
| 8014 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 8037 | } |
| 8038 | |||
| 8039 | fn airShuffleTwo(func: *Func, inst: Air.Inst.Index) !void { | ||
| 8040 | _ = inst; | ||
| 8041 | return func.fail("TODO implement airShuffleTwo for riscv64", .{}); | ||
| 8015 | } | 8042 | } |
| 8016 | 8043 | ||
| 8017 | fn airReduce(func: *Func, inst: Air.Inst.Index) !void { | 8044 | fn airReduce(func: *Func, inst: Air.Inst.Index) !void { |
src/arch/sparc64/CodeGen.zig+25-5| ... | @@ -41,6 +41,10 @@ const Self = @This(); | ... | @@ -41,6 +41,10 @@ const Self = @This(); |
| 41 | 41 | ||
| 42 | const InnerError = CodeGenError || error{OutOfRegisters}; | 42 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 43 | 43 | ||
| 44 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 45 | return null; | ||
| 46 | } | ||
| 47 | |||
| 44 | const RegisterView = enum(u1) { | 48 | const RegisterView = enum(u1) { |
| 45 | caller, | 49 | caller, |
| 46 | callee, | 50 | callee, |
| ... | @@ -617,7 +621,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -617,7 +621,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 617 | .error_name => try self.airErrorName(inst), | 621 | .error_name => try self.airErrorName(inst), |
| 618 | .splat => try self.airSplat(inst), | 622 | .splat => try self.airSplat(inst), |
| 619 | .select => @panic("TODO try self.airSelect(inst)"), | 623 | .select => @panic("TODO try self.airSelect(inst)"), |
| 620 | .shuffle => @panic("TODO try self.airShuffle(inst)"), | 624 | .shuffle_one => @panic("TODO try self.airShuffleOne(inst)"), |
| 625 | .shuffle_two => @panic("TODO try self.airShuffleTwo(inst)"), | ||
| 621 | .reduce => @panic("TODO try self.airReduce(inst)"), | 626 | .reduce => @panic("TODO try self.airReduce(inst)"), |
| 622 | .aggregate_init => try self.airAggregateInit(inst), | 627 | .aggregate_init => try self.airAggregateInit(inst), |
| 623 | .union_init => try self.airUnionInit(inst), | 628 | .union_init => try self.airUnionInit(inst), |
| ... | @@ -2270,8 +2275,14 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2270,8 +2275,14 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 2270 | } | 2275 | } |
| 2271 | 2276 | ||
| 2272 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | 2277 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 2278 | const zcu = self.pt.zcu; | ||
| 2273 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2279 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2274 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | 2280 | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 2281 | .dead | ||
| 2282 | else if (self.typeOf(bin_op.lhs).isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 2283 | return self.fail("TODO implement vector shl_sat with scalar rhs for {}", .{self.target.cpu.arch}) | ||
| 2284 | else | ||
| 2285 | return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | ||
| 2275 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 2286 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2276 | } | 2287 | } |
| 2277 | 2288 | ||
| ... | @@ -2287,7 +2298,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2287,7 +2298,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2287 | const rhs_ty = self.typeOf(extra.rhs); | 2298 | const rhs_ty = self.typeOf(extra.rhs); |
| 2288 | 2299 | ||
| 2289 | switch (lhs_ty.zigTypeTag(zcu)) { | 2300 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 2290 | .vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), | 2301 | .vector => if (!rhs_ty.isVector(zcu)) |
| 2302 | return self.fail("TODO implement vector shl_with_overflow with scalar rhs", .{}) | ||
| 2303 | else | ||
| 2304 | return self.fail("TODO implement mul_with_overflow for vectors", .{}), | ||
| 2291 | .int => { | 2305 | .int => { |
| 2292 | const int_info = lhs_ty.intInfo(zcu); | 2306 | const int_info = lhs_ty.intInfo(zcu); |
| 2293 | if (int_info.bits <= 64) { | 2307 | if (int_info.bits <= 64) { |
| ... | @@ -3002,7 +3016,10 @@ fn binOp( | ... | @@ -3002,7 +3016,10 @@ fn binOp( |
| 3002 | 3016 | ||
| 3003 | // Truncate if necessary | 3017 | // Truncate if necessary |
| 3004 | switch (lhs_ty.zigTypeTag(zcu)) { | 3018 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 3005 | .vector => return self.fail("TODO binary operations on vectors", .{}), | 3019 | .vector => if (rhs_ty.isVector(zcu)) |
| 3020 | return self.fail("TODO vector shift with scalar rhs", .{}) | ||
| 3021 | else | ||
| 3022 | return self.fail("TODO binary operations on vectors", .{}), | ||
| 3006 | .int => { | 3023 | .int => { |
| 3007 | const int_info = lhs_ty.intInfo(zcu); | 3024 | const int_info = lhs_ty.intInfo(zcu); |
| 3008 | if (int_info.bits <= 64) { | 3025 | if (int_info.bits <= 64) { |
| ... | @@ -3024,7 +3041,10 @@ fn binOp( | ... | @@ -3024,7 +3041,10 @@ fn binOp( |
| 3024 | .shr_exact, | 3041 | .shr_exact, |
| 3025 | => { | 3042 | => { |
| 3026 | switch (lhs_ty.zigTypeTag(zcu)) { | 3043 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 3027 | .vector => return self.fail("TODO binary operations on vectors", .{}), | 3044 | .vector => if (rhs_ty.isVector(zcu)) |
| 3045 | return self.fail("TODO vector shift with scalar rhs", .{}) | ||
| 3046 | else | ||
| 3047 | return self.fail("TODO binary operations on vectors", .{}), | ||
| 3028 | .int => { | 3048 | .int => { |
| 3029 | const int_info = lhs_ty.intInfo(zcu); | 3049 | const int_info = lhs_ty.intInfo(zcu); |
| 3030 | if (int_info.bits <= 64) { | 3050 | if (int_info.bits <= 64) { |
src/arch/wasm/CodeGen.zig+116-50| ... | @@ -31,6 +31,15 @@ const libcFloatSuffix = target_util.libcFloatSuffix; | ... | @@ -31,6 +31,15 @@ const libcFloatSuffix = target_util.libcFloatSuffix; |
| 31 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; | 31 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; |
| 32 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | 32 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; |
| 33 | 33 | ||
| 34 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | ||
| 35 | return comptime &.initMany(&.{ | ||
| 36 | .expand_intcast_safe, | ||
| 37 | .expand_add_safe, | ||
| 38 | .expand_sub_safe, | ||
| 39 | .expand_mul_safe, | ||
| 40 | }); | ||
| 41 | } | ||
| 42 | |||
| 34 | /// Reference to the function declaration the code | 43 | /// Reference to the function declaration the code |
| 35 | /// section belongs to | 44 | /// section belongs to |
| 36 | owner_nav: InternPool.Nav.Index, | 45 | owner_nav: InternPool.Nav.Index, |
| ... | @@ -1995,7 +2004,8 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1995,7 +2004,8 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1995 | .ret_load => cg.airRetLoad(inst), | 2004 | .ret_load => cg.airRetLoad(inst), |
| 1996 | .splat => cg.airSplat(inst), | 2005 | .splat => cg.airSplat(inst), |
| 1997 | .select => cg.airSelect(inst), | 2006 | .select => cg.airSelect(inst), |
| 1998 | .shuffle => cg.airShuffle(inst), | 2007 | .shuffle_one => cg.airShuffleOne(inst), |
| 2008 | .shuffle_two => cg.airShuffleTwo(inst), | ||
| 1999 | .reduce => cg.airReduce(inst), | 2009 | .reduce => cg.airReduce(inst), |
| 2000 | .aggregate_init => cg.airAggregateInit(inst), | 2010 | .aggregate_init => cg.airAggregateInit(inst), |
| 2001 | .union_init => cg.airUnionInit(inst), | 2011 | .union_init => cg.airUnionInit(inst), |
| ... | @@ -2638,6 +2648,10 @@ fn airBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -2638,6 +2648,10 @@ fn airBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2638 | // For big integers we can ignore this as we will call into compiler-rt which handles this. | 2648 | // For big integers we can ignore this as we will call into compiler-rt which handles this. |
| 2639 | const result = switch (op) { | 2649 | const result = switch (op) { |
| 2640 | .shr, .shl => result: { | 2650 | .shr, .shl => result: { |
| 2651 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) { | ||
| 2652 | return cg.fail("TODO: implement vector '{s}' with scalar rhs", .{@tagName(op)}); | ||
| 2653 | } | ||
| 2654 | |||
| 2641 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(zcu))) orelse { | 2655 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(zcu))) orelse { |
| 2642 | return cg.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); | 2656 | return cg.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); |
| 2643 | }; | 2657 | }; |
| ... | @@ -3055,8 +3069,12 @@ fn airWrapBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -3055,8 +3069,12 @@ fn airWrapBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3055 | const lhs_ty = cg.typeOf(bin_op.lhs); | 3069 | const lhs_ty = cg.typeOf(bin_op.lhs); |
| 3056 | const rhs_ty = cg.typeOf(bin_op.rhs); | 3070 | const rhs_ty = cg.typeOf(bin_op.rhs); |
| 3057 | 3071 | ||
| 3058 | if (lhs_ty.zigTypeTag(zcu) == .vector or rhs_ty.zigTypeTag(zcu) == .vector) { | 3072 | if (lhs_ty.isVector(zcu)) { |
| 3059 | return cg.fail("TODO: Implement wrapping arithmetic for vectors", .{}); | 3073 | if ((op == .shr or op == .shl) and !rhs_ty.isVector(zcu)) { |
| 3074 | return cg.fail("TODO: implement wrapping vector '{s}' with scalar rhs", .{@tagName(op)}); | ||
| 3075 | } else { | ||
| 3076 | return cg.fail("TODO: implement wrapping '{s}' for vectors", .{@tagName(op)}); | ||
| 3077 | } | ||
| 3060 | } | 3078 | } |
| 3061 | 3079 | ||
| 3062 | // For certain operations, such as shifting, the types are different. | 3080 | // For certain operations, such as shifting, the types are different. |
| ... | @@ -5160,66 +5178,105 @@ fn airSelect(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5160,66 +5178,105 @@ fn airSelect(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5160 | return cg.fail("TODO: Implement wasm airSelect", .{}); | 5178 | return cg.fail("TODO: Implement wasm airSelect", .{}); |
| 5161 | } | 5179 | } |
| 5162 | 5180 | ||
| 5163 | fn airShuffle(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5181 | fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5164 | const pt = cg.pt; | 5182 | const pt = cg.pt; |
| 5165 | const zcu = pt.zcu; | 5183 | const zcu = pt.zcu; |
| 5166 | const inst_ty = cg.typeOfIndex(inst); | ||
| 5167 | const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 5168 | const extra = cg.air.extraData(Air.Shuffle, ty_pl.payload).data; | ||
| 5169 | 5184 | ||
| 5170 | const a = try cg.resolveInst(extra.a); | 5185 | const unwrapped = cg.air.unwrapShuffleOne(zcu, inst); |
| 5171 | const b = try cg.resolveInst(extra.b); | 5186 | const result_ty = unwrapped.result_ty; |
| 5172 | const mask = Value.fromInterned(extra.mask); | 5187 | const mask = unwrapped.mask; |
| 5173 | const mask_len = extra.mask_len; | 5188 | const operand = try cg.resolveInst(unwrapped.operand); |
| 5174 | 5189 | ||
| 5175 | const child_ty = inst_ty.childType(zcu); | 5190 | const elem_ty = result_ty.childType(zcu); |
| 5176 | const elem_size = child_ty.abiSize(zcu); | 5191 | const elem_size = elem_ty.abiSize(zcu); |
| 5177 | 5192 | ||
| 5178 | // TODO: One of them could be by ref; handle in loop | 5193 | // TODO: this function could have an `i8x16_shuffle` fast path like `airShuffleTwo` if we were |
| 5179 | if (isByRef(cg.typeOf(extra.a), zcu, cg.target) or isByRef(inst_ty, zcu, cg.target)) { | 5194 | // to lower the comptime-known operands to a non-by-ref vector value. |
| 5180 | const result = try cg.allocStack(inst_ty); | ||
| 5181 | 5195 | ||
| 5182 | for (0..mask_len) |index| { | 5196 | // TODO: this is incorrect if either operand or the result is *not* by-ref, which is possible. |
| 5183 | const value = (try mask.elemValue(pt, index)).toSignedInt(zcu); | 5197 | // I tried to fix it, but I couldn't make much sense of how this backend handles memory. |
| 5198 | if (!isByRef(result_ty, zcu, cg.target) or | ||
| 5199 | !isByRef(cg.typeOf(unwrapped.operand), zcu, cg.target)) return cg.fail("TODO: handle mixed by-ref shuffle", .{}); | ||
| 5184 | 5200 | ||
| 5185 | try cg.emitWValue(result); | 5201 | const dest_alloc = try cg.allocStack(result_ty); |
| 5202 | for (mask, 0..) |mask_elem, out_idx| { | ||
| 5203 | try cg.emitWValue(dest_alloc); | ||
| 5204 | const elem_val = switch (mask_elem.unwrap()) { | ||
| 5205 | .elem => |idx| try cg.load(operand, elem_ty, @intCast(elem_size * idx)), | ||
| 5206 | .value => |val| try cg.lowerConstant(.fromInterned(val), elem_ty), | ||
| 5207 | }; | ||
| 5208 | try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx)); | ||
| 5209 | } | ||
| 5210 | return cg.finishAir(inst, dest_alloc, &.{unwrapped.operand}); | ||
| 5211 | } | ||
| 5186 | 5212 | ||
| 5187 | const loaded = if (value >= 0) | 5213 | fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5188 | try cg.load(a, child_ty, @as(u32, @intCast(@as(i64, @intCast(elem_size)) * value))) | 5214 | const pt = cg.pt; |
| 5189 | else | 5215 | const zcu = pt.zcu; |
| 5190 | try cg.load(b, child_ty, @as(u32, @intCast(@as(i64, @intCast(elem_size)) * ~value))); | ||
| 5191 | 5216 | ||
| 5192 | try cg.store(.stack, loaded, child_ty, result.stack_offset.value + @as(u32, @intCast(elem_size)) * @as(u32, @intCast(index))); | 5217 | const unwrapped = cg.air.unwrapShuffleTwo(zcu, inst); |
| 5193 | } | 5218 | const result_ty = unwrapped.result_ty; |
| 5219 | const mask = unwrapped.mask; | ||
| 5220 | const operand_a = try cg.resolveInst(unwrapped.operand_a); | ||
| 5221 | const operand_b = try cg.resolveInst(unwrapped.operand_b); | ||
| 5194 | 5222 | ||
| 5195 | return cg.finishAir(inst, result, &.{ extra.a, extra.b }); | 5223 | const a_ty = cg.typeOf(unwrapped.operand_a); |
| 5196 | } else { | 5224 | const b_ty = cg.typeOf(unwrapped.operand_b); |
| 5197 | var operands = [_]u32{ | 5225 | const elem_ty = result_ty.childType(zcu); |
| 5198 | @intFromEnum(std.wasm.SimdOpcode.i8x16_shuffle), | 5226 | const elem_size = elem_ty.abiSize(zcu); |
| 5199 | } ++ [1]u32{undefined} ** 4; | ||
| 5200 | |||
| 5201 | var lanes = mem.asBytes(operands[1..]); | ||
| 5202 | for (0..@as(usize, @intCast(mask_len))) |index| { | ||
| 5203 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(zcu); | ||
| 5204 | const base_index = if (mask_elem >= 0) | ||
| 5205 | @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem)) | ||
| 5206 | else | ||
| 5207 | 16 + @as(u8, @intCast(@as(i64, @intCast(elem_size)) * ~mask_elem)); | ||
| 5208 | 5227 | ||
| 5209 | for (0..@as(usize, @intCast(elem_size))) |byte_offset| { | 5228 | // WASM has `i8x16_shuffle`, which we can apply if the element type bit size is a multiple of 8 |
| 5210 | lanes[index * @as(usize, @intCast(elem_size)) + byte_offset] = base_index + @as(u8, @intCast(byte_offset)); | 5229 | // and the input and output vectors have a bit size of 128 (and are hence not by-ref). Otherwise, |
| 5230 | // we fall back to a naive loop lowering. | ||
| 5231 | if (!isByRef(a_ty, zcu, cg.target) and | ||
| 5232 | !isByRef(b_ty, zcu, cg.target) and | ||
| 5233 | !isByRef(result_ty, zcu, cg.target) and | ||
| 5234 | elem_ty.bitSize(zcu) % 8 == 0) | ||
| 5235 | { | ||
| 5236 | var lane_map: [16]u8 align(4) = undefined; | ||
| 5237 | const lanes_per_elem: usize = @intCast(elem_ty.bitSize(zcu) / 8); | ||
| 5238 | for (mask, 0..) |mask_elem, out_idx| { | ||
| 5239 | const out_first_lane = out_idx * lanes_per_elem; | ||
| 5240 | const in_first_lane = switch (mask_elem.unwrap()) { | ||
| 5241 | .a_elem => |i| i * lanes_per_elem, | ||
| 5242 | .b_elem => |i| i * lanes_per_elem + 16, | ||
| 5243 | .undef => 0, // doesn't matter | ||
| 5244 | }; | ||
| 5245 | for (lane_map[out_first_lane..][0..lanes_per_elem], in_first_lane..) |*out, in| { | ||
| 5246 | out.* = @intCast(in); | ||
| 5211 | } | 5247 | } |
| 5212 | } | 5248 | } |
| 5213 | 5249 | try cg.emitWValue(operand_a); | |
| 5214 | try cg.emitWValue(a); | 5250 | try cg.emitWValue(operand_b); |
| 5215 | try cg.emitWValue(b); | ||
| 5216 | |||
| 5217 | const extra_index = cg.extraLen(); | 5251 | const extra_index = cg.extraLen(); |
| 5218 | try cg.mir_extra.appendSlice(cg.gpa, &operands); | 5252 | try cg.mir_extra.appendSlice(cg.gpa, &.{ |
| 5253 | @intFromEnum(std.wasm.SimdOpcode.i8x16_shuffle), | ||
| 5254 | @bitCast(lane_map[0..4].*), | ||
| 5255 | @bitCast(lane_map[4..8].*), | ||
| 5256 | @bitCast(lane_map[8..12].*), | ||
| 5257 | @bitCast(lane_map[12..].*), | ||
| 5258 | }); | ||
| 5219 | try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); | 5259 | try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 5220 | 5260 | return cg.finishAir(inst, .stack, &.{ unwrapped.operand_a, unwrapped.operand_b }); | |
| 5221 | return cg.finishAir(inst, .stack, &.{ extra.a, extra.b }); | 5261 | } |
| 5262 | |||
| 5263 | // TODO: this is incorrect if either operand or the result is *not* by-ref, which is possible. | ||
| 5264 | // I tried to fix it, but I couldn't make much sense of how this backend handles memory. | ||
| 5265 | if (!isByRef(result_ty, zcu, cg.target) or | ||
| 5266 | !isByRef(a_ty, zcu, cg.target) or | ||
| 5267 | !isByRef(b_ty, zcu, cg.target)) return cg.fail("TODO: handle mixed by-ref shuffle", .{}); | ||
| 5268 | |||
| 5269 | const dest_alloc = try cg.allocStack(result_ty); | ||
| 5270 | for (mask, 0..) |mask_elem, out_idx| { | ||
| 5271 | try cg.emitWValue(dest_alloc); | ||
| 5272 | const elem_val = switch (mask_elem.unwrap()) { | ||
| 5273 | .a_elem => |idx| try cg.load(operand_a, elem_ty, @intCast(elem_size * idx)), | ||
| 5274 | .b_elem => |idx| try cg.load(operand_b, elem_ty, @intCast(elem_size * idx)), | ||
| 5275 | .undef => try cg.emitUndefined(elem_ty), | ||
| 5276 | }; | ||
| 5277 | try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx)); | ||
| 5222 | } | 5278 | } |
| 5279 | return cg.finishAir(inst, dest_alloc, &.{ unwrapped.operand_a, unwrapped.operand_b }); | ||
| 5223 | } | 5280 | } |
| 5224 | 5281 | ||
| 5225 | fn airReduce(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5282 | fn airReduce(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | @@ -6067,13 +6124,17 @@ fn airShlWithOverflow(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6067,13 +6124,17 @@ fn airShlWithOverflow(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6067 | const ty = cg.typeOf(extra.lhs); | 6124 | const ty = cg.typeOf(extra.lhs); |
| 6068 | const rhs_ty = cg.typeOf(extra.rhs); | 6125 | const rhs_ty = cg.typeOf(extra.rhs); |
| 6069 | 6126 | ||
| 6070 | if (ty.zigTypeTag(zcu) == .vector) { | 6127 | if (ty.isVector(zcu)) { |
| 6071 | return cg.fail("TODO: Implement overflow arithmetic for vectors", .{}); | 6128 | if (!rhs_ty.isVector(zcu)) { |
| 6129 | return cg.fail("TODO: implement vector 'shl_with_overflow' with scalar rhs", .{}); | ||
| 6130 | } else { | ||
| 6131 | return cg.fail("TODO: implement vector 'shl_with_overflow'", .{}); | ||
| 6132 | } | ||
| 6072 | } | 6133 | } |
| 6073 | 6134 | ||
| 6074 | const int_info = ty.intInfo(zcu); | 6135 | const int_info = ty.intInfo(zcu); |
| 6075 | const wasm_bits = toWasmBits(int_info.bits) orelse { | 6136 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6076 | return cg.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits}); | 6137 | return cg.fail("TODO: implement 'shl_with_overflow' for integer bitsize: {d}", .{int_info.bits}); |
| 6077 | }; | 6138 | }; |
| 6078 | 6139 | ||
| 6079 | // Ensure rhs is coerced to lhs as they must have the same WebAssembly types | 6140 | // Ensure rhs is coerced to lhs as they must have the same WebAssembly types |
| ... | @@ -6994,6 +7055,11 @@ fn airShlSat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6994,6 +7055,11 @@ fn airShlSat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6994 | 7055 | ||
| 6995 | const pt = cg.pt; | 7056 | const pt = cg.pt; |
| 6996 | const zcu = pt.zcu; | 7057 | const zcu = pt.zcu; |
| 7058 | |||
| 7059 | if (cg.typeOf(bin_op.lhs).isVector(zcu) and !cg.typeOf(bin_op.rhs).isVector(zcu)) { | ||
| 7060 | return cg.fail("TODO: implement vector 'shl_sat' with scalar rhs", .{}); | ||
| 7061 | } | ||
| 7062 | |||
| 6997 | const ty = cg.typeOfIndex(inst); | 7063 | const ty = cg.typeOfIndex(inst); |
| 6998 | const int_info = ty.intInfo(zcu); | 7064 | const int_info = ty.intInfo(zcu); |
| 6999 | const is_signed = int_info.signedness == .signed; | 7065 | const is_signed = int_info.signedness == .signed; |
src/arch/x86_64/CodeGen.zig+461-137| ... | @@ -32,10 +32,79 @@ const FrameIndex = bits.FrameIndex; | ... | @@ -32,10 +32,79 @@ const FrameIndex = bits.FrameIndex; |
| 32 | 32 | ||
| 33 | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; | 33 | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; |
| 34 | 34 | ||
| 35 | pub const legalize_features: Air.Legalize.Features = .{ | 35 | pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features { |
| 36 | .remove_shift_vector_rhs_splat = false, | 36 | @setEvalBranchQuota(1_200); |
| 37 | .reduce_one_elem_to_bitcast = true, | 37 | return switch (target.ofmt == .coff) { |
| 38 | }; | 38 | inline false, true => |use_old| comptime &.init(.{ |
| 39 | .scalarize_add = use_old, | ||
| 40 | .scalarize_add_sat = use_old, | ||
| 41 | .scalarize_sub = use_old, | ||
| 42 | .scalarize_sub_sat = use_old, | ||
| 43 | .scalarize_mul = use_old, | ||
| 44 | .scalarize_mul_wrap = use_old, | ||
| 45 | .scalarize_mul_sat = true, | ||
| 46 | .scalarize_div_float = use_old, | ||
| 47 | .scalarize_div_float_optimized = use_old, | ||
| 48 | .scalarize_div_trunc = use_old, | ||
| 49 | .scalarize_div_trunc_optimized = use_old, | ||
| 50 | .scalarize_div_floor = use_old, | ||
| 51 | .scalarize_div_floor_optimized = use_old, | ||
| 52 | .scalarize_div_exact = use_old, | ||
| 53 | .scalarize_div_exact_optimized = use_old, | ||
| 54 | .scalarize_max = use_old, | ||
| 55 | .scalarize_min = use_old, | ||
| 56 | .scalarize_add_with_overflow = true, | ||
| 57 | .scalarize_sub_with_overflow = true, | ||
| 58 | .scalarize_mul_with_overflow = true, | ||
| 59 | .scalarize_shl_with_overflow = true, | ||
| 60 | .scalarize_bit_and = use_old, | ||
| 61 | .scalarize_bit_or = use_old, | ||
| 62 | .scalarize_shr = true, | ||
| 63 | .scalarize_shr_exact = true, | ||
| 64 | .scalarize_shl = true, | ||
| 65 | .scalarize_shl_exact = true, | ||
| 66 | .scalarize_shl_sat = true, | ||
| 67 | .scalarize_xor = use_old, | ||
| 68 | .scalarize_not = use_old, | ||
| 69 | .scalarize_clz = use_old, | ||
| 70 | .scalarize_ctz = true, | ||
| 71 | .scalarize_popcount = true, | ||
| 72 | .scalarize_byte_swap = true, | ||
| 73 | .scalarize_bit_reverse = true, | ||
| 74 | .scalarize_sin = use_old, | ||
| 75 | .scalarize_cos = use_old, | ||
| 76 | .scalarize_tan = use_old, | ||
| 77 | .scalarize_exp = use_old, | ||
| 78 | .scalarize_exp2 = use_old, | ||
| 79 | .scalarize_log = use_old, | ||
| 80 | .scalarize_log2 = use_old, | ||
| 81 | .scalarize_log10 = use_old, | ||
| 82 | .scalarize_abs = use_old, | ||
| 83 | .scalarize_floor = use_old, | ||
| 84 | .scalarize_ceil = use_old, | ||
| 85 | .scalarize_trunc_float = use_old, | ||
| 86 | .scalarize_cmp_vector = true, | ||
| 87 | .scalarize_cmp_vector_optimized = true, | ||
| 88 | .scalarize_fptrunc = use_old, | ||
| 89 | .scalarize_fpext = use_old, | ||
| 90 | .scalarize_intcast = use_old, | ||
| 91 | .scalarize_int_from_float = use_old, | ||
| 92 | .scalarize_int_from_float_optimized = use_old, | ||
| 93 | .scalarize_float_from_int = use_old, | ||
| 94 | .scalarize_shuffle_one = true, | ||
| 95 | .scalarize_shuffle_two = true, | ||
| 96 | .scalarize_select = true, | ||
| 97 | .scalarize_mul_add = use_old, | ||
| 98 | |||
| 99 | .unsplat_shift_rhs = false, | ||
| 100 | .reduce_one_elem_to_bitcast = true, | ||
| 101 | .expand_intcast_safe = true, | ||
| 102 | .expand_add_safe = true, | ||
| 103 | .expand_sub_safe = true, | ||
| 104 | .expand_mul_safe = true, | ||
| 105 | }), | ||
| 106 | }; | ||
| 107 | } | ||
| 39 | 108 | ||
| 40 | /// Set this to `false` to uncover Sema OPV bugs. | 109 | /// Set this to `false` to uncover Sema OPV bugs. |
| 41 | /// https://github.com/ziglang/zig/issues/22419 | 110 | /// https://github.com/ziglang/zig/issues/22419 |
| ... | @@ -218,7 +287,7 @@ pub const MCValue = union(enum) { | ... | @@ -218,7 +287,7 @@ pub const MCValue = union(enum) { |
| 218 | /// Payload is a frame address. | 287 | /// Payload is a frame address. |
| 219 | lea_frame: bits.FrameAddr, | 288 | lea_frame: bits.FrameAddr, |
| 220 | /// Supports integer_per_element abi | 289 | /// Supports integer_per_element abi |
| 221 | elementwise_regs_then_frame: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex }, | 290 | elementwise_args: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex }, |
| 222 | /// This indicates that we have already allocated a frame index for this instruction, | 291 | /// This indicates that we have already allocated a frame index for this instruction, |
| 223 | /// but it has not been spilled there yet in the current control flow. | 292 | /// but it has not been spilled there yet in the current control flow. |
| 224 | /// Payload is a frame index. | 293 | /// Payload is a frame index. |
| ... | @@ -240,7 +309,7 @@ pub const MCValue = union(enum) { | ... | @@ -240,7 +309,7 @@ pub const MCValue = union(enum) { |
| 240 | .lea_direct, | 309 | .lea_direct, |
| 241 | .lea_got, | 310 | .lea_got, |
| 242 | .lea_frame, | 311 | .lea_frame, |
| 243 | .elementwise_regs_then_frame, | 312 | .elementwise_args, |
| 244 | .reserved_frame, | 313 | .reserved_frame, |
| 245 | .air_ref, | 314 | .air_ref, |
| 246 | => false, | 315 | => false, |
| ... | @@ -355,7 +424,7 @@ pub const MCValue = union(enum) { | ... | @@ -355,7 +424,7 @@ pub const MCValue = union(enum) { |
| 355 | .lea_direct, | 424 | .lea_direct, |
| 356 | .lea_got, | 425 | .lea_got, |
| 357 | .lea_frame, | 426 | .lea_frame, |
| 358 | .elementwise_regs_then_frame, | 427 | .elementwise_args, |
| 359 | .reserved_frame, | 428 | .reserved_frame, |
| 360 | .air_ref, | 429 | .air_ref, |
| 361 | => unreachable, // not in memory | 430 | => unreachable, // not in memory |
| ... | @@ -389,7 +458,7 @@ pub const MCValue = union(enum) { | ... | @@ -389,7 +458,7 @@ pub const MCValue = union(enum) { |
| 389 | .load_got, | 458 | .load_got, |
| 390 | .load_frame, | 459 | .load_frame, |
| 391 | .load_symbol, | 460 | .load_symbol, |
| 392 | .elementwise_regs_then_frame, | 461 | .elementwise_args, |
| 393 | .reserved_frame, | 462 | .reserved_frame, |
| 394 | .air_ref, | 463 | .air_ref, |
| 395 | => unreachable, // not dereferenceable | 464 | => unreachable, // not dereferenceable |
| ... | @@ -409,7 +478,7 @@ pub const MCValue = union(enum) { | ... | @@ -409,7 +478,7 @@ pub const MCValue = union(enum) { |
| 409 | .unreach, | 478 | .unreach, |
| 410 | .dead, | 479 | .dead, |
| 411 | .undef, | 480 | .undef, |
| 412 | .elementwise_regs_then_frame, | 481 | .elementwise_args, |
| 413 | .reserved_frame, | 482 | .reserved_frame, |
| 414 | .air_ref, | 483 | .air_ref, |
| 415 | => unreachable, // not valid | 484 | => unreachable, // not valid |
| ... | @@ -463,7 +532,7 @@ pub const MCValue = union(enum) { | ... | @@ -463,7 +532,7 @@ pub const MCValue = union(enum) { |
| 463 | .load_got, | 532 | .load_got, |
| 464 | .lea_got, | 533 | .lea_got, |
| 465 | .lea_frame, | 534 | .lea_frame, |
| 466 | .elementwise_regs_then_frame, | 535 | .elementwise_args, |
| 467 | .reserved_frame, | 536 | .reserved_frame, |
| 468 | .lea_symbol, | 537 | .lea_symbol, |
| 469 | => unreachable, | 538 | => unreachable, |
| ... | @@ -547,7 +616,7 @@ pub const MCValue = union(enum) { | ... | @@ -547,7 +616,7 @@ pub const MCValue = union(enum) { |
| 547 | .load_got => |pl| try writer.print("[got:{d}]", .{pl}), | 616 | .load_got => |pl| try writer.print("[got:{d}]", .{pl}), |
| 548 | .lea_got => |pl| try writer.print("got:{d}", .{pl}), | 617 | .lea_got => |pl| try writer.print("got:{d}", .{pl}), |
| 549 | .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), | 618 | .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), |
| 550 | .elementwise_regs_then_frame => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{ | 619 | .elementwise_args => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{ |
| 551 | pl.regs, pl.frame_index, pl.frame_off, | 620 | pl.regs, pl.frame_index, pl.frame_off, |
| 552 | }), | 621 | }), |
| 553 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), | 622 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), |
| ... | @@ -580,7 +649,7 @@ const InstTracking = struct { | ... | @@ -580,7 +649,7 @@ const InstTracking = struct { |
| 580 | .lea_symbol, | 649 | .lea_symbol, |
| 581 | => result, | 650 | => result, |
| 582 | .dead, | 651 | .dead, |
| 583 | .elementwise_regs_then_frame, | 652 | .elementwise_args, |
| 584 | .reserved_frame, | 653 | .reserved_frame, |
| 585 | .air_ref, | 654 | .air_ref, |
| 586 | => unreachable, | 655 | => unreachable, |
| ... | @@ -689,7 +758,7 @@ const InstTracking = struct { | ... | @@ -689,7 +758,7 @@ const InstTracking = struct { |
| 689 | .register_overflow, | 758 | .register_overflow, |
| 690 | .register_mask, | 759 | .register_mask, |
| 691 | .indirect, | 760 | .indirect, |
| 692 | .elementwise_regs_then_frame, | 761 | .elementwise_args, |
| 693 | .air_ref, | 762 | .air_ref, |
| 694 | => unreachable, | 763 | => unreachable, |
| 695 | } | 764 | } |
| ... | @@ -2239,11 +2308,17 @@ fn gen(self: *CodeGen) InnerError!void { | ... | @@ -2239,11 +2308,17 @@ fn gen(self: *CodeGen) InnerError!void { |
| 2239 | try self.genBody(self.air.getMainBody()); | 2308 | try self.genBody(self.air.getMainBody()); |
| 2240 | 2309 | ||
| 2241 | const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: { | 2310 | const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: { |
| 2242 | const epilogue_relocs_last_index = self.epilogue_relocs.items.len - 1; | 2311 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); |
| 2243 | for (if (self.epilogue_relocs.items[epilogue_relocs_last_index] == self.mir_instructions.len - 1) epilogue_relocs: { | 2312 | while (self.epilogue_relocs.getLastOrNull() == last_inst) { |
| 2244 | _ = self.mir_instructions.pop(); | 2313 | self.epilogue_relocs.items.len -= 1; |
| 2245 | break :epilogue_relocs self.epilogue_relocs.items[0..epilogue_relocs_last_index]; | 2314 | self.mir_instructions.set(last_inst, .{ |
| 2246 | } else self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc); | 2315 | .tag = .pseudo, |
| 2316 | .ops = .pseudo_dead_none, | ||
| 2317 | .data = undefined, | ||
| 2318 | }); | ||
| 2319 | last_inst -= 1; | ||
| 2320 | } | ||
| 2321 | for (self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc); | ||
| 2247 | 2322 | ||
| 2248 | if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); | 2323 | if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); |
| 2249 | const backpatch_stack_dealloc = try self.asmPlaceholder(); | 2324 | const backpatch_stack_dealloc = try self.asmPlaceholder(); |
| ... | @@ -2430,7 +2505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2430,7 +2505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2430 | switch (air_tags[@intFromEnum(inst)]) { | 2505 | switch (air_tags[@intFromEnum(inst)]) { |
| 2431 | // zig fmt: off | 2506 | // zig fmt: off |
| 2432 | .select => try cg.airSelect(inst), | 2507 | .select => try cg.airSelect(inst), |
| 2433 | .shuffle => try cg.airShuffle(inst), | 2508 | .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"), |
| 2434 | // zig fmt: on | 2509 | // zig fmt: on |
| 2435 | 2510 | ||
| 2436 | .arg => if (cg.debug_output != .none) { | 2511 | .arg => if (cg.debug_output != .none) { |
| ... | @@ -5714,7 +5789,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -5714,7 +5789,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5714 | }, | 5789 | }, |
| 5715 | .extra_temps = .{ | 5790 | .extra_temps = .{ |
| 5716 | .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, | 5791 | .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, |
| 5717 | .{ .type = .i64, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } }, | 5792 | .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, |
| 5718 | .unused, | 5793 | .unused, |
| 5719 | .unused, | 5794 | .unused, |
| 5720 | .unused, | 5795 | .unused, |
| ... | @@ -63352,14 +63427,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -63352,14 +63427,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 63352 | defer assert(cg.loops.remove(inst)); | 63427 | defer assert(cg.loops.remove(inst)); |
| 63353 | try cg.genBodyBlock(@ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len])); | 63428 | try cg.genBodyBlock(@ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len])); |
| 63354 | }, | 63429 | }, |
| 63355 | .repeat => if (use_old) try cg.airRepeat(inst) else { | 63430 | .repeat => { |
| 63356 | const repeat = air_datas[@intFromEnum(inst)].repeat; | 63431 | const repeat = air_datas[@intFromEnum(inst)].repeat; |
| 63357 | const loop = cg.loops.get(repeat.loop_inst).?; | 63432 | const loop = cg.loops.get(repeat.loop_inst).?; |
| 63358 | try cg.restoreState(loop.state, &.{}, .{ | 63433 | try cg.restoreState(loop.state, &.{}, .{ |
| 63359 | .emit_instructions = true, | 63434 | .emit_instructions = true, |
| 63360 | .update_tracking = false, | 63435 | .update_tracking = false, |
| 63361 | .resurrect = false, | 63436 | .resurrect = false, |
| 63362 | .close_scope = true, | 63437 | .close_scope = false, |
| 63363 | }); | 63438 | }); |
| 63364 | _ = try cg.asmJmpReloc(loop.target); | 63439 | _ = try cg.asmJmpReloc(loop.target); |
| 63365 | }, | 63440 | }, |
| ... | @@ -77234,11 +77309,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77234,11 +77309,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77234 | }, | 77309 | }, |
| 77235 | } | 77310 | } |
| 77236 | }, | 77311 | }, |
| 77237 | .int => res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err, | 77312 | .int => { |
| 77313 | switch (ty.zigTypeTag(zcu)) { | ||
| 77314 | else => {}, | ||
| 77315 | .@"struct", .@"union" => { | ||
| 77316 | assert(ty.containerLayout(zcu) == .@"packed"); | ||
| 77317 | for (&ops) |*op| op.wrapInt(cg) catch |err| switch (err) { | ||
| 77318 | error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{ | ||
| 77319 | @tagName(air_tag), | ||
| 77320 | ty.fmt(pt), | ||
| 77321 | op.tracking(cg), | ||
| 77322 | }), | ||
| 77323 | else => |e| return e, | ||
| 77324 | }; | ||
| 77325 | }, | ||
| 77326 | } | ||
| 77327 | res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err; | ||
| 77328 | }, | ||
| 77238 | }) catch |err| switch (err) { | 77329 | }) catch |err| switch (err) { |
| 77239 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ | 77330 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ |
| 77240 | @tagName(air_tag), | 77331 | @tagName(air_tag), |
| 77241 | cg.typeOf(bin_op.lhs).fmt(pt), | 77332 | ty.fmt(pt), |
| 77242 | ops[0].tracking(cg), | 77333 | ops[0].tracking(cg), |
| 77243 | ops[1].tracking(cg), | 77334 | ops[1].tracking(cg), |
| 77244 | }), | 77335 | }), |
| ... | @@ -92468,7 +92559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92468,7 +92559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92468 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, | 92559 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, |
| 92469 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, | 92560 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, |
| 92470 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92561 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92471 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ }, | 92562 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ }, |
| 92472 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, | 92563 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, |
| 92473 | .{ ._, ._r, .sa, .tmp0q, .ui(63), ._, ._ }, | 92564 | .{ ._, ._r, .sa, .tmp0q, .ui(63), ._, ._ }, |
| 92474 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, | 92565 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, |
| ... | @@ -92500,7 +92591,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92500,7 +92591,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92500 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, | 92591 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, |
| 92501 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, | 92592 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, |
| 92502 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92593 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92503 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ }, | 92594 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ }, |
| 92504 | .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, | 92595 | .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, |
| 92505 | .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, | 92596 | .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, |
| 92506 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, | 92597 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, |
| ... | @@ -92534,7 +92625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92534,7 +92625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92534 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, | 92625 | .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ }, |
| 92535 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, | 92626 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, |
| 92536 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92627 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92537 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -8), ._, ._ }, | 92628 | .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -8), ._, ._ }, |
| 92538 | .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, | 92629 | .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, |
| 92539 | .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, | 92630 | .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ }, |
| 92540 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, | 92631 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, |
| ... | @@ -92595,7 +92686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92595,7 +92686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92595 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, | 92686 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, |
| 92596 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92687 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92597 | .{ ._, ._, .mov, .tmp2d, .sa(.dst0, .add_bit_size_rem_64), ._, ._ }, | 92688 | .{ ._, ._, .mov, .tmp2d, .sa(.dst0, .add_bit_size_rem_64), ._, ._ }, |
| 92598 | .{ ._, ._, .bzhi, .tmp2q, .memad(.src0q, .add_size, -16), .tmp2q, ._ }, | 92689 | .{ ._, ._, .bzhi, .tmp2q, .memad(.src0q, .add_dst0_size, -16), .tmp2q, ._ }, |
| 92599 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp2q, ._, ._ }, | 92690 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp2q, ._, ._ }, |
| 92600 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ }, | 92691 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ }, |
| 92601 | } }, | 92692 | } }, |
| ... | @@ -92627,7 +92718,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92627,7 +92718,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92627 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, | 92718 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, |
| 92628 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92719 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92629 | .{ ._, ._, .mov, .tmp2d, .sa(.dst0, .add_bit_size_rem_64), ._, ._ }, | 92720 | .{ ._, ._, .mov, .tmp2d, .sa(.dst0, .add_bit_size_rem_64), ._, ._ }, |
| 92630 | .{ ._, ._, .bzhi, .tmp2q, .memad(.src0q, .add_size, -8), .tmp2q, ._ }, | 92721 | .{ ._, ._, .bzhi, .tmp2q, .memad(.src0q, .add_dst0_size, -8), .tmp2q, ._ }, |
| 92631 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ }, | 92722 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ }, |
| 92632 | } }, | 92723 | } }, |
| 92633 | }, .{ | 92724 | }, .{ |
| ... | @@ -92658,7 +92749,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92658,7 +92749,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92658 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, | 92749 | .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ }, |
| 92659 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92750 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92660 | .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ }, | 92751 | .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ }, |
| 92661 | .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ }, | 92752 | .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ }, |
| 92662 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, | 92753 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ }, |
| 92663 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ }, | 92754 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ }, |
| 92664 | } }, | 92755 | } }, |
| ... | @@ -92690,7 +92781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -92690,7 +92781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 92690 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, | 92781 | .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ }, |
| 92691 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, | 92782 | .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ }, |
| 92692 | .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ }, | 92783 | .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ }, |
| 92693 | .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_size, -8), ._, ._ }, | 92784 | .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_dst0_size, -8), ._, ._ }, |
| 92694 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, | 92785 | .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ }, |
| 92695 | } }, | 92786 | } }, |
| 92696 | }, .{ | 92787 | }, .{ |
| ... | @@ -162356,6 +162447,136 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -162356,6 +162447,136 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 162356 | .each = .{ .once = &.{ | 162447 | .each = .{ .once = &.{ |
| 162357 | .{ ._, ._, .mov, .leasi(.src0w, .@"2", .src1), .src2w, ._, ._ }, | 162448 | .{ ._, ._, .mov, .leasi(.src0w, .@"2", .src1), .src2w, ._, ._ }, |
| 162358 | } }, | 162449 | } }, |
| 162450 | }, .{ | ||
| 162451 | .required_features = .{ .avx, null, null, null }, | ||
| 162452 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162453 | .patterns = &.{ | ||
| 162454 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162455 | }, | ||
| 162456 | .each = .{ .once = &.{ | ||
| 162457 | .{ ._, .vp_w, .extr, .leaa(.src0w, .add_src0_elem_size_mul_src1), .src2x, .ui(0), ._ }, | ||
| 162458 | } }, | ||
| 162459 | }, .{ | ||
| 162460 | .required_features = .{ .sse4_1, null, null, null }, | ||
| 162461 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162462 | .patterns = &.{ | ||
| 162463 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162464 | }, | ||
| 162465 | .each = .{ .once = &.{ | ||
| 162466 | .{ ._, .p_w, .extr, .leaa(.src0w, .add_src0_elem_size_mul_src1), .src2x, .ui(0), ._ }, | ||
| 162467 | } }, | ||
| 162468 | }, .{ | ||
| 162469 | .required_features = .{ .sse2, null, null, null }, | ||
| 162470 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162471 | .patterns = &.{ | ||
| 162472 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162473 | }, | ||
| 162474 | .extra_temps = .{ | ||
| 162475 | .{ .type = .f16, .kind = .{ .rc = .general_purpose } }, | ||
| 162476 | .unused, | ||
| 162477 | .unused, | ||
| 162478 | .unused, | ||
| 162479 | .unused, | ||
| 162480 | .unused, | ||
| 162481 | .unused, | ||
| 162482 | .unused, | ||
| 162483 | .unused, | ||
| 162484 | .unused, | ||
| 162485 | .unused, | ||
| 162486 | }, | ||
| 162487 | .each = .{ .once = &.{ | ||
| 162488 | .{ ._, .p_w, .extr, .tmp0d, .src2x, .ui(0), ._ }, | ||
| 162489 | .{ ._, ._, .mov, .leaa(.src0w, .add_src0_elem_size_mul_src1), .tmp0w, ._, ._ }, | ||
| 162490 | } }, | ||
| 162491 | }, .{ | ||
| 162492 | .required_features = .{ .sse, null, null, null }, | ||
| 162493 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162494 | .patterns = &.{ | ||
| 162495 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162496 | }, | ||
| 162497 | .extra_temps = .{ | ||
| 162498 | .{ .type = .f32, .kind = .mem }, | ||
| 162499 | .{ .type = .f16, .kind = .{ .rc = .general_purpose } }, | ||
| 162500 | .unused, | ||
| 162501 | .unused, | ||
| 162502 | .unused, | ||
| 162503 | .unused, | ||
| 162504 | .unused, | ||
| 162505 | .unused, | ||
| 162506 | .unused, | ||
| 162507 | .unused, | ||
| 162508 | .unused, | ||
| 162509 | }, | ||
| 162510 | .each = .{ .once = &.{ | ||
| 162511 | .{ ._, ._ss, .mov, .mem(.tmp1d), .src2x, ._, ._ }, | ||
| 162512 | .{ ._, ._, .mov, .tmp1d, .mem(.tmp1d), ._, ._ }, | ||
| 162513 | .{ ._, ._, .mov, .leaa(.src0w, .add_src0_elem_size_mul_src1), .tmp1w, ._, ._ }, | ||
| 162514 | } }, | ||
| 162515 | }, .{ | ||
| 162516 | .required_features = .{ .avx, null, null, null }, | ||
| 162517 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162518 | .patterns = &.{ | ||
| 162519 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162520 | }, | ||
| 162521 | .each = .{ .once = &.{ | ||
| 162522 | .{ ._, .vp_w, .extr, .leasi(.src0w, .@"2", .src1), .src2x, .ui(0), ._ }, | ||
| 162523 | } }, | ||
| 162524 | }, .{ | ||
| 162525 | .required_features = .{ .sse4_1, null, null, null }, | ||
| 162526 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162527 | .patterns = &.{ | ||
| 162528 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162529 | }, | ||
| 162530 | .each = .{ .once = &.{ | ||
| 162531 | .{ ._, .p_w, .extr, .leasi(.src0w, .@"2", .src1), .src2x, .ui(0), ._ }, | ||
| 162532 | } }, | ||
| 162533 | }, .{ | ||
| 162534 | .required_features = .{ .sse2, null, null, null }, | ||
| 162535 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162536 | .patterns = &.{ | ||
| 162537 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162538 | }, | ||
| 162539 | .extra_temps = .{ | ||
| 162540 | .{ .type = .f16, .kind = .{ .rc = .general_purpose } }, | ||
| 162541 | .unused, | ||
| 162542 | .unused, | ||
| 162543 | .unused, | ||
| 162544 | .unused, | ||
| 162545 | .unused, | ||
| 162546 | .unused, | ||
| 162547 | .unused, | ||
| 162548 | .unused, | ||
| 162549 | .unused, | ||
| 162550 | .unused, | ||
| 162551 | }, | ||
| 162552 | .each = .{ .once = &.{ | ||
| 162553 | .{ ._, .p_w, .extr, .tmp0d, .src2x, .ui(0), ._ }, | ||
| 162554 | .{ ._, ._, .mov, .leasi(.src0w, .@"2", .src1), .tmp0w, ._, ._ }, | ||
| 162555 | } }, | ||
| 162556 | }, .{ | ||
| 162557 | .required_features = .{ .sse, null, null, null }, | ||
| 162558 | .src_constraints = .{ .any, .any, .{ .float = .word } }, | ||
| 162559 | .patterns = &.{ | ||
| 162560 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162561 | }, | ||
| 162562 | .extra_temps = .{ | ||
| 162563 | .{ .type = .f32, .kind = .mem }, | ||
| 162564 | .{ .type = .f16, .kind = .{ .rc = .general_purpose } }, | ||
| 162565 | .unused, | ||
| 162566 | .unused, | ||
| 162567 | .unused, | ||
| 162568 | .unused, | ||
| 162569 | .unused, | ||
| 162570 | .unused, | ||
| 162571 | .unused, | ||
| 162572 | .unused, | ||
| 162573 | .unused, | ||
| 162574 | }, | ||
| 162575 | .each = .{ .once = &.{ | ||
| 162576 | .{ ._, ._ss, .mov, .mem(.tmp1d), .src2x, ._, ._ }, | ||
| 162577 | .{ ._, ._, .mov, .tmp1d, .mem(.tmp1d), ._, ._ }, | ||
| 162578 | .{ ._, ._, .mov, .leasi(.src0w, .@"2", .src1), .tmp1w, ._, ._ }, | ||
| 162579 | } }, | ||
| 162359 | }, .{ | 162580 | }, .{ |
| 162360 | .src_constraints = .{ .any, .any, .{ .int = .dword } }, | 162581 | .src_constraints = .{ .any, .any, .{ .int = .dword } }, |
| 162361 | .patterns = &.{ | 162582 | .patterns = &.{ |
| ... | @@ -162374,30 +162595,120 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -162374,30 +162595,120 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 162374 | .each = .{ .once = &.{ | 162595 | .each = .{ .once = &.{ |
| 162375 | .{ ._, ._, .mov, .leasi(.src0d, .@"4", .src1), .src2d, ._, ._ }, | 162596 | .{ ._, ._, .mov, .leasi(.src0d, .@"4", .src1), .src2d, ._, ._ }, |
| 162376 | } }, | 162597 | } }, |
| 162598 | }, .{ | ||
| 162599 | .required_features = .{ .avx, null, null, null }, | ||
| 162600 | .src_constraints = .{ .any, .any, .{ .float = .dword } }, | ||
| 162601 | .patterns = &.{ | ||
| 162602 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162603 | }, | ||
| 162604 | .each = .{ .once = &.{ | ||
| 162605 | .{ ._, .v_ss, .mov, .leaa(.src0d, .add_src0_elem_size_mul_src1), .src2x, ._, ._ }, | ||
| 162606 | } }, | ||
| 162607 | }, .{ | ||
| 162608 | .required_features = .{ .sse, null, null, null }, | ||
| 162609 | .src_constraints = .{ .any, .any, .{ .float = .dword } }, | ||
| 162610 | .patterns = &.{ | ||
| 162611 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162612 | }, | ||
| 162613 | .each = .{ .once = &.{ | ||
| 162614 | .{ ._, ._ss, .mov, .leaa(.src0d, .add_src0_elem_size_mul_src1), .src2x, ._, ._ }, | ||
| 162615 | } }, | ||
| 162616 | }, .{ | ||
| 162617 | .required_features = .{ .avx, null, null, null }, | ||
| 162618 | .src_constraints = .{ .any, .any, .{ .float = .dword } }, | ||
| 162619 | .patterns = &.{ | ||
| 162620 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162621 | }, | ||
| 162622 | .each = .{ .once = &.{ | ||
| 162623 | .{ ._, .v_ss, .mov, .leasi(.src0d, .@"4", .src1), .src2x, ._, ._ }, | ||
| 162624 | } }, | ||
| 162625 | }, .{ | ||
| 162626 | .required_features = .{ .sse, null, null, null }, | ||
| 162627 | .src_constraints = .{ .any, .any, .{ .float = .dword } }, | ||
| 162628 | .patterns = &.{ | ||
| 162629 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162630 | }, | ||
| 162631 | .each = .{ .once = &.{ | ||
| 162632 | .{ ._, ._ss, .mov, .leasi(.src0d, .@"4", .src1), .src2x, ._, ._ }, | ||
| 162633 | } }, | ||
| 162377 | }, .{ | 162634 | }, .{ |
| 162378 | .required_features = .{ .@"64bit", null, null, null }, | 162635 | .required_features = .{ .@"64bit", null, null, null }, |
| 162379 | .dst_constraints = .{ .{ .int = .qword }, .any }, | 162636 | .src_constraints = .{ .any, .any, .{ .int = .qword } }, |
| 162380 | .patterns = &.{ | 162637 | .patterns = &.{ |
| 162381 | .{ .src = .{ .to_mem, .simm32, .simm32 } }, | 162638 | .{ .src = .{ .to_gpr, .simm32, .simm32 } }, |
| 162382 | .{ .src = .{ .to_mem, .simm32, .to_gpr } }, | 162639 | .{ .src = .{ .to_gpr, .simm32, .to_gpr } }, |
| 162383 | }, | 162640 | }, |
| 162384 | .each = .{ .once = &.{ | 162641 | .each = .{ .once = &.{ |
| 162385 | .{ ._, ._, .mov, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2q, ._, ._ }, | 162642 | .{ ._, ._, .mov, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2q, ._, ._ }, |
| 162386 | } }, | 162643 | } }, |
| 162387 | }, .{ | 162644 | }, .{ |
| 162388 | .required_features = .{ .@"64bit", null, null, null }, | 162645 | .required_features = .{ .@"64bit", null, null, null }, |
| 162389 | .dst_constraints = .{ .{ .int = .qword }, .any }, | 162646 | .src_constraints = .{ .any, .any, .{ .int = .qword } }, |
| 162390 | .patterns = &.{ | 162647 | .patterns = &.{ |
| 162391 | .{ .src = .{ .to_mem, .to_gpr, .simm32 } }, | 162648 | .{ .src = .{ .to_gpr, .to_gpr, .simm32 } }, |
| 162392 | .{ .src = .{ .to_mem, .to_gpr, .to_gpr } }, | 162649 | .{ .src = .{ .to_gpr, .to_gpr, .to_gpr } }, |
| 162393 | }, | 162650 | }, |
| 162394 | .each = .{ .once = &.{ | 162651 | .each = .{ .once = &.{ |
| 162395 | .{ ._, ._, .mov, .leasi(.src0q, .@"8", .src1), .src2q, ._, ._ }, | 162652 | .{ ._, ._, .mov, .leasi(.src0q, .@"8", .src1), .src2q, ._, ._ }, |
| 162396 | } }, | 162653 | } }, |
| 162654 | }, .{ | ||
| 162655 | .required_features = .{ .avx, null, null, null }, | ||
| 162656 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162657 | .patterns = &.{ | ||
| 162658 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162659 | }, | ||
| 162660 | .each = .{ .once = &.{ | ||
| 162661 | .{ ._, .v_sd, .mov, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2x, ._, ._ }, | ||
| 162662 | } }, | ||
| 162663 | }, .{ | ||
| 162664 | .required_features = .{ .sse2, null, null, null }, | ||
| 162665 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162666 | .patterns = &.{ | ||
| 162667 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162668 | }, | ||
| 162669 | .each = .{ .once = &.{ | ||
| 162670 | .{ ._, ._sd, .mov, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2x, ._, ._ }, | ||
| 162671 | } }, | ||
| 162672 | }, .{ | ||
| 162673 | .required_features = .{ .sse, null, null, null }, | ||
| 162674 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162675 | .patterns = &.{ | ||
| 162676 | .{ .src = .{ .to_gpr, .simm32, .to_sse } }, | ||
| 162677 | }, | ||
| 162678 | .each = .{ .once = &.{ | ||
| 162679 | .{ ._, ._ps, .movl, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2x, ._, ._ }, | ||
| 162680 | } }, | ||
| 162681 | }, .{ | ||
| 162682 | .required_features = .{ .avx, null, null, null }, | ||
| 162683 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162684 | .patterns = &.{ | ||
| 162685 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162686 | }, | ||
| 162687 | .each = .{ .once = &.{ | ||
| 162688 | .{ ._, .v_sd, .mov, .leasi(.src0q, .@"8", .src1), .src2x, ._, ._ }, | ||
| 162689 | } }, | ||
| 162690 | }, .{ | ||
| 162691 | .required_features = .{ .sse2, null, null, null }, | ||
| 162692 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162693 | .patterns = &.{ | ||
| 162694 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162695 | }, | ||
| 162696 | .each = .{ .once = &.{ | ||
| 162697 | .{ ._, ._sd, .mov, .leasi(.src0q, .@"8", .src1), .src2x, ._, ._ }, | ||
| 162698 | } }, | ||
| 162699 | }, .{ | ||
| 162700 | .required_features = .{ .sse, null, null, null }, | ||
| 162701 | .src_constraints = .{ .any, .any, .{ .float = .qword } }, | ||
| 162702 | .patterns = &.{ | ||
| 162703 | .{ .src = .{ .to_gpr, .to_gpr, .to_sse } }, | ||
| 162704 | }, | ||
| 162705 | .each = .{ .once = &.{ | ||
| 162706 | .{ ._, ._ps, .movl, .leasi(.src0q, .@"8", .src1), .src2x, ._, ._ }, | ||
| 162707 | } }, | ||
| 162397 | } }) catch |err| switch (err) { | 162708 | } }) catch |err| switch (err) { |
| 162398 | error.SelectFailed => { | 162709 | error.SelectFailed => { |
| 162399 | const elem_size = cg.typeOf(bin_op.rhs).abiSize(zcu); | 162710 | const elem_size = cg.typeOf(bin_op.rhs).abiSize(zcu); |
| 162400 | while (try ops[0].toBase(false, cg) or | 162711 | while (try ops[0].toRegClass(true, .general_purpose, cg) or |
| 162401 | try ops[1].toRegClass(true, .general_purpose, cg)) | 162712 | try ops[1].toRegClass(true, .general_purpose, cg)) |
| 162402 | {} | 162713 | {} |
| 162403 | const base_reg = ops[0].tracking(cg).short.register.to64(); | 162714 | const base_reg = ops[0].tracking(cg).short.register.to64(); |
| ... | @@ -162410,11 +162721,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -162410,11 +162721,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 162410 | rhs_reg, | 162721 | rhs_reg, |
| 162411 | .u(elem_size), | 162722 | .u(elem_size), |
| 162412 | ); | 162723 | ); |
| 162413 | try cg.asmRegisterMemory( | 162724 | try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{ |
| 162414 | .{ ._, .lea }, | 162725 | .base = .{ .reg = base_reg }, |
| 162415 | base_reg, | 162726 | .mod = .{ .rm = .{ .index = rhs_reg } }, |
| 162416 | try ops[0].tracking(cg).short.mem(cg, .{ .index = rhs_reg }), | 162727 | }); |
| 162417 | ); | ||
| 162418 | } else if (elem_size > 8) { | 162728 | } else if (elem_size > 8) { |
| 162419 | try cg.spillEflagsIfOccupied(); | 162729 | try cg.spillEflagsIfOccupied(); |
| 162420 | try cg.asmRegisterImmediate( | 162730 | try cg.asmRegisterImmediate( |
| ... | @@ -162422,20 +162732,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -162422,20 +162732,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 162422 | rhs_reg, | 162732 | rhs_reg, |
| 162423 | .u(std.math.log2_int(u64, elem_size)), | 162733 | .u(std.math.log2_int(u64, elem_size)), |
| 162424 | ); | 162734 | ); |
| 162425 | try cg.asmRegisterMemory( | 162735 | try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{ |
| 162426 | .{ ._, .lea }, | 162736 | .base = .{ .reg = base_reg }, |
| 162427 | base_reg, | 162737 | .mod = .{ .rm = .{ .index = rhs_reg } }, |
| 162428 | try ops[0].tracking(cg).short.mem(cg, .{ .index = rhs_reg }), | 162738 | }); |
| 162429 | ); | 162739 | } else try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{ |
| 162430 | } else try cg.asmRegisterMemory( | 162740 | .base = .{ .reg = base_reg }, |
| 162431 | .{ ._, .lea }, | 162741 | .mod = .{ .rm = .{ |
| 162432 | base_reg, | ||
| 162433 | try ops[0].tracking(cg).short.mem(cg, .{ | ||
| 162434 | .index = rhs_reg, | 162742 | .index = rhs_reg, |
| 162435 | .scale = .fromFactor(@intCast(elem_size)), | 162743 | .scale = .fromFactor(@intCast(elem_size)), |
| 162436 | }), | 162744 | } }, |
| 162437 | ); | 162745 | }); |
| 162438 | try ops[0].store(&ops[1], .{}, cg); | 162746 | try ops[0].store(&ops[2], .{}, cg); |
| 162439 | }, | 162747 | }, |
| 162440 | else => |e| return e, | 162748 | else => |e| return e, |
| 162441 | }; | 162749 | }; |
| ... | @@ -165315,9 +165623,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -165315,9 +165623,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 165315 | .ty = mask_ty.toIntern(), | 165623 | .ty = mask_ty.toIntern(), |
| 165316 | .storage = .{ .elems = &([1]InternPool.Index{ | 165624 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 165317 | (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(), | 165625 | (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(), |
| 165318 | } ++ [1]InternPool.Index{ | 165626 | } ++ [1]InternPool.Index{.zero_u8} ** 15) }, |
| 165319 | (try pt.intValue(.u8, 0)).toIntern(), | ||
| 165320 | } ** 15) }, | ||
| 165321 | } }))); | 165627 | } }))); |
| 165322 | const mask_addr_reg = try self.copyToTmpRegister(.usize, mask_mcv.address()); | 165628 | const mask_addr_reg = try self.copyToTmpRegister(.usize, mask_mcv.address()); |
| 165323 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); | 165629 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); |
| ... | @@ -168138,7 +168444,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE | ... | @@ -168138,7 +168444,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE |
| 168138 | .register_quadruple, | 168444 | .register_quadruple, |
| 168139 | .register_overflow, | 168445 | .register_overflow, |
| 168140 | .register_mask, | 168446 | .register_mask, |
| 168141 | .elementwise_regs_then_frame, | 168447 | .elementwise_args, |
| 168142 | .reserved_frame, | 168448 | .reserved_frame, |
| 168143 | => unreachable, // not a valid pointer | 168449 | => unreachable, // not a valid pointer |
| 168144 | .immediate, | 168450 | .immediate, |
| ... | @@ -168356,7 +168662,7 @@ fn store( | ... | @@ -168356,7 +168662,7 @@ fn store( |
| 168356 | .register_quadruple, | 168662 | .register_quadruple, |
| 168357 | .register_overflow, | 168663 | .register_overflow, |
| 168358 | .register_mask, | 168664 | .register_mask, |
| 168359 | .elementwise_regs_then_frame, | 168665 | .elementwise_args, |
| 168360 | .reserved_frame, | 168666 | .reserved_frame, |
| 168361 | => unreachable, // not a valid pointer | 168667 | => unreachable, // not a valid pointer |
| 168362 | .immediate, | 168668 | .immediate, |
| ... | @@ -168842,7 +169148,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: | ... | @@ -168842,7 +169148,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: |
| 168842 | .lea_direct, | 169148 | .lea_direct, |
| 168843 | .lea_got, | 169149 | .lea_got, |
| 168844 | .lea_frame, | 169150 | .lea_frame, |
| 168845 | .elementwise_regs_then_frame, | 169151 | .elementwise_args, |
| 168846 | .reserved_frame, | 169152 | .reserved_frame, |
| 168847 | .air_ref, | 169153 | .air_ref, |
| 168848 | => unreachable, // unmodifiable destination | 169154 | => unreachable, // unmodifiable destination |
| ... | @@ -170513,7 +170819,7 @@ fn genBinOp( | ... | @@ -170513,7 +170819,7 @@ fn genBinOp( |
| 170513 | .load_got, | 170819 | .load_got, |
| 170514 | .lea_got, | 170820 | .lea_got, |
| 170515 | .lea_frame, | 170821 | .lea_frame, |
| 170516 | .elementwise_regs_then_frame, | 170822 | .elementwise_args, |
| 170517 | .reserved_frame, | 170823 | .reserved_frame, |
| 170518 | .air_ref, | 170824 | .air_ref, |
| 170519 | => unreachable, | 170825 | => unreachable, |
| ... | @@ -171696,7 +172002,7 @@ fn genBinOpMir( | ... | @@ -171696,7 +172002,7 @@ fn genBinOpMir( |
| 171696 | .lea_got, | 172002 | .lea_got, |
| 171697 | .lea_frame, | 172003 | .lea_frame, |
| 171698 | .lea_symbol, | 172004 | .lea_symbol, |
| 171699 | .elementwise_regs_then_frame, | 172005 | .elementwise_args, |
| 171700 | .reserved_frame, | 172006 | .reserved_frame, |
| 171701 | .air_ref, | 172007 | .air_ref, |
| 171702 | => unreachable, // unmodifiable destination | 172008 | => unreachable, // unmodifiable destination |
| ... | @@ -171732,7 +172038,7 @@ fn genBinOpMir( | ... | @@ -171732,7 +172038,7 @@ fn genBinOpMir( |
| 171732 | .undef, | 172038 | .undef, |
| 171733 | .register_overflow, | 172039 | .register_overflow, |
| 171734 | .register_mask, | 172040 | .register_mask, |
| 171735 | .elementwise_regs_then_frame, | 172041 | .elementwise_args, |
| 171736 | .reserved_frame, | 172042 | .reserved_frame, |
| 171737 | => unreachable, | 172043 | => unreachable, |
| 171738 | .register, | 172044 | .register, |
| ... | @@ -171892,7 +172198,7 @@ fn genBinOpMir( | ... | @@ -171892,7 +172198,7 @@ fn genBinOpMir( |
| 171892 | .undef, | 172198 | .undef, |
| 171893 | .register_overflow, | 172199 | .register_overflow, |
| 171894 | .register_mask, | 172200 | .register_mask, |
| 171895 | .elementwise_regs_then_frame, | 172201 | .elementwise_args, |
| 171896 | .reserved_frame, | 172202 | .reserved_frame, |
| 171897 | .air_ref, | 172203 | .air_ref, |
| 171898 | => unreachable, | 172204 | => unreachable, |
| ... | @@ -171988,7 +172294,7 @@ fn genBinOpMir( | ... | @@ -171988,7 +172294,7 @@ fn genBinOpMir( |
| 171988 | .undef, | 172294 | .undef, |
| 171989 | .register_overflow, | 172295 | .register_overflow, |
| 171990 | .register_mask, | 172296 | .register_mask, |
| 171991 | .elementwise_regs_then_frame, | 172297 | .elementwise_args, |
| 171992 | .reserved_frame, | 172298 | .reserved_frame, |
| 171993 | .air_ref, | 172299 | .air_ref, |
| 171994 | => unreachable, | 172300 | => unreachable, |
| ... | @@ -172119,7 +172425,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv | ... | @@ -172119,7 +172425,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv |
| 172119 | .lea_direct, | 172425 | .lea_direct, |
| 172120 | .lea_got, | 172426 | .lea_got, |
| 172121 | .lea_frame, | 172427 | .lea_frame, |
| 172122 | .elementwise_regs_then_frame, | 172428 | .elementwise_args, |
| 172123 | .reserved_frame, | 172429 | .reserved_frame, |
| 172124 | .air_ref, | 172430 | .air_ref, |
| 172125 | => unreachable, // unmodifiable destination | 172431 | => unreachable, // unmodifiable destination |
| ... | @@ -172151,7 +172457,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv | ... | @@ -172151,7 +172457,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv |
| 172151 | .register_quadruple, | 172457 | .register_quadruple, |
| 172152 | .register_overflow, | 172458 | .register_overflow, |
| 172153 | .register_mask, | 172459 | .register_mask, |
| 172154 | .elementwise_regs_then_frame, | 172460 | .elementwise_args, |
| 172155 | .reserved_frame, | 172461 | .reserved_frame, |
| 172156 | .air_ref, | 172462 | .air_ref, |
| 172157 | => unreachable, | 172463 | => unreachable, |
| ... | @@ -172271,7 +172577,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -172271,7 +172577,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172271 | try self.genCopy(arg_ty, dst_mcv, src_mcv, .{}); | 172577 | try self.genCopy(arg_ty, dst_mcv, src_mcv, .{}); |
| 172272 | break :result dst_mcv; | 172578 | break :result dst_mcv; |
| 172273 | }, | 172579 | }, |
| 172274 | .elementwise_regs_then_frame => |regs_frame_addr| { | 172580 | .elementwise_args => |regs_frame_addr| { |
| 172275 | try self.spillEflagsIfOccupied(); | 172581 | try self.spillEflagsIfOccupied(); |
| 172276 | 172582 | ||
| 172277 | const fn_info = zcu.typeToFunc(self.fn_type).?; | 172583 | const fn_info = zcu.typeToFunc(self.fn_type).?; |
| ... | @@ -172375,7 +172681,7 @@ fn genLocalDebugInfo( | ... | @@ -172375,7 +172681,7 @@ fn genLocalDebugInfo( |
| 172375 | .arg, .dbg_arg_inline, .dbg_var_val => |tag| { | 172681 | .arg, .dbg_arg_inline, .dbg_var_val => |tag| { |
| 172376 | switch (mcv) { | 172682 | switch (mcv) { |
| 172377 | .none => try self.asmAir(.dbg_local, inst), | 172683 | .none => try self.asmAir(.dbg_local, inst), |
| 172378 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, | 172684 | .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable, |
| 172379 | .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)), | 172685 | .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)), |
| 172380 | .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr), | 172686 | .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr), |
| 172381 | .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)), | 172687 | .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)), |
| ... | @@ -172398,7 +172704,7 @@ fn genLocalDebugInfo( | ... | @@ -172398,7 +172704,7 @@ fn genLocalDebugInfo( |
| 172398 | }, | 172704 | }, |
| 172399 | .dbg_var_ptr => switch (mcv) { | 172705 | .dbg_var_ptr => switch (mcv) { |
| 172400 | else => unreachable, | 172706 | else => unreachable, |
| 172401 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, | 172707 | .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable, |
| 172402 | .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{ | 172708 | .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{ |
| 172403 | .base = .{ .frame = frame_addr.index }, | 172709 | .base = .{ .frame = frame_addr.index }, |
| 172404 | .mod = .{ .rm = .{ | 172710 | .mod = .{ .rm = .{ |
| ... | @@ -172567,7 +172873,7 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -172567,7 +172873,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 172567 | try self.genCopy(arg_ty, dst_arg, src_arg, opts); | 172873 | try self.genCopy(arg_ty, dst_arg, src_arg, opts); |
| 172568 | try self.freeValue(src_arg); | 172874 | try self.freeValue(src_arg); |
| 172569 | }, | 172875 | }, |
| 172570 | .elementwise_regs_then_frame => |regs_frame_addr| { | 172876 | .elementwise_args => |regs_frame_addr| { |
| 172571 | const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 172877 | const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 172572 | const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); | 172878 | const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); |
| 172573 | defer self.register_manager.unlockReg(index_lock); | 172879 | defer self.register_manager.unlockReg(index_lock); |
| ... | @@ -172676,7 +172982,7 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -172676,7 +172982,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 172676 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{ | 172982 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{ |
| 172677 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 172983 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 172678 | }, .{}), | 172984 | }, .{}), |
| 172679 | .elementwise_regs_then_frame => |regs_frame_addr| { | 172985 | .elementwise_args => |regs_frame_addr| { |
| 172680 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ | 172986 | const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{ |
| 172681 | .base = .{ .reg = try self.copyToTmpRegister( | 172987 | .base = .{ .reg = try self.copyToTmpRegister( |
| 172682 | .usize, | 172988 | .usize, |
| ... | @@ -173064,7 +173370,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -173064,7 +173370,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 173064 | .lea_got, | 173370 | .lea_got, |
| 173065 | .lea_frame, | 173371 | .lea_frame, |
| 173066 | .lea_symbol, | 173372 | .lea_symbol, |
| 173067 | .elementwise_regs_then_frame, | 173373 | .elementwise_args, |
| 173068 | .reserved_frame, | 173374 | .reserved_frame, |
| 173069 | .air_ref, | 173375 | .air_ref, |
| 173070 | => unreachable, | 173376 | => unreachable, |
| ... | @@ -173119,7 +173425,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v | ... | @@ -173119,7 +173425,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v |
| 173119 | .lea_direct, | 173425 | .lea_direct, |
| 173120 | .lea_got, | 173426 | .lea_got, |
| 173121 | .lea_frame, | 173427 | .lea_frame, |
| 173122 | .elementwise_regs_then_frame, | 173428 | .elementwise_args, |
| 173123 | .reserved_frame, | 173429 | .reserved_frame, |
| 173124 | .air_ref, | 173430 | .air_ref, |
| 173125 | => unreachable, | 173431 | => unreachable, |
| ... | @@ -173524,7 +173830,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) | ... | @@ -173524,7 +173830,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) |
| 173524 | .lea_direct, | 173830 | .lea_direct, |
| 173525 | .lea_got, | 173831 | .lea_got, |
| 173526 | .lea_symbol, | 173832 | .lea_symbol, |
| 173527 | .elementwise_regs_then_frame, | 173833 | .elementwise_args, |
| 173528 | .reserved_frame, | 173834 | .reserved_frame, |
| 173529 | .air_ref, | 173835 | .air_ref, |
| 173530 | => unreachable, | 173836 | => unreachable, |
| ... | @@ -173868,17 +174174,23 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index | ... | @@ -173868,17 +174174,23 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index |
| 173868 | var block_data = self.blocks.fetchRemove(inst).?; | 174174 | var block_data = self.blocks.fetchRemove(inst).?; |
| 173869 | defer block_data.value.deinit(self.gpa); | 174175 | defer block_data.value.deinit(self.gpa); |
| 173870 | if (block_data.value.relocs.items.len > 0) { | 174176 | if (block_data.value.relocs.items.len > 0) { |
| 174177 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); | ||
| 174178 | while (block_data.value.relocs.getLastOrNull() == last_inst) { | ||
| 174179 | block_data.value.relocs.items.len -= 1; | ||
| 174180 | self.mir_instructions.set(last_inst, .{ | ||
| 174181 | .tag = .pseudo, | ||
| 174182 | .ops = .pseudo_dead_none, | ||
| 174183 | .data = undefined, | ||
| 174184 | }); | ||
| 174185 | last_inst -= 1; | ||
| 174186 | } | ||
| 174187 | for (block_data.value.relocs.items) |block_reloc| self.performReloc(block_reloc); | ||
| 173871 | try self.restoreState(block_data.value.state, liveness.deaths, .{ | 174188 | try self.restoreState(block_data.value.state, liveness.deaths, .{ |
| 173872 | .emit_instructions = false, | 174189 | .emit_instructions = false, |
| 173873 | .update_tracking = true, | 174190 | .update_tracking = true, |
| 173874 | .resurrect = true, | 174191 | .resurrect = true, |
| 173875 | .close_scope = true, | 174192 | .close_scope = true, |
| 173876 | }); | 174193 | }); |
| 173877 | const block_relocs_last_index = block_data.value.relocs.items.len - 1; | ||
| 173878 | for (if (block_data.value.relocs.items[block_relocs_last_index] == self.mir_instructions.len - 1) block_relocs: { | ||
| 173879 | _ = self.mir_instructions.pop(); | ||
| 173880 | break :block_relocs block_data.value.relocs.items[0..block_relocs_last_index]; | ||
| 173881 | } else block_data.value.relocs.items) |block_reloc| self.performReloc(block_reloc); | ||
| 173882 | } | 174194 | } |
| 173883 | 174195 | ||
| 173884 | if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i); | 174196 | if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i); |
| ... | @@ -174453,18 +174765,6 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -174453,18 +174765,6 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 174453 | try self.freeValue(block_tracking.short); | 174765 | try self.freeValue(block_tracking.short); |
| 174454 | } | 174766 | } |
| 174455 | 174767 | ||
| 174456 | fn airRepeat(self: *CodeGen, inst: Air.Inst.Index) !void { | ||
| 174457 | const loop_inst = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat.loop_inst; | ||
| 174458 | const repeat_info = self.loops.get(loop_inst).?; | ||
| 174459 | try self.restoreState(repeat_info.state, &.{}, .{ | ||
| 174460 | .emit_instructions = true, | ||
| 174461 | .update_tracking = false, | ||
| 174462 | .resurrect = false, | ||
| 174463 | .close_scope = true, | ||
| 174464 | }); | ||
| 174465 | _ = try self.asmJmpReloc(repeat_info.target); | ||
| 174466 | } | ||
| 174467 | |||
| 174468 | fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | 174768 | fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 174469 | @setEvalBranchQuota(1_100); | 174769 | @setEvalBranchQuota(1_100); |
| 174470 | const pt = self.pt; | 174770 | const pt = self.pt; |
| ... | @@ -175587,7 +175887,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C | ... | @@ -175587,7 +175887,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 175587 | .lea_got, | 175887 | .lea_got, |
| 175588 | .lea_frame, | 175888 | .lea_frame, |
| 175589 | .lea_symbol, | 175889 | .lea_symbol, |
| 175590 | .elementwise_regs_then_frame, | 175890 | .elementwise_args, |
| 175591 | .reserved_frame, | 175891 | .reserved_frame, |
| 175592 | .air_ref, | 175892 | .air_ref, |
| 175593 | => unreachable, // unmodifiable destination | 175893 | => unreachable, // unmodifiable destination |
| ... | @@ -175598,7 +175898,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C | ... | @@ -175598,7 +175898,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 175598 | .dead, | 175898 | .dead, |
| 175599 | .undef, | 175899 | .undef, |
| 175600 | .register_overflow, | 175900 | .register_overflow, |
| 175601 | .elementwise_regs_then_frame, | 175901 | .elementwise_args, |
| 175602 | .reserved_frame, | 175902 | .reserved_frame, |
| 175603 | => unreachable, | 175903 | => unreachable, |
| 175604 | .immediate, | 175904 | .immediate, |
| ... | @@ -175776,7 +176076,7 @@ fn genSetReg( | ... | @@ -175776,7 +176076,7 @@ fn genSetReg( |
| 175776 | .none, | 176076 | .none, |
| 175777 | .unreach, | 176077 | .unreach, |
| 175778 | .dead, | 176078 | .dead, |
| 175779 | .elementwise_regs_then_frame, | 176079 | .elementwise_args, |
| 175780 | .reserved_frame, | 176080 | .reserved_frame, |
| 175781 | => unreachable, | 176081 | => unreachable, |
| 175782 | .undef => if (opts.safety) switch (dst_reg.class()) { | 176082 | .undef => if (opts.safety) switch (dst_reg.class()) { |
| ... | @@ -176313,7 +176613,7 @@ fn genSetMem( | ... | @@ -176313,7 +176613,7 @@ fn genSetMem( |
| 176313 | .none, | 176613 | .none, |
| 176314 | .unreach, | 176614 | .unreach, |
| 176315 | .dead, | 176615 | .dead, |
| 176316 | .elementwise_regs_then_frame, | 176616 | .elementwise_args, |
| 176317 | .reserved_frame, | 176617 | .reserved_frame, |
| 176318 | => unreachable, | 176618 | => unreachable, |
| 176319 | .undef => if (opts.safety) try self.genInlineMemset( | 176619 | .undef => if (opts.safety) try self.genInlineMemset( |
| ... | @@ -178566,10 +178866,10 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178566,10 +178866,10 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178566 | const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() }); | 178866 | const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() }); |
| 178567 | var mask_elems_buf: [32]InternPool.Index = undefined; | 178867 | var mask_elems_buf: [32]InternPool.Index = undefined; |
| 178568 | const mask_elems = mask_elems_buf[0..vec_len]; | 178868 | const mask_elems = mask_elems_buf[0..vec_len]; |
| 178569 | for (mask_elems, 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{ | 178869 | for (mask_elems, 0..) |*elem, bit| elem.* = (try pt.intValue( |
| 178570 | .ty = mask_elem_ty.toIntern(), | 178870 | mask_elem_ty, |
| 178571 | .storage = .{ .u64 = @as(u64, 1) << @intCast(bit) }, | 178871 | @as(u8, 1) << @truncate(bit), |
| 178572 | } }); | 178872 | )).toIntern(); |
| 178573 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ | 178873 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 178574 | .ty = mask_ty.toIntern(), | 178874 | .ty = mask_ty.toIntern(), |
| 178575 | .storage = .{ .elems = mask_elems }, | 178875 | .storage = .{ .elems = mask_elems }, |
| ... | @@ -179437,16 +179737,13 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -179437,16 +179737,13 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 179437 | var lhs_mask_elems: [16]InternPool.Index = undefined; | 179737 | var lhs_mask_elems: [16]InternPool.Index = undefined; |
| 179438 | for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| { | 179738 | for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| { |
| 179439 | const elem_index = byte_index / elem_abi_size; | 179739 | const elem_index = byte_index / elem_abi_size; |
| 179440 | lhs_mask_elem.* = try pt.intern(.{ .int = .{ | 179740 | lhs_mask_elem.* = (try pt.intValue(.u8, if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { |
| 179441 | .ty = .u8_type, | 179741 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; |
| 179442 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { | 179742 | if (mask_elem < 0) break :elem 0b1_00_00000; |
| 179443 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; | 179743 | const mask_elem_index: u31 = @intCast(mask_elem); |
| 179444 | if (mask_elem < 0) break :elem 0b1_00_00000; | 179744 | const byte_off: u32 = @intCast(byte_index % elem_abi_size); |
| 179445 | const mask_elem_index: u31 = @intCast(mask_elem); | 179745 | break :elem mask_elem_index * elem_abi_size + byte_off; |
| 179446 | const byte_off: u32 = @intCast(byte_index % elem_abi_size); | 179746 | })).toIntern(); |
| 179447 | break :elem @intCast(mask_elem_index * elem_abi_size + byte_off); | ||
| 179448 | } }, | ||
| 179449 | } }); | ||
| 179450 | } | 179747 | } |
| 179451 | const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 179748 | const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 179452 | const lhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ | 179749 | const lhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| ... | @@ -179471,16 +179768,13 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -179471,16 +179768,13 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 179471 | var rhs_mask_elems: [16]InternPool.Index = undefined; | 179768 | var rhs_mask_elems: [16]InternPool.Index = undefined; |
| 179472 | for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| { | 179769 | for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| { |
| 179473 | const elem_index = byte_index / elem_abi_size; | 179770 | const elem_index = byte_index / elem_abi_size; |
| 179474 | rhs_mask_elem.* = try pt.intern(.{ .int = .{ | 179771 | rhs_mask_elem.* = (try pt.intValue(.u8, if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { |
| 179475 | .ty = .u8_type, | 179772 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; |
| 179476 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { | 179773 | if (mask_elem >= 0) break :elem 0b1_00_00000; |
| 179477 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; | 179774 | const mask_elem_index: u31 = @intCast(~mask_elem); |
| 179478 | if (mask_elem >= 0) break :elem 0b1_00_00000; | 179775 | const byte_off: u32 = @intCast(byte_index % elem_abi_size); |
| 179479 | const mask_elem_index: u31 = @intCast(~mask_elem); | 179776 | break :elem mask_elem_index * elem_abi_size + byte_off; |
| 179480 | const byte_off: u32 = @intCast(byte_index % elem_abi_size); | 179777 | })).toIntern(); |
| 179481 | break :elem @intCast(mask_elem_index * elem_abi_size + byte_off); | ||
| 179482 | } }, | ||
| 179483 | } }); | ||
| 179484 | } | 179778 | } |
| 179485 | const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 179779 | const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 179486 | const rhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ | 179780 | const rhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| ... | @@ -180611,7 +180905,7 @@ fn resolveCallingConventionValues( | ... | @@ -180611,7 +180905,7 @@ fn resolveCallingConventionValues( |
| 180611 | 180905 | ||
| 180612 | result.stack_byte_count = | 180906 | result.stack_byte_count = |
| 180613 | std.mem.alignForward(u31, result.stack_byte_count, frame_elem_align); | 180907 | std.mem.alignForward(u31, result.stack_byte_count, frame_elem_align); |
| 180614 | arg_mcv[arg_mcv_i] = .{ .elementwise_regs_then_frame = .{ | 180908 | arg_mcv[arg_mcv_i] = .{ .elementwise_args = .{ |
| 180615 | .regs = remaining_param_int_regs, | 180909 | .regs = remaining_param_int_regs, |
| 180616 | .frame_off = @intCast(result.stack_byte_count), | 180910 | .frame_off = @intCast(result.stack_byte_count), |
| 180617 | .frame_index = stack_frame_base, | 180911 | .frame_index = stack_frame_base, |
| ... | @@ -181236,7 +181530,7 @@ const Temp = struct { | ... | @@ -181236,7 +181530,7 @@ const Temp = struct { |
| 181236 | .load_got, | 181530 | .load_got, |
| 181237 | .lea_got, | 181531 | .lea_got, |
| 181238 | .lea_frame, | 181532 | .lea_frame, |
| 181239 | .elementwise_regs_then_frame, | 181533 | .elementwise_args, |
| 181240 | .reserved_frame, | 181534 | .reserved_frame, |
| 181241 | .air_ref, | 181535 | .air_ref, |
| 181242 | => false, | 181536 | => false, |
| ... | @@ -181671,7 +181965,7 @@ const Temp = struct { | ... | @@ -181671,7 +181965,7 @@ const Temp = struct { |
| 181671 | .register_quadruple, | 181965 | .register_quadruple, |
| 181672 | .register_overflow, | 181966 | .register_overflow, |
| 181673 | .register_mask, | 181967 | .register_mask, |
| 181674 | .elementwise_regs_then_frame, | 181968 | .elementwise_args, |
| 181675 | .reserved_frame, | 181969 | .reserved_frame, |
| 181676 | .air_ref, | 181970 | .air_ref, |
| 181677 | => unreachable, // not a valid pointer | 181971 | => unreachable, // not a valid pointer |
| ... | @@ -186395,19 +186689,46 @@ const Temp = struct { | ... | @@ -186395,19 +186689,46 @@ const Temp = struct { |
| 186395 | if (cg.reused_operands.isSet(op_index)) continue; | 186689 | if (cg.reused_operands.isSet(op_index)) continue; |
| 186396 | try cg.processDeath(op_ref.toIndexAllowNone() orelse continue); | 186690 | try cg.processDeath(op_ref.toIndexAllowNone() orelse continue); |
| 186397 | } | 186691 | } |
| 186398 | if (cg.liveness.isUnused(inst)) try temp.die(cg) else switch (temp.unwrap(cg)) { | 186692 | if (cg.liveness.isUnused(inst)) try temp.die(cg) else { |
| 186399 | .ref, .err_ret_trace => { | 186693 | switch (temp.unwrap(cg)) { |
| 186400 | const result = try cg.allocRegOrMem(inst, true); | 186694 | .ref, .err_ret_trace => { |
| 186401 | try cg.genCopy(cg.typeOfIndex(inst), result, temp.tracking(cg).short, .{}); | 186695 | const temp_mcv = temp.tracking(cg).short; |
| 186402 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | 186696 | const result = result: switch (temp_mcv) { |
| 186403 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); | 186697 | .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable, |
| 186404 | }, | 186698 | .undef, .immediate, .lea_frame => temp_mcv, |
| 186405 | .temp => |temp_index| { | 186699 | .eflags, |
| 186406 | const temp_tracking = temp_index.tracking(cg); | 186700 | .register, |
| 186407 | tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short }); | 186701 | .register_pair, |
| 186408 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short)); | 186702 | .register_triple, |
| 186409 | assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking)); | 186703 | .register_quadruple, |
| 186410 | }, | 186704 | .register_offset, |
| 186705 | .register_overflow, | ||
| 186706 | .register_mask, | ||
| 186707 | .memory, | ||
| 186708 | .load_symbol, | ||
| 186709 | .lea_symbol, | ||
| 186710 | .indirect, | ||
| 186711 | .load_direct, | ||
| 186712 | .lea_direct, | ||
| 186713 | .load_got, | ||
| 186714 | .lea_got, | ||
| 186715 | .load_frame, | ||
| 186716 | => { | ||
| 186717 | const result = try cg.allocRegOrMem(inst, true); | ||
| 186718 | try cg.genCopy(cg.typeOfIndex(inst), result, temp_mcv, .{}); | ||
| 186719 | break :result result; | ||
| 186720 | }, | ||
| 186721 | }; | ||
| 186722 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | ||
| 186723 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); | ||
| 186724 | }, | ||
| 186725 | .temp => |temp_index| { | ||
| 186726 | const temp_tracking = temp_index.tracking(cg); | ||
| 186727 | tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short }); | ||
| 186728 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short)); | ||
| 186729 | assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking)); | ||
| 186730 | }, | ||
| 186731 | } | ||
| 186411 | } | 186732 | } |
| 186412 | for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| { | 186733 | for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| { |
| 186413 | if (op_temp.index != temp.index) continue; | 186734 | if (op_temp.index != temp.index) continue; |
| ... | @@ -187950,6 +188271,7 @@ const Select = struct { | ... | @@ -187950,6 +188271,7 @@ const Select = struct { |
| 187950 | ptr_bit_size, | 188271 | ptr_bit_size, |
| 187951 | size, | 188272 | size, |
| 187952 | src0_size, | 188273 | src0_size, |
| 188274 | dst0_size, | ||
| 187953 | delta_size, | 188275 | delta_size, |
| 187954 | delta_elem_size, | 188276 | delta_elem_size, |
| 187955 | unaligned_size, | 188277 | unaligned_size, |
| ... | @@ -187993,6 +188315,7 @@ const Select = struct { | ... | @@ -187993,6 +188315,7 @@ const Select = struct { |
| 187993 | const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; | 188315 | const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; |
| 187994 | const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; | 188316 | const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" }; |
| 187995 | const add_8_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"8" }; | 188317 | const add_8_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"8" }; |
| 188318 | const add_dst0_size: Adjust = .{ .sign = .pos, .lhs = .dst0_size, .op = .mul, .rhs = .@"1" }; | ||
| 187996 | const add_delta_size_div_8: Adjust = .{ .sign = .pos, .lhs = .delta_size, .op = .div, .rhs = .@"8" }; | 188319 | const add_delta_size_div_8: Adjust = .{ .sign = .pos, .lhs = .delta_size, .op = .div, .rhs = .@"8" }; |
| 187997 | const add_delta_elem_size: Adjust = .{ .sign = .pos, .lhs = .delta_elem_size, .op = .mul, .rhs = .@"1" }; | 188320 | const add_delta_elem_size: Adjust = .{ .sign = .pos, .lhs = .delta_elem_size, .op = .mul, .rhs = .@"1" }; |
| 187998 | const add_delta_elem_size_div_8: Adjust = .{ .sign = .pos, .lhs = .delta_elem_size, .op = .div, .rhs = .@"8" }; | 188321 | const add_delta_elem_size_div_8: Adjust = .{ .sign = .pos, .lhs = .delta_elem_size, .op = .div, .rhs = .@"8" }; |
| ... | @@ -188788,6 +189111,7 @@ const Select = struct { | ... | @@ -188788,6 +189111,7 @@ const Select = struct { |
| 188788 | .ptr_bit_size => s.cg.target.ptrBitWidth(), | 189111 | .ptr_bit_size => s.cg.target.ptrBitWidth(), |
| 188789 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), | 189112 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 188790 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), | 189113 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 189114 | .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)), | ||
| 188791 | .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) - | 189115 | .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) - |
| 188792 | @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).abiSize(s.cg.pt.zcu)))), | 189116 | @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).abiSize(s.cg.pt.zcu)))), |
| 188793 | .delta_elem_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))) - | 189117 | .delta_elem_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))) - |
src/codegen.zig+48-10| ... | @@ -27,13 +27,27 @@ pub const CodeGenError = GenerateSymbolError || error{ | ... | @@ -27,13 +27,27 @@ pub const CodeGenError = GenerateSymbolError || error{ |
| 27 | CodegenFail, | 27 | CodegenFail, |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | fn devFeatureForBackend(comptime backend: std.builtin.CompilerBackend) dev.Feature { | 30 | fn devFeatureForBackend(backend: std.builtin.CompilerBackend) dev.Feature { |
| 31 | comptime assert(mem.startsWith(u8, @tagName(backend), "stage2_")); | 31 | return switch (backend) { |
| 32 | return @field(dev.Feature, @tagName(backend)["stage2_".len..] ++ "_backend"); | 32 | .other, .stage1 => unreachable, |
| 33 | .stage2_aarch64 => .aarch64_backend, | ||
| 34 | .stage2_arm => .arm_backend, | ||
| 35 | .stage2_c => .c_backend, | ||
| 36 | .stage2_llvm => .llvm_backend, | ||
| 37 | .stage2_powerpc => .powerpc_backend, | ||
| 38 | .stage2_riscv64 => .riscv64_backend, | ||
| 39 | .stage2_sparc64 => .sparc64_backend, | ||
| 40 | .stage2_spirv64 => .spirv64_backend, | ||
| 41 | .stage2_wasm => .wasm_backend, | ||
| 42 | .stage2_x86 => .x86_backend, | ||
| 43 | .stage2_x86_64 => .x86_64_backend, | ||
| 44 | _ => unreachable, | ||
| 45 | }; | ||
| 33 | } | 46 | } |
| 34 | 47 | ||
| 35 | pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type { | 48 | fn importBackend(comptime backend: std.builtin.CompilerBackend) type { |
| 36 | return switch (backend) { | 49 | return switch (backend) { |
| 50 | .other, .stage1 => unreachable, | ||
| 37 | .stage2_aarch64 => @import("arch/aarch64/CodeGen.zig"), | 51 | .stage2_aarch64 => @import("arch/aarch64/CodeGen.zig"), |
| 38 | .stage2_arm => @import("arch/arm/CodeGen.zig"), | 52 | .stage2_arm => @import("arch/arm/CodeGen.zig"), |
| 39 | .stage2_c => @import("codegen/c.zig"), | 53 | .stage2_c => @import("codegen/c.zig"), |
| ... | @@ -42,11 +56,35 @@ pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type { | ... | @@ -42,11 +56,35 @@ pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type { |
| 42 | .stage2_riscv64 => @import("arch/riscv64/CodeGen.zig"), | 56 | .stage2_riscv64 => @import("arch/riscv64/CodeGen.zig"), |
| 43 | .stage2_sparc64 => @import("arch/sparc64/CodeGen.zig"), | 57 | .stage2_sparc64 => @import("arch/sparc64/CodeGen.zig"), |
| 44 | .stage2_spirv64 => @import("codegen/spirv.zig"), | 58 | .stage2_spirv64 => @import("codegen/spirv.zig"), |
| 45 | .stage2_x86_64 => @import("arch/x86_64/CodeGen.zig"), | 59 | .stage2_wasm => @import("arch/wasm/CodeGen.zig"), |
| 46 | else => null, | 60 | .stage2_x86, .stage2_x86_64 => @import("arch/x86_64/CodeGen.zig"), |
| 61 | _ => unreachable, | ||
| 47 | }; | 62 | }; |
| 48 | } | 63 | } |
| 49 | 64 | ||
| 65 | pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*const Air.Legalize.Features { | ||
| 66 | const zcu = pt.zcu; | ||
| 67 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; | ||
| 68 | switch (target_util.zigBackend(target.*, zcu.comp.config.use_llvm)) { | ||
| 69 | else => unreachable, | ||
| 70 | inline .stage2_llvm, | ||
| 71 | .stage2_c, | ||
| 72 | .stage2_wasm, | ||
| 73 | .stage2_arm, | ||
| 74 | .stage2_x86_64, | ||
| 75 | .stage2_aarch64, | ||
| 76 | .stage2_x86, | ||
| 77 | .stage2_riscv64, | ||
| 78 | .stage2_sparc64, | ||
| 79 | .stage2_spirv64, | ||
| 80 | .stage2_powerpc, | ||
| 81 | => |backend| { | ||
| 82 | dev.check(devFeatureForBackend(backend)); | ||
| 83 | return importBackend(backend).legalizeFeatures(target); | ||
| 84 | }, | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 50 | pub fn generateFunction( | 88 | pub fn generateFunction( |
| 51 | lf: *link.File, | 89 | lf: *link.File, |
| 52 | pt: Zcu.PerThread, | 90 | pt: Zcu.PerThread, |
| ... | @@ -60,7 +98,7 @@ pub fn generateFunction( | ... | @@ -60,7 +98,7 @@ pub fn generateFunction( |
| 60 | const zcu = pt.zcu; | 98 | const zcu = pt.zcu; |
| 61 | const func = zcu.funcInfo(func_index); | 99 | const func = zcu.funcInfo(func_index); |
| 62 | const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; | 100 | const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| 63 | switch (target_util.zigBackend(target, false)) { | 101 | switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) { |
| 64 | else => unreachable, | 102 | else => unreachable, |
| 65 | inline .stage2_aarch64, | 103 | inline .stage2_aarch64, |
| 66 | .stage2_arm, | 104 | .stage2_arm, |
| ... | @@ -70,7 +108,7 @@ pub fn generateFunction( | ... | @@ -70,7 +108,7 @@ pub fn generateFunction( |
| 70 | .stage2_x86_64, | 108 | .stage2_x86_64, |
| 71 | => |backend| { | 109 | => |backend| { |
| 72 | dev.check(devFeatureForBackend(backend)); | 110 | dev.check(devFeatureForBackend(backend)); |
| 73 | return importBackend(backend).?.generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output); | 111 | return importBackend(backend).generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output); |
| 74 | }, | 112 | }, |
| 75 | } | 113 | } |
| 76 | } | 114 | } |
| ... | @@ -88,14 +126,14 @@ pub fn generateLazyFunction( | ... | @@ -88,14 +126,14 @@ pub fn generateLazyFunction( |
| 88 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result | 126 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result |
| 89 | else | 127 | else |
| 90 | zcu.getTarget(); | 128 | zcu.getTarget(); |
| 91 | switch (target_util.zigBackend(target, false)) { | 129 | switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) { |
| 92 | else => unreachable, | 130 | else => unreachable, |
| 93 | inline .stage2_powerpc, | 131 | inline .stage2_powerpc, |
| 94 | .stage2_riscv64, | 132 | .stage2_riscv64, |
| 95 | .stage2_x86_64, | 133 | .stage2_x86_64, |
| 96 | => |backend| { | 134 | => |backend| { |
| 97 | dev.check(devFeatureForBackend(backend)); | 135 | dev.check(devFeatureForBackend(backend)); |
| 98 | return importBackend(backend).?.generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output); | 136 | return importBackend(backend).generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output); |
| 99 | }, | 137 | }, |
| 100 | } | 138 | } |
| 101 | } | 139 | } |
src/codegen/c.zig+80-26| ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; | ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const log = std.log.scoped(.c); | 5 | const log = std.log.scoped(.c); |
| 6 | 6 | ||
| 7 | const dev = @import("../dev.zig"); | ||
| 7 | const link = @import("../link.zig"); | 8 | const link = @import("../link.zig"); |
| 8 | const Zcu = @import("../Zcu.zig"); | 9 | const Zcu = @import("../Zcu.zig"); |
| 9 | const Module = @import("../Package/Module.zig"); | 10 | const Module = @import("../Package/Module.zig"); |
| ... | @@ -20,6 +21,15 @@ const Alignment = InternPool.Alignment; | ... | @@ -20,6 +21,15 @@ const Alignment = InternPool.Alignment; |
| 20 | const BigIntLimb = std.math.big.Limb; | 21 | const BigIntLimb = std.math.big.Limb; |
| 21 | const BigInt = std.math.big.int; | 22 | const BigInt = std.math.big.int; |
| 22 | 23 | ||
| 24 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 25 | return if (dev.env.supports(.legalize)) comptime &.initMany(&.{ | ||
| 26 | .expand_intcast_safe, | ||
| 27 | .expand_add_safe, | ||
| 28 | .expand_sub_safe, | ||
| 29 | .expand_mul_safe, | ||
| 30 | }) else null; // we don't currently ask zig1 to use safe optimization modes | ||
| 31 | } | ||
| 32 | |||
| 23 | pub const CType = @import("c/Type.zig"); | 33 | pub const CType = @import("c/Type.zig"); |
| 24 | 34 | ||
| 25 | pub const CValue = union(enum) { | 35 | pub const CValue = union(enum) { |
| ... | @@ -206,7 +216,6 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ | ... | @@ -206,7 +216,6 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ |
| 206 | .{ "atomic_ushort", {} }, | 216 | .{ "atomic_ushort", {} }, |
| 207 | .{ "atomic_wchar_t", {} }, | 217 | .{ "atomic_wchar_t", {} }, |
| 208 | .{ "auto", {} }, | 218 | .{ "auto", {} }, |
| 209 | .{ "bool", {} }, | ||
| 210 | .{ "break", {} }, | 219 | .{ "break", {} }, |
| 211 | .{ "case", {} }, | 220 | .{ "case", {} }, |
| 212 | .{ "char", {} }, | 221 | .{ "char", {} }, |
| ... | @@ -266,6 +275,11 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ | ... | @@ -266,6 +275,11 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ |
| 266 | .{ "va_end", {} }, | 275 | .{ "va_end", {} }, |
| 267 | .{ "va_copy", {} }, | 276 | .{ "va_copy", {} }, |
| 268 | 277 | ||
| 278 | // stdbool.h | ||
| 279 | .{ "bool", {} }, | ||
| 280 | .{ "false", {} }, | ||
| 281 | .{ "true", {} }, | ||
| 282 | |||
| 269 | // stddef.h | 283 | // stddef.h |
| 270 | .{ "offsetof", {} }, | 284 | .{ "offsetof", {} }, |
| 271 | 285 | ||
| ... | @@ -1591,7 +1605,7 @@ pub const DeclGen = struct { | ... | @@ -1591,7 +1605,7 @@ pub const DeclGen = struct { |
| 1591 | try writer.writeAll("(("); | 1605 | try writer.writeAll("(("); |
| 1592 | try dg.renderCType(writer, ctype); | 1606 | try dg.renderCType(writer, ctype); |
| 1593 | return writer.print("){x})", .{ | 1607 | return writer.print("){x})", .{ |
| 1594 | try dg.fmtIntLiteral(try pt.undefValue(.usize), .Other), | 1608 | try dg.fmtIntLiteral(.undef_usize, .Other), |
| 1595 | }); | 1609 | }); |
| 1596 | }, | 1610 | }, |
| 1597 | .slice => { | 1611 | .slice => { |
| ... | @@ -1605,7 +1619,7 @@ pub const DeclGen = struct { | ... | @@ -1605,7 +1619,7 @@ pub const DeclGen = struct { |
| 1605 | const ptr_ty = ty.slicePtrFieldType(zcu); | 1619 | const ptr_ty = ty.slicePtrFieldType(zcu); |
| 1606 | try dg.renderType(writer, ptr_ty); | 1620 | try dg.renderType(writer, ptr_ty); |
| 1607 | return writer.print("){x}, {0x}}}", .{ | 1621 | return writer.print("){x}, {0x}}}", .{ |
| 1608 | try dg.fmtIntLiteral(try dg.pt.undefValue(.usize), .Other), | 1622 | try dg.fmtIntLiteral(.undef_usize, .Other), |
| 1609 | }); | 1623 | }); |
| 1610 | }, | 1624 | }, |
| 1611 | }, | 1625 | }, |
| ... | @@ -3360,7 +3374,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, | ... | @@ -3360,7 +3374,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3360 | .error_name => try airErrorName(f, inst), | 3374 | .error_name => try airErrorName(f, inst), |
| 3361 | .splat => try airSplat(f, inst), | 3375 | .splat => try airSplat(f, inst), |
| 3362 | .select => try airSelect(f, inst), | 3376 | .select => try airSelect(f, inst), |
| 3363 | .shuffle => try airShuffle(f, inst), | 3377 | .shuffle_one => try airShuffleOne(f, inst), |
| 3378 | .shuffle_two => try airShuffleTwo(f, inst), | ||
| 3364 | .reduce => try airReduce(f, inst), | 3379 | .reduce => try airReduce(f, inst), |
| 3365 | .aggregate_init => try airAggregateInit(f, inst), | 3380 | .aggregate_init => try airAggregateInit(f, inst), |
| 3366 | .union_init => try airUnionInit(f, inst), | 3381 | .union_init => try airUnionInit(f, inst), |
| ... | @@ -4179,7 +4194,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: | ... | @@ -4179,7 +4194,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 4179 | try v.elem(f, w); | 4194 | try v.elem(f, w); |
| 4180 | try w.writeAll(", "); | 4195 | try w.writeAll(", "); |
| 4181 | try f.writeCValue(w, rhs, .FunctionArgument); | 4196 | try f.writeCValue(w, rhs, .FunctionArgument); |
| 4182 | try v.elem(f, w); | 4197 | if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w); |
| 4183 | try f.object.dg.renderBuiltinInfo(w, scalar_ty, info); | 4198 | try f.object.dg.renderBuiltinInfo(w, scalar_ty, info); |
| 4184 | try w.writeAll(");\n"); | 4199 | try w.writeAll(");\n"); |
| 4185 | try v.end(f, inst, w); | 4200 | try v.end(f, inst, w); |
| ... | @@ -6376,7 +6391,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6376,7 +6391,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6376 | if (operand_child_ctype.info(ctype_pool) == .array) { | 6391 | if (operand_child_ctype.info(ctype_pool) == .array) { |
| 6377 | try writer.writeByte('&'); | 6392 | try writer.writeByte('&'); |
| 6378 | try f.writeCValueDeref(writer, operand); | 6393 | try f.writeCValueDeref(writer, operand); |
| 6379 | try writer.print("[{}]", .{try f.fmtIntLiteral(try pt.intValue(.usize, 0))}); | 6394 | try writer.print("[{}]", .{try f.fmtIntLiteral(.zero_usize)}); |
| 6380 | } else try f.writeCValue(writer, operand, .Other); | 6395 | } else try f.writeCValue(writer, operand, .Other); |
| 6381 | } | 6396 | } |
| 6382 | try a.end(f, writer); | 6397 | try a.end(f, writer); |
| ... | @@ -6536,7 +6551,7 @@ fn airBinBuiltinCall( | ... | @@ -6536,7 +6551,7 @@ fn airBinBuiltinCall( |
| 6536 | try v.elem(f, writer); | 6551 | try v.elem(f, writer); |
| 6537 | try writer.writeAll(", "); | 6552 | try writer.writeAll(", "); |
| 6538 | try f.writeCValue(writer, rhs, .FunctionArgument); | 6553 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 6539 | try v.elem(f, writer); | 6554 | if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, writer); |
| 6540 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | 6555 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); |
| 6541 | try writer.writeAll(");\n"); | 6556 | try writer.writeAll(");\n"); |
| 6542 | try v.end(f, inst, writer); | 6557 | try v.end(f, inst, writer); |
| ... | @@ -6907,7 +6922,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6907,7 +6922,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6907 | try writer.writeAll("for ("); | 6922 | try writer.writeAll("for ("); |
| 6908 | try f.writeCValue(writer, index, .Other); | 6923 | try f.writeCValue(writer, index, .Other); |
| 6909 | try writer.writeAll(" = "); | 6924 | try writer.writeAll(" = "); |
| 6910 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, 0), .Other); | 6925 | try f.object.dg.renderValue(writer, .zero_usize, .Other); |
| 6911 | try writer.writeAll("; "); | 6926 | try writer.writeAll("; "); |
| 6912 | try f.writeCValue(writer, index, .Other); | 6927 | try f.writeCValue(writer, index, .Other); |
| 6913 | try writer.writeAll(" != "); | 6928 | try writer.writeAll(" != "); |
| ... | @@ -7149,34 +7164,73 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7149,34 +7164,73 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7149 | return local; | 7164 | return local; |
| 7150 | } | 7165 | } |
| 7151 | 7166 | ||
| 7152 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { | 7167 | fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7153 | const pt = f.object.dg.pt; | 7168 | const pt = f.object.dg.pt; |
| 7154 | const zcu = pt.zcu; | 7169 | const zcu = pt.zcu; |
| 7155 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | ||
| 7156 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; | ||
| 7157 | 7170 | ||
| 7158 | const mask = Value.fromInterned(extra.mask); | 7171 | const unwrapped = f.air.unwrapShuffleOne(zcu, inst); |
| 7159 | const lhs = try f.resolveInst(extra.a); | 7172 | const mask = unwrapped.mask; |
| 7160 | const rhs = try f.resolveInst(extra.b); | 7173 | const operand = try f.resolveInst(unwrapped.operand); |
| 7161 | 7174 | const inst_ty = unwrapped.result_ty; | |
| 7162 | const inst_ty = f.typeOfIndex(inst); | ||
| 7163 | 7175 | ||
| 7164 | const writer = f.object.writer(); | 7176 | const writer = f.object.writer(); |
| 7165 | const local = try f.allocLocal(inst, inst_ty); | 7177 | const local = try f.allocLocal(inst, inst_ty); |
| 7166 | try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands | 7178 | try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand |
| 7167 | for (0..extra.mask_len) |index| { | 7179 | for (mask, 0..) |mask_elem, out_idx| { |
| 7168 | try f.writeCValue(writer, local, .Other); | 7180 | try f.writeCValue(writer, local, .Other); |
| 7169 | try writer.writeByte('['); | 7181 | try writer.writeByte('['); |
| 7170 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, index), .Other); | 7182 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other); |
| 7171 | try writer.writeAll("] = "); | 7183 | try writer.writeAll("] = "); |
| 7184 | switch (mask_elem.unwrap()) { | ||
| 7185 | .elem => |src_idx| { | ||
| 7186 | try f.writeCValue(writer, operand, .Other); | ||
| 7187 | try writer.writeByte('['); | ||
| 7188 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other); | ||
| 7189 | try writer.writeByte(']'); | ||
| 7190 | }, | ||
| 7191 | .value => |val| try f.object.dg.renderValue(writer, .fromInterned(val), .Other), | ||
| 7192 | } | ||
| 7193 | try writer.writeAll(";\n"); | ||
| 7194 | } | ||
| 7172 | 7195 | ||
| 7173 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(zcu); | 7196 | return local; |
| 7174 | const src_val = try pt.intValue(.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63))); | 7197 | } |
| 7198 | |||
| 7199 | fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 7200 | const pt = f.object.dg.pt; | ||
| 7201 | const zcu = pt.zcu; | ||
| 7202 | |||
| 7203 | const unwrapped = f.air.unwrapShuffleTwo(zcu, inst); | ||
| 7204 | const mask = unwrapped.mask; | ||
| 7205 | const operand_a = try f.resolveInst(unwrapped.operand_a); | ||
| 7206 | const operand_b = try f.resolveInst(unwrapped.operand_b); | ||
| 7207 | const inst_ty = unwrapped.result_ty; | ||
| 7208 | const elem_ty = inst_ty.childType(zcu); | ||
| 7175 | 7209 | ||
| 7176 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); | 7210 | const writer = f.object.writer(); |
| 7211 | const local = try f.allocLocal(inst, inst_ty); | ||
| 7212 | try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands | ||
| 7213 | for (mask, 0..) |mask_elem, out_idx| { | ||
| 7214 | try f.writeCValue(writer, local, .Other); | ||
| 7177 | try writer.writeByte('['); | 7215 | try writer.writeByte('['); |
| 7178 | try f.object.dg.renderValue(writer, src_val, .Other); | 7216 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other); |
| 7179 | try writer.writeAll("];\n"); | 7217 | try writer.writeAll("] = "); |
| 7218 | switch (mask_elem.unwrap()) { | ||
| 7219 | .a_elem => |src_idx| { | ||
| 7220 | try f.writeCValue(writer, operand_a, .Other); | ||
| 7221 | try writer.writeByte('['); | ||
| 7222 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other); | ||
| 7223 | try writer.writeByte(']'); | ||
| 7224 | }, | ||
| 7225 | .b_elem => |src_idx| { | ||
| 7226 | try f.writeCValue(writer, operand_b, .Other); | ||
| 7227 | try writer.writeByte('['); | ||
| 7228 | try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other); | ||
| 7229 | try writer.writeByte(']'); | ||
| 7230 | }, | ||
| 7231 | .undef => try f.object.dg.renderUndefValue(writer, elem_ty, .Other), | ||
| 7232 | } | ||
| 7233 | try writer.writeAll(";\n"); | ||
| 7180 | } | 7234 | } |
| 7181 | 7235 | ||
| 7182 | return local; | 7236 | return local; |
| ... | @@ -8311,11 +8365,11 @@ const Vectorize = struct { | ... | @@ -8311,11 +8365,11 @@ const Vectorize = struct { |
| 8311 | 8365 | ||
| 8312 | try writer.writeAll("for ("); | 8366 | try writer.writeAll("for ("); |
| 8313 | try f.writeCValue(writer, local, .Other); | 8367 | try f.writeCValue(writer, local, .Other); |
| 8314 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, 0))}); | 8368 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(.zero_usize)}); |
| 8315 | try f.writeCValue(writer, local, .Other); | 8369 | try f.writeCValue(writer, local, .Other); |
| 8316 | try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))}); | 8370 | try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))}); |
| 8317 | try f.writeCValue(writer, local, .Other); | 8371 | try f.writeCValue(writer, local, .Other); |
| 8318 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try pt.intValue(.usize, 1))}); | 8372 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(.one_usize)}); |
| 8319 | f.object.indent_writer.pushIndent(); | 8373 | f.object.indent_writer.pushIndent(); |
| 8320 | 8374 | ||
| 8321 | break :index .{ .index = local }; | 8375 | break :index .{ .index = local }; |
src/codegen/c/Type.zig+15-6| ... | @@ -1408,6 +1408,15 @@ pub const Pool = struct { | ... | @@ -1408,6 +1408,15 @@ pub const Pool = struct { |
| 1408 | .bits = pt.zcu.errorSetBits(), | 1408 | .bits = pt.zcu.errorSetBits(), |
| 1409 | }, mod, kind), | 1409 | }, mod, kind), |
| 1410 | 1410 | ||
| 1411 | .ptr_usize_type, | ||
| 1412 | => return pool.getPointer(allocator, .{ | ||
| 1413 | .elem_ctype = .usize, | ||
| 1414 | }), | ||
| 1415 | .ptr_const_comptime_int_type, | ||
| 1416 | => return pool.getPointer(allocator, .{ | ||
| 1417 | .elem_ctype = .void, | ||
| 1418 | .@"const" = true, | ||
| 1419 | }), | ||
| 1411 | .manyptr_u8_type, | 1420 | .manyptr_u8_type, |
| 1412 | => return pool.getPointer(allocator, .{ | 1421 | => return pool.getPointer(allocator, .{ |
| 1413 | .elem_ctype = .u8, | 1422 | .elem_ctype = .u8, |
| ... | @@ -1418,11 +1427,6 @@ pub const Pool = struct { | ... | @@ -1418,11 +1427,6 @@ pub const Pool = struct { |
| 1418 | .elem_ctype = .u8, | 1427 | .elem_ctype = .u8, |
| 1419 | .@"const" = true, | 1428 | .@"const" = true, |
| 1420 | }), | 1429 | }), |
| 1421 | .single_const_pointer_to_comptime_int_type, | ||
| 1422 | => return pool.getPointer(allocator, .{ | ||
| 1423 | .elem_ctype = .void, | ||
| 1424 | .@"const" = true, | ||
| 1425 | }), | ||
| 1426 | .slice_const_u8_type, | 1430 | .slice_const_u8_type, |
| 1427 | .slice_const_u8_sentinel_0_type, | 1431 | .slice_const_u8_sentinel_0_type, |
| 1428 | => { | 1432 | => { |
| ... | @@ -2157,11 +2161,16 @@ pub const Pool = struct { | ... | @@ -2157,11 +2161,16 @@ pub const Pool = struct { |
| 2157 | }, | 2161 | }, |
| 2158 | 2162 | ||
| 2159 | .undef, | 2163 | .undef, |
| 2164 | .undef_bool, | ||
| 2165 | .undef_usize, | ||
| 2166 | .undef_u1, | ||
| 2160 | .zero, | 2167 | .zero, |
| 2161 | .zero_usize, | 2168 | .zero_usize, |
| 2169 | .zero_u1, | ||
| 2162 | .zero_u8, | 2170 | .zero_u8, |
| 2163 | .one, | 2171 | .one, |
| 2164 | .one_usize, | 2172 | .one_usize, |
| 2173 | .one_u1, | ||
| 2165 | .one_u8, | 2174 | .one_u8, |
| 2166 | .four_u8, | 2175 | .four_u8, |
| 2167 | .negative_one, | 2176 | .negative_one, |
| ... | @@ -2172,7 +2181,7 @@ pub const Pool = struct { | ... | @@ -2172,7 +2181,7 @@ pub const Pool = struct { |
| 2172 | .bool_false, | 2181 | .bool_false, |
| 2173 | .empty_tuple, | 2182 | .empty_tuple, |
| 2174 | .none, | 2183 | .none, |
| 2175 | => unreachable, | 2184 | => unreachable, // values, not types |
| 2176 | 2185 | ||
| 2177 | _ => |ip_index| switch (ip.indexToKey(ip_index)) { | 2186 | _ => |ip_index| switch (ip.indexToKey(ip_index)) { |
| 2178 | .int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind), | 2187 | .int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind), |
src/codegen/llvm.zig+216-47| ... | @@ -36,6 +36,10 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | ... | @@ -36,6 +36,10 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; |
| 36 | 36 | ||
| 37 | const Error = error{ OutOfMemory, CodegenFail }; | 37 | const Error = error{ OutOfMemory, CodegenFail }; |
| 38 | 38 | ||
| 39 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | ||
| 40 | return null; | ||
| 41 | } | ||
| 42 | |||
| 39 | fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 { | 43 | fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 { |
| 40 | inline for (mappings) |mapping| { | 44 | inline for (mappings) |mapping| { |
| 41 | if (arch.featureSetHas(features, mapping[0])) return mapping[1]; | 45 | if (arch.featureSetHas(features, mapping[0])) return mapping[1]; |
| ... | @@ -3081,10 +3085,11 @@ pub const Object = struct { | ... | @@ -3081,10 +3085,11 @@ pub const Object = struct { |
| 3081 | .undefined_type, | 3085 | .undefined_type, |
| 3082 | .enum_literal_type, | 3086 | .enum_literal_type, |
| 3083 | => unreachable, | 3087 | => unreachable, |
| 3088 | .ptr_usize_type, | ||
| 3089 | .ptr_const_comptime_int_type, | ||
| 3084 | .manyptr_u8_type, | 3090 | .manyptr_u8_type, |
| 3085 | .manyptr_const_u8_type, | 3091 | .manyptr_const_u8_type, |
| 3086 | .manyptr_const_u8_sentinel_0_type, | 3092 | .manyptr_const_u8_sentinel_0_type, |
| 3087 | .single_const_pointer_to_comptime_int_type, | ||
| 3088 | => .ptr, | 3093 | => .ptr, |
| 3089 | .slice_const_u8_type, | 3094 | .slice_const_u8_type, |
| 3090 | .slice_const_u8_sentinel_0_type, | 3095 | .slice_const_u8_sentinel_0_type, |
| ... | @@ -3098,11 +3103,16 @@ pub const Object = struct { | ... | @@ -3098,11 +3103,16 @@ pub const Object = struct { |
| 3098 | => unreachable, | 3103 | => unreachable, |
| 3099 | // values, not types | 3104 | // values, not types |
| 3100 | .undef, | 3105 | .undef, |
| 3106 | .undef_bool, | ||
| 3107 | .undef_usize, | ||
| 3108 | .undef_u1, | ||
| 3101 | .zero, | 3109 | .zero, |
| 3102 | .zero_usize, | 3110 | .zero_usize, |
| 3111 | .zero_u1, | ||
| 3103 | .zero_u8, | 3112 | .zero_u8, |
| 3104 | .one, | 3113 | .one, |
| 3105 | .one_usize, | 3114 | .one_usize, |
| 3115 | .one_u1, | ||
| 3106 | .one_u8, | 3116 | .one_u8, |
| 3107 | .four_u8, | 3117 | .four_u8, |
| 3108 | .negative_one, | 3118 | .negative_one, |
| ... | @@ -4959,7 +4969,8 @@ pub const FuncGen = struct { | ... | @@ -4959,7 +4969,8 @@ pub const FuncGen = struct { |
| 4959 | .error_name => try self.airErrorName(inst), | 4969 | .error_name => try self.airErrorName(inst), |
| 4960 | .splat => try self.airSplat(inst), | 4970 | .splat => try self.airSplat(inst), |
| 4961 | .select => try self.airSelect(inst), | 4971 | .select => try self.airSelect(inst), |
| 4962 | .shuffle => try self.airShuffle(inst), | 4972 | .shuffle_one => try self.airShuffleOne(inst), |
| 4973 | .shuffle_two => try self.airShuffleTwo(inst), | ||
| 4963 | .aggregate_init => try self.airAggregateInit(inst), | 4974 | .aggregate_init => try self.airAggregateInit(inst), |
| 4964 | .union_init => try self.airUnionInit(inst), | 4975 | .union_init => try self.airUnionInit(inst), |
| 4965 | .prefetch => try self.airPrefetch(inst), | 4976 | .prefetch => try self.airPrefetch(inst), |
| ... | @@ -8917,6 +8928,8 @@ pub const FuncGen = struct { | ... | @@ -8917,6 +8928,8 @@ pub const FuncGen = struct { |
| 8917 | const rhs = try self.resolveInst(extra.rhs); | 8928 | const rhs = try self.resolveInst(extra.rhs); |
| 8918 | 8929 | ||
| 8919 | const lhs_ty = self.typeOf(extra.lhs); | 8930 | const lhs_ty = self.typeOf(extra.lhs); |
| 8931 | if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) | ||
| 8932 | return self.ng.todo("implement vector shifts with scalar rhs", .{}); | ||
| 8920 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 8933 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 8921 | 8934 | ||
| 8922 | const dest_ty = self.typeOfIndex(inst); | 8935 | const dest_ty = self.typeOfIndex(inst); |
| ... | @@ -8986,6 +8999,8 @@ pub const FuncGen = struct { | ... | @@ -8986,6 +8999,8 @@ pub const FuncGen = struct { |
| 8986 | const rhs = try self.resolveInst(bin_op.rhs); | 8999 | const rhs = try self.resolveInst(bin_op.rhs); |
| 8987 | 9000 | ||
| 8988 | const lhs_ty = self.typeOf(bin_op.lhs); | 9001 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 9002 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 9003 | return self.ng.todo("implement vector shifts with scalar rhs", .{}); | ||
| 8989 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 9004 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 8990 | 9005 | ||
| 8991 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); | 9006 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| ... | @@ -8997,14 +9012,17 @@ pub const FuncGen = struct { | ... | @@ -8997,14 +9012,17 @@ pub const FuncGen = struct { |
| 8997 | 9012 | ||
| 8998 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9013 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8999 | const o = self.ng.object; | 9014 | const o = self.ng.object; |
| 9015 | const zcu = o.pt.zcu; | ||
| 9000 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9016 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9001 | 9017 | ||
| 9002 | const lhs = try self.resolveInst(bin_op.lhs); | 9018 | const lhs = try self.resolveInst(bin_op.lhs); |
| 9003 | const rhs = try self.resolveInst(bin_op.rhs); | 9019 | const rhs = try self.resolveInst(bin_op.rhs); |
| 9004 | 9020 | ||
| 9005 | const lhs_type = self.typeOf(bin_op.lhs); | 9021 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 9022 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 9023 | return self.ng.todo("implement vector shifts with scalar rhs", .{}); | ||
| 9006 | 9024 | ||
| 9007 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_type), ""); | 9025 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 9008 | return self.wip.bin(.shl, lhs, casted_rhs, ""); | 9026 | return self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 9009 | } | 9027 | } |
| 9010 | 9028 | ||
| ... | @@ -9023,6 +9041,8 @@ pub const FuncGen = struct { | ... | @@ -9023,6 +9041,8 @@ pub const FuncGen = struct { |
| 9023 | const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder); | 9041 | const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder); |
| 9024 | 9042 | ||
| 9025 | const rhs_ty = self.typeOf(bin_op.rhs); | 9043 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 9044 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) | ||
| 9045 | return self.ng.todo("implement vector shifts with scalar rhs", .{}); | ||
| 9026 | const rhs_info = rhs_ty.intInfo(zcu); | 9046 | const rhs_info = rhs_ty.intInfo(zcu); |
| 9027 | assert(rhs_info.signedness == .unsigned); | 9047 | assert(rhs_info.signedness == .unsigned); |
| 9028 | const llvm_rhs_ty = try o.lowerType(rhs_ty); | 9048 | const llvm_rhs_ty = try o.lowerType(rhs_ty); |
| ... | @@ -9095,6 +9115,8 @@ pub const FuncGen = struct { | ... | @@ -9095,6 +9115,8 @@ pub const FuncGen = struct { |
| 9095 | const rhs = try self.resolveInst(bin_op.rhs); | 9115 | const rhs = try self.resolveInst(bin_op.rhs); |
| 9096 | 9116 | ||
| 9097 | const lhs_ty = self.typeOf(bin_op.lhs); | 9117 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 9118 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | ||
| 9119 | return self.ng.todo("implement vector shifts with scalar rhs", .{}); | ||
| 9098 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 9120 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 9099 | 9121 | ||
| 9100 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); | 9122 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| ... | @@ -9167,11 +9189,7 @@ pub const FuncGen = struct { | ... | @@ -9167,11 +9189,7 @@ pub const FuncGen = struct { |
| 9167 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; | 9189 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 9168 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); | 9190 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); |
| 9169 | 9191 | ||
| 9170 | const min_panic_id: Zcu.SimplePanicId, const max_panic_id: Zcu.SimplePanicId = id: { | 9192 | const panic_id: Zcu.SimplePanicId = if (dest_is_enum) .invalid_enum_value else .integer_out_of_bounds; |
| 9171 | if (dest_is_enum) break :id .{ .invalid_enum_value, .invalid_enum_value }; | ||
| 9172 | if (dest_info.signedness == .unsigned) break :id .{ .negative_to_unsigned, .cast_truncated_data }; | ||
| 9173 | break :id .{ .cast_truncated_data, .cast_truncated_data }; | ||
| 9174 | }; | ||
| 9175 | 9193 | ||
| 9176 | if (have_min_check) { | 9194 | if (have_min_check) { |
| 9177 | const min_const_scalar = try minIntConst(&o.builder, dest_scalar, operand_scalar_llvm_ty, zcu); | 9195 | const min_const_scalar = try minIntConst(&o.builder, dest_scalar, operand_scalar_llvm_ty, zcu); |
| ... | @@ -9185,7 +9203,7 @@ pub const FuncGen = struct { | ... | @@ -9185,7 +9203,7 @@ pub const FuncGen = struct { |
| 9185 | const ok_block = try fg.wip.block(1, "IntMinOk"); | 9203 | const ok_block = try fg.wip.block(1, "IntMinOk"); |
| 9186 | _ = try fg.wip.brCond(ok, ok_block, fail_block, .none); | 9204 | _ = try fg.wip.brCond(ok, ok_block, fail_block, .none); |
| 9187 | fg.wip.cursor = .{ .block = fail_block }; | 9205 | fg.wip.cursor = .{ .block = fail_block }; |
| 9188 | try fg.buildSimplePanic(min_panic_id); | 9206 | try fg.buildSimplePanic(panic_id); |
| 9189 | fg.wip.cursor = .{ .block = ok_block }; | 9207 | fg.wip.cursor = .{ .block = ok_block }; |
| 9190 | } | 9208 | } |
| 9191 | 9209 | ||
| ... | @@ -9201,7 +9219,7 @@ pub const FuncGen = struct { | ... | @@ -9201,7 +9219,7 @@ pub const FuncGen = struct { |
| 9201 | const ok_block = try fg.wip.block(1, "IntMaxOk"); | 9219 | const ok_block = try fg.wip.block(1, "IntMaxOk"); |
| 9202 | _ = try fg.wip.brCond(ok, ok_block, fail_block, .none); | 9220 | _ = try fg.wip.brCond(ok, ok_block, fail_block, .none); |
| 9203 | fg.wip.cursor = .{ .block = fail_block }; | 9221 | fg.wip.cursor = .{ .block = fail_block }; |
| 9204 | try fg.buildSimplePanic(max_panic_id); | 9222 | try fg.buildSimplePanic(panic_id); |
| 9205 | fg.wip.cursor = .{ .block = ok_block }; | 9223 | fg.wip.cursor = .{ .block = ok_block }; |
| 9206 | } | 9224 | } |
| 9207 | } | 9225 | } |
| ... | @@ -9249,8 +9267,6 @@ pub const FuncGen = struct { | ... | @@ -9249,8 +9267,6 @@ pub const FuncGen = struct { |
| 9249 | const operand_ty = self.typeOf(ty_op.operand); | 9267 | const operand_ty = self.typeOf(ty_op.operand); |
| 9250 | const dest_ty = self.typeOfIndex(inst); | 9268 | const dest_ty = self.typeOfIndex(inst); |
| 9251 | const target = zcu.getTarget(); | 9269 | const target = zcu.getTarget(); |
| 9252 | const dest_bits = dest_ty.floatBits(target); | ||
| 9253 | const src_bits = operand_ty.floatBits(target); | ||
| 9254 | 9270 | ||
| 9255 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 9271 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 9256 | return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty), ""); | 9272 | return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty), ""); |
| ... | @@ -9258,6 +9274,8 @@ pub const FuncGen = struct { | ... | @@ -9258,6 +9274,8 @@ pub const FuncGen = struct { |
| 9258 | const operand_llvm_ty = try o.lowerType(operand_ty); | 9274 | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 9259 | const dest_llvm_ty = try o.lowerType(dest_ty); | 9275 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 9260 | 9276 | ||
| 9277 | const dest_bits = dest_ty.floatBits(target); | ||
| 9278 | const src_bits = operand_ty.floatBits(target); | ||
| 9261 | const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{ | 9279 | const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{ |
| 9262 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | 9280 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 9263 | }); | 9281 | }); |
| ... | @@ -9342,11 +9360,12 @@ pub const FuncGen = struct { | ... | @@ -9342,11 +9360,12 @@ pub const FuncGen = struct { |
| 9342 | return self.wip.conv(.unsigned, operand, llvm_dest_ty, ""); | 9360 | return self.wip.conv(.unsigned, operand, llvm_dest_ty, ""); |
| 9343 | } | 9361 | } |
| 9344 | 9362 | ||
| 9345 | if (operand_ty.zigTypeTag(zcu) == .int and inst_ty.isPtrAtRuntime(zcu)) { | 9363 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 9364 | const inst_scalar_ty = inst_ty.scalarType(zcu); | ||
| 9365 | if (operand_scalar_ty.zigTypeTag(zcu) == .int and inst_scalar_ty.isPtrAtRuntime(zcu)) { | ||
| 9346 | return self.wip.cast(.inttoptr, operand, llvm_dest_ty, ""); | 9366 | return self.wip.cast(.inttoptr, operand, llvm_dest_ty, ""); |
| 9347 | } | 9367 | } |
| 9348 | 9368 | if (operand_scalar_ty.isPtrAtRuntime(zcu) and inst_scalar_ty.zigTypeTag(zcu) == .int) { | |
| 9349 | if (operand_ty.isPtrAtRuntime(zcu) and inst_ty.zigTypeTag(zcu) == .int) { | ||
| 9350 | return self.wip.cast(.ptrtoint, operand, llvm_dest_ty, ""); | 9369 | return self.wip.cast(.ptrtoint, operand, llvm_dest_ty, ""); |
| 9351 | } | 9370 | } |
| 9352 | 9371 | ||
| ... | @@ -9644,7 +9663,7 @@ pub const FuncGen = struct { | ... | @@ -9644,7 +9663,7 @@ pub const FuncGen = struct { |
| 9644 | const zcu = o.pt.zcu; | 9663 | const zcu = o.pt.zcu; |
| 9645 | const ip = &zcu.intern_pool; | 9664 | const ip = &zcu.intern_pool; |
| 9646 | for (body_tail[1..]) |body_inst| { | 9665 | for (body_tail[1..]) |body_inst| { |
| 9647 | switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) { | 9666 | switch (fg.liveness.categorizeOperand(fg.air, zcu, body_inst, body_tail[0], ip)) { |
| 9648 | .none => continue, | 9667 | .none => continue, |
| 9649 | .write, .noret, .complex => return false, | 9668 | .write, .noret, .complex => return false, |
| 9650 | .tomb => return true, | 9669 | .tomb => return true, |
| ... | @@ -10399,42 +10418,192 @@ pub const FuncGen = struct { | ... | @@ -10399,42 +10418,192 @@ pub const FuncGen = struct { |
| 10399 | return self.wip.select(.normal, pred, a, b, ""); | 10418 | return self.wip.select(.normal, pred, a, b, ""); |
| 10400 | } | 10419 | } |
| 10401 | 10420 | ||
| 10402 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10421 | fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10403 | const o = self.ng.object; | 10422 | const o = fg.ng.object; |
| 10404 | const pt = o.pt; | 10423 | const pt = o.pt; |
| 10405 | const zcu = pt.zcu; | 10424 | const zcu = pt.zcu; |
| 10406 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 10425 | const gpa = zcu.gpa; |
| 10407 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 10426 | |
| 10408 | const a = try self.resolveInst(extra.a); | 10427 | const unwrapped = fg.air.unwrapShuffleOne(zcu, inst); |
| 10409 | const b = try self.resolveInst(extra.b); | 10428 | |
| 10410 | const mask = Value.fromInterned(extra.mask); | 10429 | const operand = try fg.resolveInst(unwrapped.operand); |
| 10411 | const mask_len = extra.mask_len; | 10430 | const mask = unwrapped.mask; |
| 10412 | const a_len = self.typeOf(extra.a).vectorLen(zcu); | 10431 | const operand_ty = fg.typeOf(unwrapped.operand); |
| 10413 | 10432 | const llvm_operand_ty = try o.lowerType(operand_ty); | |
| 10414 | // LLVM uses integers larger than the length of the first array to | 10433 | const llvm_result_ty = try o.lowerType(unwrapped.result_ty); |
| 10415 | // index into the second array. This was deemed unnecessarily fragile | 10434 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu)); |
| 10416 | // when changing code, so Zig uses negative numbers to index the | 10435 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); |
| 10417 | // second vector. These start at -1 and go down, and are easiest to use | 10436 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 10418 | // with the ~ operator. Here we convert between the two formats. | 10437 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| 10419 | const values = try self.gpa.alloc(Builder.Constant, mask_len); | 10438 | |
| 10420 | defer self.gpa.free(values); | 10439 | // LLVM requires that the two input vectors have the same length, so lowering isn't trivial. |
| 10421 | 10440 | // And, in the words of jacobly0: "llvm sucks at shuffles so we do have to hold its hand at | |
| 10422 | for (values, 0..) |*val, i| { | 10441 | // least a bit". So, there are two cases here. |
| 10423 | const elem = try mask.elemValue(pt, i); | 10442 | // |
| 10424 | if (elem.isUndef(zcu)) { | 10443 | // If the operand length equals the mask length, we do just the one `shufflevector`, where |
| 10425 | val.* = try o.builder.undefConst(.i32); | 10444 | // the second operand is a constant vector with comptime-known elements at the right indices |
| 10426 | } else { | 10445 | // and poison values elsewhere (in the indices which won't be selected). |
| 10427 | const int = elem.toSignedInt(zcu); | 10446 | // |
| 10428 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len); | 10447 | // Otherwise, we lower to *two* `shufflevector` instructions. The first shuffles the runtime |
| 10429 | val.* = try o.builder.intConst(.i32, unsigned); | 10448 | // operand with an all-poison vector to extract and correctly position all of the runtime |
| 10449 | // elements. We also make a constant vector with all of the comptime elements correctly | ||
| 10450 | // positioned. Then, our second instruction selects elements from those "runtime-or-poison" | ||
| 10451 | // and "comptime-or-poison" vectors to compute the result. | ||
| 10452 | |||
| 10453 | // This buffer is used primarily for the mask constants. | ||
| 10454 | const llvm_elem_buf = try gpa.alloc(Builder.Constant, mask.len); | ||
| 10455 | defer gpa.free(llvm_elem_buf); | ||
| 10456 | |||
| 10457 | // ...but first, we'll collect all of the comptime-known values. | ||
| 10458 | var any_defined_comptime_value = false; | ||
| 10459 | for (mask, llvm_elem_buf) |mask_elem, *llvm_elem| { | ||
| 10460 | llvm_elem.* = switch (mask_elem.unwrap()) { | ||
| 10461 | .elem => llvm_poison_elem, | ||
| 10462 | .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) elem: { | ||
| 10463 | any_defined_comptime_value = true; | ||
| 10464 | break :elem try o.lowerValue(val); | ||
| 10465 | } else llvm_poison_elem, | ||
| 10466 | }; | ||
| 10467 | } | ||
| 10468 | // This vector is like the result, but runtime elements are replaced with poison. | ||
| 10469 | const comptime_and_poison: Builder.Value = if (any_defined_comptime_value) vec: { | ||
| 10470 | break :vec try o.builder.vectorValue(llvm_result_ty, llvm_elem_buf); | ||
| 10471 | } else try o.builder.poisonValue(llvm_result_ty); | ||
| 10472 | |||
| 10473 | if (operand_ty.vectorLen(zcu) == mask.len) { | ||
| 10474 | // input length equals mask/output length, so we lower to one instruction | ||
| 10475 | for (mask, llvm_elem_buf, 0..) |mask_elem, *llvm_elem, elem_idx| { | ||
| 10476 | llvm_elem.* = switch (mask_elem.unwrap()) { | ||
| 10477 | .elem => |idx| try o.builder.intConst(.i32, idx), | ||
| 10478 | .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) mask_val: { | ||
| 10479 | break :mask_val try o.builder.intConst(.i32, mask.len + elem_idx); | ||
| 10480 | } else llvm_poison_mask_elem, | ||
| 10481 | }; | ||
| 10430 | } | 10482 | } |
| 10483 | return fg.wip.shuffleVector( | ||
| 10484 | operand, | ||
| 10485 | comptime_and_poison, | ||
| 10486 | try o.builder.vectorValue(llvm_mask_ty, llvm_elem_buf), | ||
| 10487 | "", | ||
| 10488 | ); | ||
| 10489 | } | ||
| 10490 | |||
| 10491 | for (mask, llvm_elem_buf) |mask_elem, *llvm_elem| { | ||
| 10492 | llvm_elem.* = switch (mask_elem.unwrap()) { | ||
| 10493 | .elem => |idx| try o.builder.intConst(.i32, idx), | ||
| 10494 | .value => llvm_poison_mask_elem, | ||
| 10495 | }; | ||
| 10431 | } | 10496 | } |
| 10497 | // This vector is like our result, but all comptime-known elements are poison. | ||
| 10498 | const runtime_and_poison = try fg.wip.shuffleVector( | ||
| 10499 | operand, | ||
| 10500 | try o.builder.poisonValue(llvm_operand_ty), | ||
| 10501 | try o.builder.vectorValue(llvm_mask_ty, llvm_elem_buf), | ||
| 10502 | "", | ||
| 10503 | ); | ||
| 10432 | 10504 | ||
| 10433 | const llvm_mask_value = try o.builder.vectorValue( | 10505 | if (!any_defined_comptime_value) { |
| 10434 | try o.builder.vectorType(.normal, mask_len, .i32), | 10506 | // `comptime_and_poison` is just poison; a second shuffle would be a nop. |
| 10435 | values, | 10507 | return runtime_and_poison; |
| 10508 | } | ||
| 10509 | |||
| 10510 | // In this second shuffle, the inputs, the mask, and the output all have the same length. | ||
| 10511 | for (mask, llvm_elem_buf, 0..) |mask_elem, *llvm_elem, elem_idx| { | ||
| 10512 | llvm_elem.* = switch (mask_elem.unwrap()) { | ||
| 10513 | .elem => try o.builder.intConst(.i32, elem_idx), | ||
| 10514 | .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) mask_val: { | ||
| 10515 | break :mask_val try o.builder.intConst(.i32, mask.len + elem_idx); | ||
| 10516 | } else llvm_poison_mask_elem, | ||
| 10517 | }; | ||
| 10518 | } | ||
| 10519 | // Merge the runtime and comptime elements with the mask we just built. | ||
| 10520 | return fg.wip.shuffleVector( | ||
| 10521 | runtime_and_poison, | ||
| 10522 | comptime_and_poison, | ||
| 10523 | try o.builder.vectorValue(llvm_mask_ty, llvm_elem_buf), | ||
| 10524 | "", | ||
| 10525 | ); | ||
| 10526 | } | ||
| 10527 | |||
| 10528 | fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ||
| 10529 | const o = fg.ng.object; | ||
| 10530 | const pt = o.pt; | ||
| 10531 | const zcu = pt.zcu; | ||
| 10532 | const gpa = zcu.gpa; | ||
| 10533 | |||
| 10534 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); | ||
| 10535 | |||
| 10536 | const mask = unwrapped.mask; | ||
| 10537 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu)); | ||
| 10538 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); | ||
| 10539 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); | ||
| 10540 | |||
| 10541 | // This is kind of simpler than in `airShuffleOne`. We extend the shorter vector to the | ||
| 10542 | // length of the longer one with an initial `shufflevector` if necessary, and then do the | ||
| 10543 | // actual computation with a second `shufflevector`. | ||
| 10544 | |||
| 10545 | const operand_a_len = fg.typeOf(unwrapped.operand_a).vectorLen(zcu); | ||
| 10546 | const operand_b_len = fg.typeOf(unwrapped.operand_b).vectorLen(zcu); | ||
| 10547 | const operand_len: u32 = @max(operand_a_len, operand_b_len); | ||
| 10548 | |||
| 10549 | // If we need to extend an operand, this is the type that mask will have. | ||
| 10550 | const llvm_operand_mask_ty = try o.builder.vectorType(.normal, operand_len, .i32); | ||
| 10551 | |||
| 10552 | const llvm_elem_buf = try gpa.alloc(Builder.Constant, @max(mask.len, operand_len)); | ||
| 10553 | defer gpa.free(llvm_elem_buf); | ||
| 10554 | |||
| 10555 | const operand_a: Builder.Value = extend: { | ||
| 10556 | const raw = try fg.resolveInst(unwrapped.operand_a); | ||
| 10557 | if (operand_a_len == operand_len) break :extend raw; | ||
| 10558 | // Extend with a `shufflevector`, with a mask `<0, 1, ..., n, poison, poison, ..., poison>` | ||
| 10559 | const mask_elems = llvm_elem_buf[0..operand_len]; | ||
| 10560 | for (mask_elems[0..operand_a_len], 0..) |*llvm_elem, elem_idx| { | ||
| 10561 | llvm_elem.* = try o.builder.intConst(.i32, elem_idx); | ||
| 10562 | } | ||
| 10563 | @memset(mask_elems[operand_a_len..], llvm_poison_mask_elem); | ||
| 10564 | const llvm_this_operand_ty = try o.builder.vectorType(.normal, operand_a_len, llvm_elem_ty); | ||
| 10565 | break :extend try fg.wip.shuffleVector( | ||
| 10566 | raw, | ||
| 10567 | try o.builder.poisonValue(llvm_this_operand_ty), | ||
| 10568 | try o.builder.vectorValue(llvm_operand_mask_ty, mask_elems), | ||
| 10569 | "", | ||
| 10570 | ); | ||
| 10571 | }; | ||
| 10572 | const operand_b: Builder.Value = extend: { | ||
| 10573 | const raw = try fg.resolveInst(unwrapped.operand_b); | ||
| 10574 | if (operand_b_len == operand_len) break :extend raw; | ||
| 10575 | // Extend with a `shufflevector`, with a mask `<0, 1, ..., n, poison, poison, ..., poison>` | ||
| 10576 | const mask_elems = llvm_elem_buf[0..operand_len]; | ||
| 10577 | for (mask_elems[0..operand_b_len], 0..) |*llvm_elem, elem_idx| { | ||
| 10578 | llvm_elem.* = try o.builder.intConst(.i32, elem_idx); | ||
| 10579 | } | ||
| 10580 | @memset(mask_elems[operand_b_len..], llvm_poison_mask_elem); | ||
| 10581 | const llvm_this_operand_ty = try o.builder.vectorType(.normal, operand_b_len, llvm_elem_ty); | ||
| 10582 | break :extend try fg.wip.shuffleVector( | ||
| 10583 | raw, | ||
| 10584 | try o.builder.poisonValue(llvm_this_operand_ty), | ||
| 10585 | try o.builder.vectorValue(llvm_operand_mask_ty, mask_elems), | ||
| 10586 | "", | ||
| 10587 | ); | ||
| 10588 | }; | ||
| 10589 | |||
| 10590 | // `operand_a` and `operand_b` now have the same length (we've extended the shorter one with | ||
| 10591 | // an initial shuffle if necessary). Now for the easy bit. | ||
| 10592 | |||
| 10593 | const mask_elems = llvm_elem_buf[0..mask.len]; | ||
| 10594 | for (mask, mask_elems) |mask_elem, *llvm_mask_elem| { | ||
| 10595 | llvm_mask_elem.* = switch (mask_elem.unwrap()) { | ||
| 10596 | .a_elem => |idx| try o.builder.intConst(.i32, idx), | ||
| 10597 | .b_elem => |idx| try o.builder.intConst(.i32, operand_len + idx), | ||
| 10598 | .undef => llvm_poison_mask_elem, | ||
| 10599 | }; | ||
| 10600 | } | ||
| 10601 | return fg.wip.shuffleVector( | ||
| 10602 | operand_a, | ||
| 10603 | operand_b, | ||
| 10604 | try o.builder.vectorValue(llvm_mask_ty, mask_elems), | ||
| 10605 | "", | ||
| 10436 | ); | 10606 | ); |
| 10437 | return self.wip.shuffleVector(a, b, llvm_mask_value, ""); | ||
| 10438 | } | 10607 | } |
| 10439 | 10608 | ||
| 10440 | /// Reduce a vector by repeatedly applying `llvm_fn` to produce an accumulated result. | 10609 | /// Reduce a vector by repeatedly applying `llvm_fn` to produce an accumulated result. |
src/codegen/spirv.zig+63-28| ... | @@ -28,6 +28,15 @@ const SpvAssembler = @import("spirv/Assembler.zig"); | ... | @@ -28,6 +28,15 @@ const SpvAssembler = @import("spirv/Assembler.zig"); |
| 28 | 28 | ||
| 29 | const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef); | 29 | const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef); |
| 30 | 30 | ||
| 31 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | ||
| 32 | return comptime &.initMany(&.{ | ||
| 33 | .expand_intcast_safe, | ||
| 34 | .expand_add_safe, | ||
| 35 | .expand_sub_safe, | ||
| 36 | .expand_mul_safe, | ||
| 37 | }); | ||
| 38 | } | ||
| 39 | |||
| 31 | pub const zig_call_abi_ver = 3; | 40 | pub const zig_call_abi_ver = 3; |
| 32 | pub const big_int_bits = 32; | 41 | pub const big_int_bits = 32; |
| 33 | 42 | ||
| ... | @@ -3243,7 +3252,8 @@ const NavGen = struct { | ... | @@ -3243,7 +3252,8 @@ const NavGen = struct { |
| 3243 | 3252 | ||
| 3244 | .splat => try self.airSplat(inst), | 3253 | .splat => try self.airSplat(inst), |
| 3245 | .reduce, .reduce_optimized => try self.airReduce(inst), | 3254 | .reduce, .reduce_optimized => try self.airReduce(inst), |
| 3246 | .shuffle => try self.airShuffle(inst), | 3255 | .shuffle_one => try self.airShuffleOne(inst), |
| 3256 | .shuffle_two => try self.airShuffleTwo(inst), | ||
| 3247 | 3257 | ||
| 3248 | .ptr_add => try self.airPtrAdd(inst), | 3258 | .ptr_add => try self.airPtrAdd(inst), |
| 3249 | .ptr_sub => try self.airPtrSub(inst), | 3259 | .ptr_sub => try self.airPtrSub(inst), |
| ... | @@ -3380,6 +3390,10 @@ const NavGen = struct { | ... | @@ -3380,6 +3390,10 @@ const NavGen = struct { |
| 3380 | const zcu = self.pt.zcu; | 3390 | const zcu = self.pt.zcu; |
| 3381 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3391 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3382 | 3392 | ||
| 3393 | if (self.typeOf(bin_op.lhs).isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { | ||
| 3394 | return self.fail("vector shift with scalar rhs", .{}); | ||
| 3395 | } | ||
| 3396 | |||
| 3383 | const base = try self.temporary(bin_op.lhs); | 3397 | const base = try self.temporary(bin_op.lhs); |
| 3384 | const shift = try self.temporary(bin_op.rhs); | 3398 | const shift = try self.temporary(bin_op.rhs); |
| 3385 | 3399 | ||
| ... | @@ -3866,6 +3880,10 @@ const NavGen = struct { | ... | @@ -3866,6 +3880,10 @@ const NavGen = struct { |
| 3866 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3880 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3867 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3881 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3868 | 3882 | ||
| 3883 | if (self.typeOf(extra.lhs).isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) { | ||
| 3884 | return self.fail("vector shift with scalar rhs", .{}); | ||
| 3885 | } | ||
| 3886 | |||
| 3869 | const base = try self.temporary(extra.lhs); | 3887 | const base = try self.temporary(extra.lhs); |
| 3870 | const shift = try self.temporary(extra.rhs); | 3888 | const shift = try self.temporary(extra.rhs); |
| 3871 | 3889 | ||
| ... | @@ -4030,40 +4048,57 @@ const NavGen = struct { | ... | @@ -4030,40 +4048,57 @@ const NavGen = struct { |
| 4030 | return result_id; | 4048 | return result_id; |
| 4031 | } | 4049 | } |
| 4032 | 4050 | ||
| 4033 | fn airShuffle(self: *NavGen, inst: Air.Inst.Index) !?IdRef { | 4051 | fn airShuffleOne(ng: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4034 | const pt = self.pt; | 4052 | const pt = ng.pt; |
| 4035 | const zcu = pt.zcu; | 4053 | const zcu = pt.zcu; |
| 4036 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4054 | const gpa = zcu.gpa; |
| 4037 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | ||
| 4038 | const a = try self.resolve(extra.a); | ||
| 4039 | const b = try self.resolve(extra.b); | ||
| 4040 | const mask = Value.fromInterned(extra.mask); | ||
| 4041 | 4055 | ||
| 4042 | // Note: number of components in the result, a, and b may differ. | 4056 | const unwrapped = ng.air.unwrapShuffleOne(zcu, inst); |
| 4043 | const result_ty = self.typeOfIndex(inst); | 4057 | const mask = unwrapped.mask; |
| 4044 | const scalar_ty = result_ty.scalarType(zcu); | 4058 | const result_ty = unwrapped.result_ty; |
| 4045 | const scalar_ty_id = try self.resolveType(scalar_ty, .direct); | 4059 | const elem_ty = result_ty.childType(zcu); |
| 4060 | const operand = try ng.resolve(unwrapped.operand); | ||
| 4046 | 4061 | ||
| 4047 | const constituents = try self.gpa.alloc(IdRef, result_ty.vectorLen(zcu)); | 4062 | const constituents = try gpa.alloc(IdRef, mask.len); |
| 4048 | defer self.gpa.free(constituents); | 4063 | defer gpa.free(constituents); |
| 4049 | 4064 | ||
| 4050 | for (constituents, 0..) |*id, i| { | 4065 | for (constituents, mask) |*id, mask_elem| { |
| 4051 | const elem = try mask.elemValue(pt, i); | 4066 | id.* = switch (mask_elem.unwrap()) { |
| 4052 | if (elem.isUndef(zcu)) { | 4067 | .elem => |idx| try ng.extractVectorComponent(elem_ty, operand, idx), |
| 4053 | id.* = try self.spv.constUndef(scalar_ty_id); | 4068 | .value => |val| try ng.constant(elem_ty, .fromInterned(val), .direct), |
| 4054 | continue; | 4069 | }; |
| 4055 | } | 4070 | } |
| 4056 | 4071 | ||
| 4057 | const index = elem.toSignedInt(zcu); | 4072 | const result_ty_id = try ng.resolveType(result_ty, .direct); |
| 4058 | if (index >= 0) { | 4073 | return try ng.constructComposite(result_ty_id, constituents); |
| 4059 | id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index)); | 4074 | } |
| 4060 | } else { | 4075 | |
| 4061 | id.* = try self.extractVectorComponent(scalar_ty, b, @intCast(~index)); | 4076 | fn airShuffleTwo(ng: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4062 | } | 4077 | const pt = ng.pt; |
| 4078 | const zcu = pt.zcu; | ||
| 4079 | const gpa = zcu.gpa; | ||
| 4080 | |||
| 4081 | const unwrapped = ng.air.unwrapShuffleTwo(zcu, inst); | ||
| 4082 | const mask = unwrapped.mask; | ||
| 4083 | const result_ty = unwrapped.result_ty; | ||
| 4084 | const elem_ty = result_ty.childType(zcu); | ||
| 4085 | const elem_ty_id = try ng.resolveType(elem_ty, .direct); | ||
| 4086 | const operand_a = try ng.resolve(unwrapped.operand_a); | ||
| 4087 | const operand_b = try ng.resolve(unwrapped.operand_b); | ||
| 4088 | |||
| 4089 | const constituents = try gpa.alloc(IdRef, mask.len); | ||
| 4090 | defer gpa.free(constituents); | ||
| 4091 | |||
| 4092 | for (constituents, mask) |*id, mask_elem| { | ||
| 4093 | id.* = switch (mask_elem.unwrap()) { | ||
| 4094 | .a_elem => |idx| try ng.extractVectorComponent(elem_ty, operand_a, idx), | ||
| 4095 | .b_elem => |idx| try ng.extractVectorComponent(elem_ty, operand_b, idx), | ||
| 4096 | .undef => try ng.spv.constUndef(elem_ty_id), | ||
| 4097 | }; | ||
| 4063 | } | 4098 | } |
| 4064 | 4099 | ||
| 4065 | const result_ty_id = try self.resolveType(result_ty, .direct); | 4100 | const result_ty_id = try ng.resolveType(result_ty, .direct); |
| 4066 | return try self.constructComposite(result_ty_id, constituents); | 4101 | return try ng.constructComposite(result_ty_id, constituents); |
| 4067 | } | 4102 | } |
| 4068 | 4103 | ||
| 4069 | fn indicesToIds(self: *NavGen, indices: []const u32) ![]IdRef { | 4104 | fn indicesToIds(self: *NavGen, indices: []const u32) ![]IdRef { |
src/dev.zig+6| ... | @@ -1,5 +1,8 @@ | ... | @@ -1,5 +1,8 @@ |
| 1 | pub const Env = enum { | 1 | pub const Env = enum { |
| 2 | /// zig1 features | 2 | /// zig1 features |
| 3 | /// - `-ofmt=c` only | ||
| 4 | /// - `-OReleaseFast` or `-OReleaseSmall` only | ||
| 5 | /// - no `@setRuntimeSafety(true)` | ||
| 3 | bootstrap, | 6 | bootstrap, |
| 4 | 7 | ||
| 5 | /// zig2 features | 8 | /// zig2 features |
| ... | @@ -67,6 +70,7 @@ pub const Env = enum { | ... | @@ -67,6 +70,7 @@ pub const Env = enum { |
| 67 | .incremental, | 70 | .incremental, |
| 68 | .ast_gen, | 71 | .ast_gen, |
| 69 | .sema, | 72 | .sema, |
| 73 | .legalize, | ||
| 70 | .llvm_backend, | 74 | .llvm_backend, |
| 71 | .c_backend, | 75 | .c_backend, |
| 72 | .wasm_backend, | 76 | .wasm_backend, |
| ... | @@ -144,6 +148,7 @@ pub const Env = enum { | ... | @@ -144,6 +148,7 @@ pub const Env = enum { |
| 144 | .build_command, | 148 | .build_command, |
| 145 | .stdio_listen, | 149 | .stdio_listen, |
| 146 | .incremental, | 150 | .incremental, |
| 151 | .legalize, | ||
| 147 | .x86_64_backend, | 152 | .x86_64_backend, |
| 148 | .elf_linker, | 153 | .elf_linker, |
| 149 | => true, | 154 | => true, |
| ... | @@ -222,6 +227,7 @@ pub const Feature = enum { | ... | @@ -222,6 +227,7 @@ pub const Feature = enum { |
| 222 | incremental, | 227 | incremental, |
| 223 | ast_gen, | 228 | ast_gen, |
| 224 | sema, | 229 | sema, |
| 230 | legalize, | ||
| 225 | 231 | ||
| 226 | llvm_backend, | 232 | llvm_backend, |
| 227 | c_backend, | 233 | c_backend, |
src/mutable_value.zig+2-2| ... | @@ -260,7 +260,7 @@ pub const MutableValue = union(enum) { | ... | @@ -260,7 +260,7 @@ pub const MutableValue = union(enum) { |
| 260 | const ptr = try arena.create(MutableValue); | 260 | const ptr = try arena.create(MutableValue); |
| 261 | const len = try arena.create(MutableValue); | 261 | const len = try arena.create(MutableValue); |
| 262 | ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) }; | 262 | ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) }; |
| 263 | len.* = .{ .interned = try pt.intern(.{ .undef = .usize_type }) }; | 263 | len.* = .{ .interned = .undef_usize }; |
| 264 | mv.* = .{ .slice = .{ | 264 | mv.* = .{ .slice = .{ |
| 265 | .ty = ty_ip, | 265 | .ty = ty_ip, |
| 266 | .ptr = ptr, | 266 | .ptr = ptr, |
| ... | @@ -464,7 +464,7 @@ pub const MutableValue = union(enum) { | ... | @@ -464,7 +464,7 @@ pub const MutableValue = union(enum) { |
| 464 | return switch (field_idx) { | 464 | return switch (field_idx) { |
| 465 | Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() }, | 465 | Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() }, |
| 466 | Value.slice_len_index => .{ .interned = switch (pt.zcu.intern_pool.indexToKey(ip_index)) { | 466 | Value.slice_len_index => .{ .interned = switch (pt.zcu.intern_pool.indexToKey(ip_index)) { |
| 467 | .undef => try pt.intern(.{ .undef = .usize_type }), | 467 | .undef => .undef_usize, |
| 468 | .slice => |s| s.len, | 468 | .slice => |s| s.len, |
| 469 | else => unreachable, | 469 | else => unreachable, |
| 470 | } }, | 470 | } }, |
src/print_air.zig+33-7| ... | @@ -315,7 +315,8 @@ const Writer = struct { | ... | @@ -315,7 +315,8 @@ const Writer = struct { |
| 315 | .wasm_memory_grow => try w.writeWasmMemoryGrow(s, inst), | 315 | .wasm_memory_grow => try w.writeWasmMemoryGrow(s, inst), |
| 316 | .mul_add => try w.writeMulAdd(s, inst), | 316 | .mul_add => try w.writeMulAdd(s, inst), |
| 317 | .select => try w.writeSelect(s, inst), | 317 | .select => try w.writeSelect(s, inst), |
| 318 | .shuffle => try w.writeShuffle(s, inst), | 318 | .shuffle_one => try w.writeShuffleOne(s, inst), |
| 319 | .shuffle_two => try w.writeShuffleTwo(s, inst), | ||
| 319 | .reduce, .reduce_optimized => try w.writeReduce(s, inst), | 320 | .reduce, .reduce_optimized => try w.writeReduce(s, inst), |
| 320 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), | 321 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), |
| 321 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), | 322 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), |
| ... | @@ -499,14 +500,39 @@ const Writer = struct { | ... | @@ -499,14 +500,39 @@ const Writer = struct { |
| 499 | try w.writeOperand(s, inst, 2, pl_op.operand); | 500 | try w.writeOperand(s, inst, 2, pl_op.operand); |
| 500 | } | 501 | } |
| 501 | 502 | ||
| 502 | fn writeShuffle(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 503 | fn writeShuffleOne(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 503 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 504 | const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst); |
| 504 | const extra = w.air.extraData(Air.Shuffle, ty_pl.payload).data; | 505 | try w.writeType(s, unwrapped.result_ty); |
| 506 | try s.writeAll(", "); | ||
| 507 | try w.writeOperand(s, inst, 0, unwrapped.operand); | ||
| 508 | try s.writeAll(", ["); | ||
| 509 | for (unwrapped.mask, 0..) |mask_elem, mask_idx| { | ||
| 510 | if (mask_idx > 0) try s.writeAll(", "); | ||
| 511 | switch (mask_elem.unwrap()) { | ||
| 512 | .elem => |idx| try s.print("elem {d}", .{idx}), | ||
| 513 | .value => |val| try s.print("val {}", .{Value.fromInterned(val).fmtValue(w.pt)}), | ||
| 514 | } | ||
| 515 | } | ||
| 516 | try s.writeByte(']'); | ||
| 517 | } | ||
| 505 | 518 | ||
| 506 | try w.writeOperand(s, inst, 0, extra.a); | 519 | fn writeShuffleTwo(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 520 | const unwrapped = w.air.unwrapShuffleTwo(w.pt.zcu, inst); | ||
| 521 | try w.writeType(s, unwrapped.result_ty); | ||
| 522 | try s.writeAll(", "); | ||
| 523 | try w.writeOperand(s, inst, 0, unwrapped.operand_a); | ||
| 507 | try s.writeAll(", "); | 524 | try s.writeAll(", "); |
| 508 | try w.writeOperand(s, inst, 1, extra.b); | 525 | try w.writeOperand(s, inst, 1, unwrapped.operand_b); |
| 509 | try s.print(", mask {d}, len {d}", .{ extra.mask, extra.mask_len }); | 526 | try s.writeAll(", ["); |
| 527 | for (unwrapped.mask, 0..) |mask_elem, mask_idx| { | ||
| 528 | if (mask_idx > 0) try s.writeAll(", "); | ||
| 529 | switch (mask_elem.unwrap()) { | ||
| 530 | .a_elem => |idx| try s.print("a_elem {d}", .{idx}), | ||
| 531 | .b_elem => |idx| try s.print("b_elem {d}", .{idx}), | ||
| 532 | .undef => try s.writeAll("undef"), | ||
| 533 | } | ||
| 534 | } | ||
| 535 | try s.writeByte(']'); | ||
| 510 | } | 536 | } |
| 511 | 537 | ||
| 512 | fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 538 | fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
src/target.zig-8| ... | @@ -842,17 +842,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt | ... | @@ -842,17 +842,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt |
| 842 | .stage2_c, .stage2_llvm, .stage2_x86_64 => true, | 842 | .stage2_c, .stage2_llvm, .stage2_x86_64 => true, |
| 843 | else => false, | 843 | else => false, |
| 844 | }, | 844 | }, |
| 845 | .safety_checked_instructions => switch (backend) { | ||
| 846 | .stage2_llvm => true, | ||
| 847 | else => false, | ||
| 848 | }, | ||
| 849 | .separate_thread => switch (backend) { | 845 | .separate_thread => switch (backend) { |
| 850 | .stage2_llvm => false, | 846 | .stage2_llvm => false, |
| 851 | else => true, | 847 | else => true, |
| 852 | }, | 848 | }, |
| 853 | .all_vector_instructions => switch (backend) { | ||
| 854 | .stage2_x86_64 => true, | ||
| 855 | else => false, | ||
| 856 | }, | ||
| 857 | }; | 849 | }; |
| 858 | } | 850 | } |
stage1/zig.h+21-11| ... | @@ -481,6 +481,7 @@ | ... | @@ -481,6 +481,7 @@ |
| 481 | 481 | ||
| 482 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); | 482 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); |
| 483 | zig_extern void *memset (void *, int, size_t); | 483 | zig_extern void *memset (void *, int, size_t); |
| 484 | zig_extern void *memmove (void *, void const *, size_t); | ||
| 484 | 485 | ||
| 485 | /* ================ Bool and 8/16/32/64-bit Integer Support ================= */ | 486 | /* ================ Bool and 8/16/32/64-bit Integer Support ================= */ |
| 486 | 487 | ||
| ... | @@ -1114,14 +1115,15 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1114,14 +1115,15 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1114 | \ | 1115 | \ |
| 1115 | static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1116 | static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 1116 | uint##w##_t res; \ | 1117 | uint##w##_t res; \ |
| 1117 | if (rhs >= bits) return lhs != UINT##w##_C(0) ? zig_maxInt_u(w, bits) : lhs; \ | 1118 | if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \ |
| 1118 | return zig_shlo_u##w(&res, lhs, (uint8_t)rhs, bits) ? zig_maxInt_u(w, bits) : res; \ | 1119 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \ |
| 1119 | } \ | 1120 | } \ |
| 1120 | \ | 1121 | \ |
| 1121 | static inline int##w##_t zig_shls_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1122 | static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 1122 | int##w##_t res; \ | 1123 | int##w##_t res; \ |
| 1123 | if ((uint##w##_t)rhs < (uint##w##_t)bits && !zig_shlo_i##w(&res, lhs, (uint8_t)rhs, bits)) return res; \ | 1124 | if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \ |
| 1124 | return lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | 1125 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ |
| 1126 | lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | ||
| 1125 | } \ | 1127 | } \ |
| 1126 | \ | 1128 | \ |
| 1127 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1129 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| ... | @@ -1850,15 +1852,23 @@ static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8 | ... | @@ -1850,15 +1852,23 @@ static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8 |
| 1850 | 1852 | ||
| 1851 | static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1853 | static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 1852 | zig_u128 res; | 1854 | zig_u128 res; |
| 1853 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) >= INT32_C(0)) | 1855 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 1854 | return zig_cmp_u128(lhs, zig_make_u128(0, 0)) != INT32_C(0) ? zig_maxInt_u(128, bits) : lhs; | 1856 | switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) { |
| 1855 | return zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits) ? zig_maxInt_u(128, bits) : res; | 1857 | case 0: return zig_make_u128(0, 0); |
| 1858 | case 1: return zig_maxInt_u(128, bits); | ||
| 1859 | default: zig_unreachable(); | ||
| 1860 | } | ||
| 1856 | } | 1861 | } |
| 1857 | 1862 | ||
| 1858 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 1863 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { |
| 1859 | zig_i128 res; | 1864 | zig_i128 res; |
| 1860 | if (zig_cmp_u128(zig_bitCast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res; | 1865 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 1861 | return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); | 1866 | switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) { |
| 1867 | case -1: return zig_minInt_i(128, bits); | ||
| 1868 | case 0: return zig_make_i128(0, 0); | ||
| 1869 | case 1: return zig_maxInt_i(128, bits); | ||
| 1870 | default: zig_unreachable(); | ||
| 1871 | } | ||
| 1862 | } | 1872 | } |
| 1863 | 1873 | ||
| 1864 | static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1874 | static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ | |||
test/behavior/abs.zig-2| ... | @@ -96,7 +96,6 @@ test "@abs big int <= 128 bits" { | ... | @@ -96,7 +96,6 @@ test "@abs big int <= 128 bits" { |
| 96 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 96 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 97 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 97 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 98 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 98 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 99 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 100 | 99 | ||
| 101 | try comptime testAbsSignedBigInt(); | 100 | try comptime testAbsSignedBigInt(); |
| 102 | try testAbsSignedBigInt(); | 101 | try testAbsSignedBigInt(); |
| ... | @@ -211,7 +210,6 @@ fn testAbsFloats(comptime T: type) !void { | ... | @@ -211,7 +210,6 @@ fn testAbsFloats(comptime T: type) !void { |
| 211 | test "@abs int vectors" { | 210 | test "@abs int vectors" { |
| 212 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 211 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 213 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 212 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 214 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 215 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 213 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 216 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 214 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 217 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/basic.zig-1| ... | @@ -837,7 +837,6 @@ test "extern variable with non-pointer opaque type" { | ... | @@ -837,7 +837,6 @@ test "extern variable with non-pointer opaque type" { |
| 837 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 837 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 838 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 838 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 839 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 839 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 840 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 841 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 840 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 842 | 841 | ||
| 843 | @export(&var_to_export, .{ .name = "opaque_extern_var" }); | 842 | @export(&var_to_export, .{ .name = "opaque_extern_var" }); |
test/behavior/bitcast.zig-1| ... | @@ -384,7 +384,6 @@ test "comptime bitcast with fields following f80" { | ... | @@ -384,7 +384,6 @@ test "comptime bitcast with fields following f80" { |
| 384 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 384 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 385 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 385 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 386 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 386 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 387 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 388 | 387 | ||
| 389 | const FloatT = extern struct { f: f80, x: u128 align(16) }; | 388 | const FloatT = extern struct { f: f80, x: u128 align(16) }; |
| 390 | const x: FloatT = .{ .f = 0.5, .x = 123 }; | 389 | const x: FloatT = .{ .f = 0.5, .x = 123 }; |
test/behavior/bitreverse.zig-4| ... | @@ -12,7 +12,6 @@ test "@bitReverse" { | ... | @@ -12,7 +12,6 @@ test "@bitReverse" { |
| 12 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 16 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 17 | 16 | ||
| 18 | try comptime testBitReverse(); | 17 | try comptime testBitReverse(); |
| ... | @@ -123,7 +122,6 @@ fn vector8() !void { | ... | @@ -123,7 +122,6 @@ fn vector8() !void { |
| 123 | 122 | ||
| 124 | test "bitReverse vectors u8" { | 123 | test "bitReverse vectors u8" { |
| 125 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 124 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 126 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 127 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 125 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 128 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 126 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 127 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -144,7 +142,6 @@ fn vector16() !void { | ... | @@ -144,7 +142,6 @@ fn vector16() !void { |
| 144 | 142 | ||
| 145 | test "bitReverse vectors u16" { | 143 | test "bitReverse vectors u16" { |
| 146 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 144 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 147 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 148 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 145 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 146 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 150 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 147 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -165,7 +162,6 @@ fn vector24() !void { | ... | @@ -165,7 +162,6 @@ fn vector24() !void { |
| 165 | 162 | ||
| 166 | test "bitReverse vectors u24" { | 163 | test "bitReverse vectors u24" { |
| 167 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 164 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 168 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 169 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 165 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 166 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 171 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 167 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/byteswap.zig-4| ... | @@ -39,7 +39,6 @@ test "@byteSwap integers" { | ... | @@ -39,7 +39,6 @@ test "@byteSwap integers" { |
| 39 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 39 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 40 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 40 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 41 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 41 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 42 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 43 | 42 | ||
| 44 | const ByteSwapIntTest = struct { | 43 | const ByteSwapIntTest = struct { |
| 45 | fn run() !void { | 44 | fn run() !void { |
| ... | @@ -95,7 +94,6 @@ fn vector8() !void { | ... | @@ -95,7 +94,6 @@ fn vector8() !void { |
| 95 | 94 | ||
| 96 | test "@byteSwap vectors u8" { | 95 | test "@byteSwap vectors u8" { |
| 97 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 96 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 98 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 99 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 97 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 100 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 98 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 101 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 99 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -116,7 +114,6 @@ fn vector16() !void { | ... | @@ -116,7 +114,6 @@ fn vector16() !void { |
| 116 | 114 | ||
| 117 | test "@byteSwap vectors u16" { | 115 | test "@byteSwap vectors u16" { |
| 118 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 116 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 119 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 120 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 117 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 121 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 118 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 122 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -137,7 +134,6 @@ fn vector24() !void { | ... | @@ -137,7 +134,6 @@ fn vector24() !void { |
| 137 | 134 | ||
| 138 | test "@byteSwap vectors u24" { | 135 | test "@byteSwap vectors u24" { |
| 139 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 136 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 140 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 137 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 142 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 143 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/cast.zig-4| ... | @@ -617,7 +617,6 @@ test "@intCast on vector" { | ... | @@ -617,7 +617,6 @@ test "@intCast on vector" { |
| 617 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 617 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 618 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 618 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 619 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 619 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 620 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 621 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 620 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 622 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 621 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 623 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 622 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -2520,7 +2519,6 @@ test "@ptrFromInt on vector" { | ... | @@ -2520,7 +2519,6 @@ test "@ptrFromInt on vector" { |
| 2520 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2519 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2521 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2520 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2522 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2521 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2523 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 2524 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 2522 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 2525 | 2523 | ||
| 2526 | const S = struct { | 2524 | const S = struct { |
| ... | @@ -2592,7 +2590,6 @@ test "@intFromFloat on vector" { | ... | @@ -2592,7 +2590,6 @@ test "@intFromFloat on vector" { |
| 2592 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2590 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2593 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2591 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2594 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2592 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2595 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 2596 | 2593 | ||
| 2597 | const S = struct { | 2594 | const S = struct { |
| 2598 | fn doTheTest() !void { | 2595 | fn doTheTest() !void { |
| ... | @@ -2693,7 +2690,6 @@ test "@intCast vector of signed integer" { | ... | @@ -2693,7 +2690,6 @@ test "@intCast vector of signed integer" { |
| 2693 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2690 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2694 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2691 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2695 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2692 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2696 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2697 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2693 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2698 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 2694 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 2699 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 2695 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
test/behavior/extern.zig-1| ... | @@ -5,7 +5,6 @@ const expect = std.testing.expect; | ... | @@ -5,7 +5,6 @@ const expect = std.testing.expect; |
| 5 | test "anyopaque extern symbol" { | 5 | test "anyopaque extern symbol" { |
| 6 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 9 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 8 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 10 | 9 | ||
| 11 | const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" }); | 10 | const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" }); |
test/behavior/floatop.zig+36-15| ... | @@ -14,9 +14,11 @@ fn epsForType(comptime T: type) T { | ... | @@ -14,9 +14,11 @@ fn epsForType(comptime T: type) T { |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | test "add f16" { | 16 | test "add f16" { |
| 17 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 18 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 17 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 19 | 18 | ||
| 19 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 20 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 21 | |||
| 20 | try testAdd(f16); | 22 | try testAdd(f16); |
| 21 | try comptime testAdd(f16); | 23 | try comptime testAdd(f16); |
| 22 | } | 24 | } |
| ... | @@ -123,10 +125,12 @@ fn testMul(comptime T: type) !void { | ... | @@ -123,10 +125,12 @@ fn testMul(comptime T: type) !void { |
| 123 | 125 | ||
| 124 | test "cmp f16" { | 126 | test "cmp f16" { |
| 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 127 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 126 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 127 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 128 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 128 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | 129 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 |
| 129 | 130 | ||
| 131 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 132 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 133 | |||
| 130 | try testCmp(f16); | 134 | try testCmp(f16); |
| 131 | try comptime testCmp(f16); | 135 | try comptime testCmp(f16); |
| 132 | } | 136 | } |
| ... | @@ -135,7 +139,6 @@ test "cmp f32" { | ... | @@ -135,7 +139,6 @@ test "cmp f32" { |
| 135 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 139 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 136 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 140 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 137 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | 141 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 |
| 138 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 139 | 142 | ||
| 140 | try testCmp(f32); | 143 | try testCmp(f32); |
| 141 | try comptime testCmp(f32); | 144 | try comptime testCmp(f32); |
| ... | @@ -144,7 +147,6 @@ test "cmp f32" { | ... | @@ -144,7 +147,6 @@ test "cmp f32" { |
| 144 | test "cmp f64" { | 147 | test "cmp f64" { |
| 145 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 148 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 146 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 147 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 148 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | 150 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 |
| 149 | 151 | ||
| 150 | try testCmp(f64); | 152 | try testCmp(f64); |
| ... | @@ -340,9 +342,11 @@ test "different sized float comparisons" { | ... | @@ -340,9 +342,11 @@ test "different sized float comparisons" { |
| 340 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 342 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 341 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 343 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 342 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 344 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 343 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 344 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 345 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 345 | 346 | ||
| 347 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 348 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 349 | |||
| 346 | try testDifferentSizedFloatComparisons(); | 350 | try testDifferentSizedFloatComparisons(); |
| 347 | try comptime testDifferentSizedFloatComparisons(); | 351 | try comptime testDifferentSizedFloatComparisons(); |
| 348 | } | 352 | } |
| ... | @@ -388,10 +392,12 @@ test "@sqrt f16" { | ... | @@ -388,10 +392,12 @@ test "@sqrt f16" { |
| 388 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 392 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 389 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 393 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 390 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 394 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 391 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 392 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 395 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 393 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 396 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 394 | 397 | ||
| 398 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 399 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 400 | |||
| 395 | try testSqrt(f16); | 401 | try testSqrt(f16); |
| 396 | try comptime testSqrt(f16); | 402 | try comptime testSqrt(f16); |
| 397 | } | 403 | } |
| ... | @@ -400,7 +406,6 @@ test "@sqrt f32/f64" { | ... | @@ -400,7 +406,6 @@ test "@sqrt f32/f64" { |
| 400 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 406 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 401 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 407 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 402 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 408 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 403 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 404 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 409 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 405 | 410 | ||
| 406 | try testSqrt(f32); | 411 | try testSqrt(f32); |
| ... | @@ -1132,9 +1137,11 @@ test "@abs f16" { | ... | @@ -1132,9 +1137,11 @@ test "@abs f16" { |
| 1132 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1137 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1133 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1134 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1135 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1136 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1140 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1137 | 1141 | ||
| 1142 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1143 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 1144 | |||
| 1138 | try testFabs(f16); | 1145 | try testFabs(f16); |
| 1139 | try comptime testFabs(f16); | 1146 | try comptime testFabs(f16); |
| 1140 | } | 1147 | } |
| ... | @@ -1266,9 +1273,11 @@ test "@floor f32/f64" { | ... | @@ -1266,9 +1273,11 @@ test "@floor f32/f64" { |
| 1266 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1273 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1267 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1274 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1268 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1275 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1269 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1270 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1276 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1271 | 1277 | ||
| 1278 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1279 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1280 | |||
| 1272 | try testFloor(f32); | 1281 | try testFloor(f32); |
| 1273 | try comptime testFloor(f32); | 1282 | try comptime testFloor(f32); |
| 1274 | try testFloor(f64); | 1283 | try testFloor(f64); |
| ... | @@ -1332,7 +1341,9 @@ test "@floor with vectors" { | ... | @@ -1332,7 +1341,9 @@ test "@floor with vectors" { |
| 1332 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1341 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1333 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1342 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1334 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1343 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1335 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1344 | |
| 1345 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1346 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1336 | 1347 | ||
| 1337 | try testFloorWithVectors(); | 1348 | try testFloorWithVectors(); |
| 1338 | try comptime testFloorWithVectors(); | 1349 | try comptime testFloorWithVectors(); |
| ... | @@ -1363,9 +1374,11 @@ test "@ceil f32/f64" { | ... | @@ -1363,9 +1374,11 @@ test "@ceil f32/f64" { |
| 1363 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1374 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1364 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1375 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1365 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1376 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1366 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1367 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1377 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1368 | 1378 | ||
| 1379 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1380 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1381 | |||
| 1369 | try testCeil(f32); | 1382 | try testCeil(f32); |
| 1370 | try comptime testCeil(f32); | 1383 | try comptime testCeil(f32); |
| 1371 | try testCeil(f64); | 1384 | try testCeil(f64); |
| ... | @@ -1429,7 +1442,9 @@ test "@ceil with vectors" { | ... | @@ -1429,7 +1442,9 @@ test "@ceil with vectors" { |
| 1429 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1442 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1430 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1443 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1431 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1444 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1432 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1445 | |
| 1446 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1447 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1433 | 1448 | ||
| 1434 | try testCeilWithVectors(); | 1449 | try testCeilWithVectors(); |
| 1435 | try comptime testCeilWithVectors(); | 1450 | try comptime testCeilWithVectors(); |
| ... | @@ -1460,9 +1475,11 @@ test "@trunc f32/f64" { | ... | @@ -1460,9 +1475,11 @@ test "@trunc f32/f64" { |
| 1460 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1475 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1461 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1462 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1477 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1463 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1464 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1478 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1465 | 1479 | ||
| 1480 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1481 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1482 | |||
| 1466 | try testTrunc(f32); | 1483 | try testTrunc(f32); |
| 1467 | try comptime testTrunc(f32); | 1484 | try comptime testTrunc(f32); |
| 1468 | try testTrunc(f64); | 1485 | try testTrunc(f64); |
| ... | @@ -1526,7 +1543,9 @@ test "@trunc with vectors" { | ... | @@ -1526,7 +1543,9 @@ test "@trunc with vectors" { |
| 1526 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1543 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1527 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1544 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1528 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1545 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1529 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1546 | |
| 1547 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1548 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1530 | 1549 | ||
| 1531 | try testTruncWithVectors(); | 1550 | try testTruncWithVectors(); |
| 1532 | try comptime testTruncWithVectors(); | 1551 | try comptime testTruncWithVectors(); |
| ... | @@ -1546,9 +1565,11 @@ test "neg f16" { | ... | @@ -1546,9 +1565,11 @@ test "neg f16" { |
| 1546 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1565 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1547 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1566 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1548 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1567 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1549 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1550 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1568 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1551 | 1569 | ||
| 1570 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1571 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 1572 | |||
| 1552 | if (builtin.os.tag == .freebsd) { | 1573 | if (builtin.os.tag == .freebsd) { |
| 1553 | // TODO file issue to track this failure | 1574 | // TODO file issue to track this failure |
| 1554 | return error.SkipZigTest; | 1575 | return error.SkipZigTest; |
test/behavior/fn.zig-1| ... | @@ -429,7 +429,6 @@ test "implicit cast function to function ptr" { | ... | @@ -429,7 +429,6 @@ test "implicit cast function to function ptr" { |
| 429 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 429 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 430 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 430 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 431 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 431 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 432 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 433 | 432 | ||
| 434 | const S1 = struct { | 433 | const S1 = struct { |
| 435 | export fn someFunctionThatReturnsAValue() c_int { | 434 | export fn someFunctionThatReturnsAValue() c_int { |
test/behavior/math.zig+7-13| ... | @@ -85,7 +85,6 @@ test "@clz big ints" { | ... | @@ -85,7 +85,6 @@ test "@clz big ints" { |
| 85 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 85 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 86 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 86 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 87 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 87 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 88 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 89 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 88 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 90 | 89 | ||
| 91 | try testClzBigInts(); | 90 | try testClzBigInts(); |
| ... | @@ -103,7 +102,6 @@ fn testOneClz(comptime T: type, x: T) u32 { | ... | @@ -103,7 +102,6 @@ fn testOneClz(comptime T: type, x: T) u32 { |
| 103 | 102 | ||
| 104 | test "@clz vectors" { | 103 | test "@clz vectors" { |
| 105 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 104 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 106 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 107 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 105 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 108 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 106 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 107 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -173,7 +171,6 @@ fn testOneCtz(comptime T: type, x: T) u32 { | ... | @@ -173,7 +171,6 @@ fn testOneCtz(comptime T: type, x: T) u32 { |
| 173 | } | 171 | } |
| 174 | 172 | ||
| 175 | test "@ctz 128-bit integers" { | 173 | test "@ctz 128-bit integers" { |
| 176 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 177 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 174 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 178 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 175 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 179 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 176 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -193,7 +190,6 @@ fn testCtz128() !void { | ... | @@ -193,7 +190,6 @@ fn testCtz128() !void { |
| 193 | 190 | ||
| 194 | test "@ctz vectors" { | 191 | test "@ctz vectors" { |
| 195 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 192 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 196 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 197 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 193 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 198 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 194 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 199 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 195 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -475,10 +471,12 @@ test "division" { | ... | @@ -475,10 +471,12 @@ test "division" { |
| 475 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 471 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 472 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 477 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 478 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 479 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 474 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 480 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 475 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 481 | 476 | ||
| 477 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 478 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 479 | |||
| 482 | try testIntDivision(); | 480 | try testIntDivision(); |
| 483 | try comptime testIntDivision(); | 481 | try comptime testIntDivision(); |
| 484 | 482 | ||
| ... | @@ -1623,10 +1621,10 @@ test "vector integer addition" { | ... | @@ -1623,10 +1621,10 @@ test "vector integer addition" { |
| 1623 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1621 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1624 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1622 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1625 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1623 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1626 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1627 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1624 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1628 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1625 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1629 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1626 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1627 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1630 | 1628 | ||
| 1631 | const S = struct { | 1629 | const S = struct { |
| 1632 | fn doTheTest() !void { | 1630 | fn doTheTest() !void { |
| ... | @@ -1694,9 +1692,6 @@ test "vector comparison" { | ... | @@ -1694,9 +1692,6 @@ test "vector comparison" { |
| 1694 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1692 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1695 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1693 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1696 | 1694 | ||
| 1697 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 1698 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return error.SkipZigTest; | ||
| 1699 | |||
| 1700 | const S = struct { | 1695 | const S = struct { |
| 1701 | fn doTheTest() !void { | 1696 | fn doTheTest() !void { |
| 1702 | var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 }; | 1697 | var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 }; |
| ... | @@ -1785,7 +1780,6 @@ test "mod lazy values" { | ... | @@ -1785,7 +1780,6 @@ test "mod lazy values" { |
| 1785 | 1780 | ||
| 1786 | test "@clz works on both vector and scalar inputs" { | 1781 | test "@clz works on both vector and scalar inputs" { |
| 1787 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1782 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1788 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1789 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1783 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1790 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1784 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1791 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1785 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1807,7 +1801,6 @@ test "runtime comparison to NaN is comptime-known" { | ... | @@ -1807,7 +1801,6 @@ test "runtime comparison to NaN is comptime-known" { |
| 1807 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1801 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1808 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1802 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1809 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1803 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1810 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1811 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1804 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1812 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | 1805 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 |
| 1813 | 1806 | ||
| ... | @@ -1838,7 +1831,6 @@ test "runtime int comparison to inf is comptime-known" { | ... | @@ -1838,7 +1831,6 @@ test "runtime int comparison to inf is comptime-known" { |
| 1838 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1831 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1839 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1832 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1840 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1833 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1841 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1842 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1834 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1843 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | 1835 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 |
| 1844 | 1836 | ||
| ... | @@ -1936,7 +1928,9 @@ test "float vector division of comptime zero by runtime nan is nan" { | ... | @@ -1936,7 +1928,9 @@ test "float vector division of comptime zero by runtime nan is nan" { |
| 1936 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1928 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1937 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1929 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1938 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1930 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1939 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1931 | |
| 1932 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 1933 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 1940 | 1934 | ||
| 1941 | const ct_zero: @Vector(1, f32) = .{0}; | 1935 | const ct_zero: @Vector(1, f32) = .{0}; |
| 1942 | var rt_nan: @Vector(1, f32) = .{math.nan(f32)}; | 1936 | var rt_nan: @Vector(1, f32) = .{math.nan(f32)}; |
test/behavior/maximum_minimum.zig-6| ... | @@ -34,7 +34,6 @@ test "@max on vectors" { | ... | @@ -34,7 +34,6 @@ test "@max on vectors" { |
| 34 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 34 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 35 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 35 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 36 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 36 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 37 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 38 | 37 | ||
| 39 | const S = struct { | 38 | const S = struct { |
| 40 | fn doTheTest() !void { | 39 | fn doTheTest() !void { |
| ... | @@ -90,7 +89,6 @@ test "@min for vectors" { | ... | @@ -90,7 +89,6 @@ test "@min for vectors" { |
| 90 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 89 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 91 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 90 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 92 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 91 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 93 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 94 | 92 | ||
| 95 | const S = struct { | 93 | const S = struct { |
| 96 | fn doTheTest() !void { | 94 | fn doTheTest() !void { |
| ... | @@ -206,7 +204,6 @@ test "@min/@max notices vector bounds" { | ... | @@ -206,7 +204,6 @@ test "@min/@max notices vector bounds" { |
| 206 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 204 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 207 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 208 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 206 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 209 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 210 | 207 | ||
| 211 | var x: @Vector(2, u16) = .{ 140, 40 }; | 208 | var x: @Vector(2, u16) = .{ 140, 40 }; |
| 212 | const y: @Vector(2, u64) = .{ 5, 100 }; | 209 | const y: @Vector(2, u64) = .{ 5, 100 }; |
| ... | @@ -260,7 +257,6 @@ test "@min/@max notices bounds from vector types" { | ... | @@ -260,7 +257,6 @@ test "@min/@max notices bounds from vector types" { |
| 260 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 257 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 261 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 262 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 259 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 263 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 264 | 260 | ||
| 265 | var x: @Vector(2, u16) = .{ 30, 67 }; | 261 | var x: @Vector(2, u16) = .{ 30, 67 }; |
| 266 | var y: @Vector(2, u32) = .{ 20, 500 }; | 262 | var y: @Vector(2, u32) = .{ 20, 500 }; |
| ... | @@ -303,7 +299,6 @@ test "@min/@max notices bounds from vector types when element of comptime-known | ... | @@ -303,7 +299,6 @@ test "@min/@max notices bounds from vector types when element of comptime-known |
| 303 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 299 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 304 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 300 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 305 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 301 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 306 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 307 | 302 | ||
| 308 | var x: @Vector(2, u32) = .{ 1_000_000, 12345 }; | 303 | var x: @Vector(2, u32) = .{ 1_000_000, 12345 }; |
| 309 | _ = &x; | 304 | _ = &x; |
| ... | @@ -375,7 +370,6 @@ test "@min/@max with runtime vectors of signed and unsigned integers of same siz | ... | @@ -375,7 +370,6 @@ test "@min/@max with runtime vectors of signed and unsigned integers of same siz |
| 375 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 370 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 376 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 371 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 377 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 372 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 378 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 379 | 373 | ||
| 380 | const S = struct { | 374 | const S = struct { |
| 381 | fn min(a: @Vector(2, i32), b: @Vector(2, u32)) @Vector(2, i32) { | 375 | fn min(a: @Vector(2, i32), b: @Vector(2, u32)) @Vector(2, i32) { |
test/behavior/muladd.zig+9-3| ... | @@ -6,10 +6,12 @@ test "@mulAdd" { | ... | @@ -6,10 +6,12 @@ test "@mulAdd" { |
| 6 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 10 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 11 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 10 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 12 | 11 | ||
| 12 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 13 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest; | ||
| 14 | |||
| 13 | try comptime testMulAdd(); | 15 | try comptime testMulAdd(); |
| 14 | try testMulAdd(); | 16 | try testMulAdd(); |
| 15 | } | 17 | } |
| ... | @@ -137,10 +139,12 @@ test "vector f32" { | ... | @@ -137,10 +139,12 @@ test "vector f32" { |
| 137 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 139 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 141 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 140 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 141 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 142 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 142 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 143 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 143 | 144 | ||
| 145 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 146 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest; | ||
| 147 | |||
| 144 | try comptime vector32(); | 148 | try comptime vector32(); |
| 145 | try vector32(); | 149 | try vector32(); |
| 146 | } | 150 | } |
| ... | @@ -163,10 +167,12 @@ test "vector f64" { | ... | @@ -163,10 +167,12 @@ test "vector f64" { |
| 163 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 164 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 168 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 169 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 166 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 167 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 170 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 168 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 171 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 169 | 172 | ||
| 173 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 174 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest; | ||
| 175 | |||
| 170 | try comptime vector64(); | 176 | try comptime vector64(); |
| 171 | try vector64(); | 177 | try vector64(); |
| 172 | } | 178 | } |
test/behavior/packed-struct.zig+11| ... | @@ -1307,6 +1307,17 @@ test "packed struct equality" { | ... | @@ -1307,6 +1307,17 @@ test "packed struct equality" { |
| 1307 | comptime try S.doTest(x, y); | 1307 | comptime try S.doTest(x, y); |
| 1308 | } | 1308 | } |
| 1309 | 1309 | ||
| 1310 | test "packed struct equality ignores padding bits" { | ||
| 1311 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1312 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1313 | |||
| 1314 | const S = packed struct { b: bool }; | ||
| 1315 | var s: S = undefined; | ||
| 1316 | s.b = true; | ||
| 1317 | try std.testing.expect(s != S{ .b = false }); | ||
| 1318 | try std.testing.expect(s == S{ .b = true }); | ||
| 1319 | } | ||
| 1320 | |||
| 1310 | test "packed struct with signed field" { | 1321 | test "packed struct with signed field" { |
| 1311 | var s: packed struct { | 1322 | var s: packed struct { |
| 1312 | a: i2, | 1323 | a: i2, |
test/behavior/popcount.zig-1| ... | @@ -77,7 +77,6 @@ fn testPopCountIntegers() !void { | ... | @@ -77,7 +77,6 @@ fn testPopCountIntegers() !void { |
| 77 | 77 | ||
| 78 | test "@popCount vectors" { | 78 | test "@popCount vectors" { |
| 79 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 81 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 80 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 82 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 81 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 83 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 82 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/select.zig-3| ... | @@ -41,8 +41,6 @@ test "@select arrays" { | ... | @@ -41,8 +41,6 @@ test "@select arrays" { |
| 41 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 41 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 42 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 42 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 43 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 43 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 44 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 45 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return error.SkipZigTest; | ||
| 46 | 44 | ||
| 47 | try comptime selectArrays(); | 45 | try comptime selectArrays(); |
| 48 | try selectArrays(); | 46 | try selectArrays(); |
| ... | @@ -70,7 +68,6 @@ fn selectArrays() !void { | ... | @@ -70,7 +68,6 @@ fn selectArrays() !void { |
| 70 | test "@select compare result" { | 68 | test "@select compare result" { |
| 71 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 69 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 72 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 70 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 73 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 74 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 71 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 75 | 72 | ||
| 76 | const S = struct { | 73 | const S = struct { |
test/behavior/shuffle.zig-5| ... | @@ -10,8 +10,6 @@ test "@shuffle int" { | ... | @@ -10,8 +10,6 @@ test "@shuffle int" { |
| 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 11 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 14 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .ssse3)) return error.SkipZigTest; | ||
| 15 | 13 | ||
| 16 | const S = struct { | 14 | const S = struct { |
| 17 | fn doTheTest() !void { | 15 | fn doTheTest() !void { |
| ... | @@ -53,7 +51,6 @@ test "@shuffle int" { | ... | @@ -53,7 +51,6 @@ test "@shuffle int" { |
| 53 | 51 | ||
| 54 | test "@shuffle int strange sizes" { | 52 | test "@shuffle int strange sizes" { |
| 55 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 53 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 56 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 57 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 55 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 59 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 56 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -136,7 +133,6 @@ fn testShuffle( | ... | @@ -136,7 +133,6 @@ fn testShuffle( |
| 136 | 133 | ||
| 137 | test "@shuffle bool 1" { | 134 | test "@shuffle bool 1" { |
| 138 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 135 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 139 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 136 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 137 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 138 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -160,7 +156,6 @@ test "@shuffle bool 1" { | ... | @@ -160,7 +156,6 @@ test "@shuffle bool 1" { |
| 160 | 156 | ||
| 161 | test "@shuffle bool 2" { | 157 | test "@shuffle bool 2" { |
| 162 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 158 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 163 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 164 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 159 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 165 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 160 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 166 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 161 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/union.zig+1| ... | @@ -282,6 +282,7 @@ test "cast union to tag type of union" { | ... | @@ -282,6 +282,7 @@ test "cast union to tag type of union" { |
| 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 283 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 283 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 284 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 284 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 285 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 285 | 286 | ||
| 286 | try testCastUnionToTag(); | 287 | try testCastUnionToTag(); |
| 287 | try comptime testCastUnionToTag(); | 288 | try comptime testCastUnionToTag(); |
test/behavior/vector.zig+9-20| ... | @@ -31,7 +31,6 @@ test "vector wrap operators" { | ... | @@ -31,7 +31,6 @@ test "vector wrap operators" { |
| 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 32 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 33 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 33 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 34 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 35 | 34 | ||
| 36 | const S = struct { | 35 | const S = struct { |
| 37 | fn doTheTest() !void { | 36 | fn doTheTest() !void { |
| ... | @@ -76,12 +75,12 @@ test "vector bin compares with mem.eql" { | ... | @@ -76,12 +75,12 @@ test "vector bin compares with mem.eql" { |
| 76 | 75 | ||
| 77 | test "vector int operators" { | 76 | test "vector int operators" { |
| 78 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 79 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 80 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 78 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 81 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 82 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 80 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 83 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 81 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 84 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 82 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 83 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 85 | 84 | ||
| 86 | const S = struct { | 85 | const S = struct { |
| 87 | fn doTheTest() !void { | 86 | fn doTheTest() !void { |
| ... | @@ -249,9 +248,11 @@ test "array to vector with element type coercion" { | ... | @@ -249,9 +248,11 @@ test "array to vector with element type coercion" { |
| 249 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 248 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 250 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 249 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 251 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 250 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 252 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 253 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 251 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 254 | 252 | ||
| 253 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and | ||
| 254 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; | ||
| 255 | |||
| 255 | const S = struct { | 256 | const S = struct { |
| 256 | fn doTheTest() !void { | 257 | fn doTheTest() !void { |
| 257 | var foo: f16 = 3.14; | 258 | var foo: f16 = 3.14; |
| ... | @@ -286,11 +287,11 @@ test "peer type resolution with coercible element types" { | ... | @@ -286,11 +287,11 @@ test "peer type resolution with coercible element types" { |
| 286 | 287 | ||
| 287 | test "tuple to vector" { | 288 | test "tuple to vector" { |
| 288 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 289 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 289 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 290 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 290 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 291 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 291 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 292 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 292 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 293 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 293 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 294 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 294 | 295 | ||
| 295 | const S = struct { | 296 | const S = struct { |
| 296 | fn doTheTest() !void { | 297 | fn doTheTest() !void { |
| ... | @@ -652,7 +653,6 @@ test "vector division operators" { | ... | @@ -652,7 +653,6 @@ test "vector division operators" { |
| 652 | test "vector bitwise not operator" { | 653 | test "vector bitwise not operator" { |
| 653 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 654 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 654 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 655 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 655 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 656 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 656 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 657 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 657 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 658 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 658 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -684,12 +684,12 @@ test "vector bitwise not operator" { | ... | @@ -684,12 +684,12 @@ test "vector bitwise not operator" { |
| 684 | 684 | ||
| 685 | test "vector shift operators" { | 685 | test "vector shift operators" { |
| 686 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 686 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 687 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 688 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 687 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 689 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 688 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 690 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 689 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 691 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 690 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 692 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 691 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 692 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 693 | 693 | ||
| 694 | const S = struct { | 694 | const S = struct { |
| 695 | fn doTheTestShift(x: anytype, y: anytype) !void { | 695 | fn doTheTestShift(x: anytype, y: anytype) !void { |
| ... | @@ -908,8 +908,6 @@ test "mask parameter of @shuffle is comptime scope" { | ... | @@ -908,8 +908,6 @@ test "mask parameter of @shuffle is comptime scope" { |
| 908 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 908 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 909 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 909 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 910 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 910 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 911 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 912 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .ssse3)) return error.SkipZigTest; | ||
| 913 | 911 | ||
| 914 | const __v4hi = @Vector(4, i16); | 912 | const __v4hi = @Vector(4, i16); |
| 915 | var v4_a = __v4hi{ 1, 2, 3, 4 }; | 913 | var v4_a = __v4hi{ 1, 2, 3, 4 }; |
| ... | @@ -934,7 +932,6 @@ test "saturating add" { | ... | @@ -934,7 +932,6 @@ test "saturating add" { |
| 934 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 932 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 935 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 933 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 936 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 934 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 937 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 938 | 935 | ||
| 939 | const S = struct { | 936 | const S = struct { |
| 940 | fn doTheTest() !void { | 937 | fn doTheTest() !void { |
| ... | @@ -969,7 +966,6 @@ test "saturating subtraction" { | ... | @@ -969,7 +966,6 @@ test "saturating subtraction" { |
| 969 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 966 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 970 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 967 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 971 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 968 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 972 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 973 | 969 | ||
| 974 | const S = struct { | 970 | const S = struct { |
| 975 | fn doTheTest() !void { | 971 | fn doTheTest() !void { |
| ... | @@ -989,7 +985,6 @@ test "saturating subtraction" { | ... | @@ -989,7 +985,6 @@ test "saturating subtraction" { |
| 989 | 985 | ||
| 990 | test "saturating multiplication" { | 986 | test "saturating multiplication" { |
| 991 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 987 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 992 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 993 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 988 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 994 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 989 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 995 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 990 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1018,12 +1013,12 @@ test "saturating multiplication" { | ... | @@ -1018,12 +1013,12 @@ test "saturating multiplication" { |
| 1018 | 1013 | ||
| 1019 | test "saturating shift-left" { | 1014 | test "saturating shift-left" { |
| 1020 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1015 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1021 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1022 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1016 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1023 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1017 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1024 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1018 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1025 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1019 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1026 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1020 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1021 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1027 | 1022 | ||
| 1028 | const S = struct { | 1023 | const S = struct { |
| 1029 | fn doTheTest() !void { | 1024 | fn doTheTest() !void { |
| ... | @@ -1043,12 +1038,12 @@ test "saturating shift-left" { | ... | @@ -1043,12 +1038,12 @@ test "saturating shift-left" { |
| 1043 | 1038 | ||
| 1044 | test "multiplication-assignment operator with an array operand" { | 1039 | test "multiplication-assignment operator with an array operand" { |
| 1045 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1040 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1046 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1047 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1041 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1048 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1042 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1049 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1043 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1050 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1044 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1051 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1045 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1046 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | ||
| 1052 | 1047 | ||
| 1053 | const S = struct { | 1048 | const S = struct { |
| 1054 | fn doTheTest() !void { | 1049 | fn doTheTest() !void { |
| ... | @@ -1065,7 +1060,6 @@ test "multiplication-assignment operator with an array operand" { | ... | @@ -1065,7 +1060,6 @@ test "multiplication-assignment operator with an array operand" { |
| 1065 | 1060 | ||
| 1066 | test "@addWithOverflow" { | 1061 | test "@addWithOverflow" { |
| 1067 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1062 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1068 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1069 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1063 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1070 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1064 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1071 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1065 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1116,7 +1110,6 @@ test "@addWithOverflow" { | ... | @@ -1116,7 +1110,6 @@ test "@addWithOverflow" { |
| 1116 | 1110 | ||
| 1117 | test "@subWithOverflow" { | 1111 | test "@subWithOverflow" { |
| 1118 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1112 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1119 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1120 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1113 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1121 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1114 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1122 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1115 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1151,7 +1144,6 @@ test "@subWithOverflow" { | ... | @@ -1151,7 +1144,6 @@ test "@subWithOverflow" { |
| 1151 | 1144 | ||
| 1152 | test "@mulWithOverflow" { | 1145 | test "@mulWithOverflow" { |
| 1153 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1146 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1154 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1155 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1147 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1156 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1148 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1157 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1175,7 +1167,6 @@ test "@mulWithOverflow" { | ... | @@ -1175,7 +1167,6 @@ test "@mulWithOverflow" { |
| 1175 | 1167 | ||
| 1176 | test "@shlWithOverflow" { | 1168 | test "@shlWithOverflow" { |
| 1177 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1169 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1178 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1179 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1180 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1171 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1181 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1172 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1314,7 +1305,7 @@ test "zero multiplicand" { | ... | @@ -1314,7 +1305,7 @@ test "zero multiplicand" { |
| 1314 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1305 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1315 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1306 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1316 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 1307 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 1317 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1308 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 1318 | 1309 | ||
| 1319 | const zeros = @Vector(2, u32){ 0.0, 0.0 }; | 1310 | const zeros = @Vector(2, u32){ 0.0, 0.0 }; |
| 1320 | var ones = @Vector(2, u32){ 1.0, 1.0 }; | 1311 | var ones = @Vector(2, u32){ 1.0, 1.0 }; |
| ... | @@ -1362,7 +1353,6 @@ test "array operands to shuffle are coerced to vectors" { | ... | @@ -1362,7 +1353,6 @@ test "array operands to shuffle are coerced to vectors" { |
| 1362 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1353 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1363 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1354 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1364 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1355 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1365 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 1366 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1356 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1367 | 1357 | ||
| 1368 | const mask = [5]i32{ -1, 0, 1, 2, 3 }; | 1358 | const mask = [5]i32{ -1, 0, 1, 2, 3 }; |
| ... | @@ -1469,7 +1459,6 @@ test "compare vectors with different element types" { | ... | @@ -1469,7 +1459,6 @@ test "compare vectors with different element types" { |
| 1469 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1459 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1470 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1460 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1471 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1461 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1472 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1462 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1474 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1463 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1475 | 1464 |
test/behavior/x86_64/binary.zig+40-16| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | const AddOneBit = math.AddOneBit; | 1 | const AddOneBit = math.AddOneBit; |
| 2 | const AsSignedness = math.AsSignedness; | ||
| 2 | const cast = math.cast; | 3 | const cast = math.cast; |
| 4 | const ChangeScalar = math.ChangeScalar; | ||
| 3 | const checkExpected = math.checkExpected; | 5 | const checkExpected = math.checkExpected; |
| 4 | const Compare = math.Compare; | 6 | const Compare = math.Compare; |
| 5 | const DoubleBits = math.DoubleBits; | 7 | const DoubleBits = math.DoubleBits; |
| ... | @@ -13,6 +15,7 @@ const math = @import("math.zig"); | ... | @@ -13,6 +15,7 @@ const math = @import("math.zig"); |
| 13 | const nan = math.nan; | 15 | const nan = math.nan; |
| 14 | const Scalar = math.Scalar; | 16 | const Scalar = math.Scalar; |
| 15 | const sign = math.sign; | 17 | const sign = math.sign; |
| 18 | const splat = math.splat; | ||
| 16 | const Sse = math.Sse; | 19 | const Sse = math.Sse; |
| 17 | const tmin = math.tmin; | 20 | const tmin = math.tmin; |
| 18 | 21 | ||
| ... | @@ -5141,6 +5144,7 @@ inline fn mulSat(comptime Type: type, lhs: Type, rhs: Type) Type { | ... | @@ -5141,6 +5144,7 @@ inline fn mulSat(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5141 | test mulSat { | 5144 | test mulSat { |
| 5142 | const test_mul_sat = binary(mulSat, .{}); | 5145 | const test_mul_sat = binary(mulSat, .{}); |
| 5143 | try test_mul_sat.testInts(); | 5146 | try test_mul_sat.testInts(); |
| 5147 | try test_mul_sat.testIntVectors(); | ||
| 5144 | } | 5148 | } |
| 5145 | 5149 | ||
| 5146 | inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) { | 5150 | inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) { |
| ... | @@ -5240,38 +5244,42 @@ test min { | ... | @@ -5240,38 +5244,42 @@ test min { |
| 5240 | try test_min.testFloatVectors(); | 5244 | try test_min.testFloatVectors(); |
| 5241 | } | 5245 | } |
| 5242 | 5246 | ||
| 5243 | inline fn addWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } { | 5247 | inline fn addWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } { |
| 5244 | return @addWithOverflow(lhs, rhs); | 5248 | return @addWithOverflow(lhs, rhs); |
| 5245 | } | 5249 | } |
| 5246 | test addWithOverflow { | 5250 | test addWithOverflow { |
| 5247 | const test_add_with_overflow = binary(addWithOverflow, .{}); | 5251 | const test_add_with_overflow = binary(addWithOverflow, .{}); |
| 5248 | try test_add_with_overflow.testInts(); | 5252 | try test_add_with_overflow.testInts(); |
| 5253 | try test_add_with_overflow.testIntVectors(); | ||
| 5249 | } | 5254 | } |
| 5250 | 5255 | ||
| 5251 | inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } { | 5256 | inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } { |
| 5252 | return @subWithOverflow(lhs, rhs); | 5257 | return @subWithOverflow(lhs, rhs); |
| 5253 | } | 5258 | } |
| 5254 | test subWithOverflow { | 5259 | test subWithOverflow { |
| 5255 | const test_sub_with_overflow = binary(subWithOverflow, .{}); | 5260 | const test_sub_with_overflow = binary(subWithOverflow, .{}); |
| 5256 | try test_sub_with_overflow.testInts(); | 5261 | try test_sub_with_overflow.testInts(); |
| 5262 | try test_sub_with_overflow.testIntVectors(); | ||
| 5257 | } | 5263 | } |
| 5258 | 5264 | ||
| 5259 | inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } { | 5265 | inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } { |
| 5260 | return @mulWithOverflow(lhs, rhs); | 5266 | return @mulWithOverflow(lhs, rhs); |
| 5261 | } | 5267 | } |
| 5262 | test mulWithOverflow { | 5268 | test mulWithOverflow { |
| 5263 | const test_mul_with_overflow = binary(mulWithOverflow, .{}); | 5269 | const test_mul_with_overflow = binary(mulWithOverflow, .{}); |
| 5264 | try test_mul_with_overflow.testInts(); | 5270 | try test_mul_with_overflow.testInts(); |
| 5271 | try test_mul_with_overflow.testIntVectors(); | ||
| 5265 | } | 5272 | } |
| 5266 | 5273 | ||
| 5267 | inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } { | 5274 | inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } { |
| 5268 | const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs); | 5275 | const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs); |
| 5269 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); | 5276 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); |
| 5270 | return @shlWithOverflow(lhs, if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs); | 5277 | return @shlWithOverflow(lhs, if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs); |
| 5271 | } | 5278 | } |
| 5272 | test shlWithOverflow { | 5279 | test shlWithOverflow { |
| 5273 | const test_shl_with_overflow = binary(shlWithOverflow, .{}); | 5280 | const test_shl_with_overflow = binary(shlWithOverflow, .{}); |
| 5274 | try test_shl_with_overflow.testInts(); | 5281 | try test_shl_with_overflow.testInts(); |
| 5282 | try test_shl_with_overflow.testIntVectors(); | ||
| 5275 | } | 5283 | } |
| 5276 | 5284 | ||
| 5277 | inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) { | 5285 | inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) { |
| ... | @@ -5280,7 +5288,9 @@ inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) { | ... | @@ -5280,7 +5288,9 @@ inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) { |
| 5280 | test equal { | 5288 | test equal { |
| 5281 | const test_equal = binary(equal, .{}); | 5289 | const test_equal = binary(equal, .{}); |
| 5282 | try test_equal.testInts(); | 5290 | try test_equal.testInts(); |
| 5291 | try test_equal.testIntVectors(); | ||
| 5283 | try test_equal.testFloats(); | 5292 | try test_equal.testFloats(); |
| 5293 | try test_equal.testFloatVectors(); | ||
| 5284 | } | 5294 | } |
| 5285 | 5295 | ||
| 5286 | inline fn notEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs != rhs) { | 5296 | inline fn notEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs != rhs) { |
| ... | @@ -5289,7 +5299,9 @@ inline fn notEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs != rhs | ... | @@ -5289,7 +5299,9 @@ inline fn notEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs != rhs |
| 5289 | test notEqual { | 5299 | test notEqual { |
| 5290 | const test_not_equal = binary(notEqual, .{}); | 5300 | const test_not_equal = binary(notEqual, .{}); |
| 5291 | try test_not_equal.testInts(); | 5301 | try test_not_equal.testInts(); |
| 5302 | try test_not_equal.testIntVectors(); | ||
| 5292 | try test_not_equal.testFloats(); | 5303 | try test_not_equal.testFloats(); |
| 5304 | try test_not_equal.testFloatVectors(); | ||
| 5293 | } | 5305 | } |
| 5294 | 5306 | ||
| 5295 | inline fn lessThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs < rhs) { | 5307 | inline fn lessThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs < rhs) { |
| ... | @@ -5298,7 +5310,9 @@ inline fn lessThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs < rhs) | ... | @@ -5298,7 +5310,9 @@ inline fn lessThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs < rhs) |
| 5298 | test lessThan { | 5310 | test lessThan { |
| 5299 | const test_less_than = binary(lessThan, .{}); | 5311 | const test_less_than = binary(lessThan, .{}); |
| 5300 | try test_less_than.testInts(); | 5312 | try test_less_than.testInts(); |
| 5313 | try test_less_than.testIntVectors(); | ||
| 5301 | try test_less_than.testFloats(); | 5314 | try test_less_than.testFloats(); |
| 5315 | try test_less_than.testFloatVectors(); | ||
| 5302 | } | 5316 | } |
| 5303 | 5317 | ||
| 5304 | inline fn lessThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs <= rhs) { | 5318 | inline fn lessThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs <= rhs) { |
| ... | @@ -5307,7 +5321,9 @@ inline fn lessThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs | ... | @@ -5307,7 +5321,9 @@ inline fn lessThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs |
| 5307 | test lessThanOrEqual { | 5321 | test lessThanOrEqual { |
| 5308 | const test_less_than_or_equal = binary(lessThanOrEqual, .{}); | 5322 | const test_less_than_or_equal = binary(lessThanOrEqual, .{}); |
| 5309 | try test_less_than_or_equal.testInts(); | 5323 | try test_less_than_or_equal.testInts(); |
| 5324 | try test_less_than_or_equal.testIntVectors(); | ||
| 5310 | try test_less_than_or_equal.testFloats(); | 5325 | try test_less_than_or_equal.testFloats(); |
| 5326 | try test_less_than_or_equal.testFloatVectors(); | ||
| 5311 | } | 5327 | } |
| 5312 | 5328 | ||
| 5313 | inline fn greaterThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs > rhs) { | 5329 | inline fn greaterThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs > rhs) { |
| ... | @@ -5316,7 +5332,9 @@ inline fn greaterThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs > r | ... | @@ -5316,7 +5332,9 @@ inline fn greaterThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs > r |
| 5316 | test greaterThan { | 5332 | test greaterThan { |
| 5317 | const test_greater_than = binary(greaterThan, .{}); | 5333 | const test_greater_than = binary(greaterThan, .{}); |
| 5318 | try test_greater_than.testInts(); | 5334 | try test_greater_than.testInts(); |
| 5335 | try test_greater_than.testIntVectors(); | ||
| 5319 | try test_greater_than.testFloats(); | 5336 | try test_greater_than.testFloats(); |
| 5337 | try test_greater_than.testFloatVectors(); | ||
| 5320 | } | 5338 | } |
| 5321 | 5339 | ||
| 5322 | inline fn greaterThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs >= rhs) { | 5340 | inline fn greaterThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs >= rhs) { |
| ... | @@ -5325,7 +5343,9 @@ inline fn greaterThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf( | ... | @@ -5325,7 +5343,9 @@ inline fn greaterThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf( |
| 5325 | test greaterThanOrEqual { | 5343 | test greaterThanOrEqual { |
| 5326 | const test_greater_than_or_equal = binary(greaterThanOrEqual, .{}); | 5344 | const test_greater_than_or_equal = binary(greaterThanOrEqual, .{}); |
| 5327 | try test_greater_than_or_equal.testInts(); | 5345 | try test_greater_than_or_equal.testInts(); |
| 5346 | try test_greater_than_or_equal.testIntVectors(); | ||
| 5328 | try test_greater_than_or_equal.testFloats(); | 5347 | try test_greater_than_or_equal.testFloats(); |
| 5348 | try test_greater_than_or_equal.testFloatVectors(); | ||
| 5329 | } | 5349 | } |
| 5330 | 5350 | ||
| 5331 | inline fn bitAnd(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs & rhs) { | 5351 | inline fn bitAnd(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs & rhs) { |
| ... | @@ -5347,54 +5367,57 @@ test bitOr { | ... | @@ -5347,54 +5367,57 @@ test bitOr { |
| 5347 | } | 5367 | } |
| 5348 | 5368 | ||
| 5349 | inline fn shr(comptime Type: type, lhs: Type, rhs: Type) Type { | 5369 | inline fn shr(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5350 | const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs); | 5370 | const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs); |
| 5351 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); | 5371 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); |
| 5352 | return lhs >> if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs; | 5372 | return lhs >> if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs; |
| 5353 | } | 5373 | } |
| 5354 | test shr { | 5374 | test shr { |
| 5355 | const test_shr = binary(shr, .{}); | 5375 | const test_shr = binary(shr, .{}); |
| 5356 | try test_shr.testInts(); | 5376 | try test_shr.testInts(); |
| 5377 | try test_shr.testIntVectors(); | ||
| 5357 | } | 5378 | } |
| 5358 | 5379 | ||
| 5359 | inline fn shrExact(comptime Type: type, lhs: Type, rhs: Type) Type { | 5380 | inline fn shrExact(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5360 | const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs); | 5381 | const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs); |
| 5361 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); | 5382 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); |
| 5362 | const final_rhs = if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs; | 5383 | const final_rhs = if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs; |
| 5363 | return @shrExact(lhs >> final_rhs << final_rhs, final_rhs); | 5384 | return @shrExact(lhs >> final_rhs << final_rhs, final_rhs); |
| 5364 | } | 5385 | } |
| 5365 | test shrExact { | 5386 | test shrExact { |
| 5366 | const test_shr_exact = binary(shrExact, .{}); | 5387 | const test_shr_exact = binary(shrExact, .{}); |
| 5367 | try test_shr_exact.testInts(); | 5388 | try test_shr_exact.testInts(); |
| 5389 | try test_shr_exact.testIntVectors(); | ||
| 5368 | } | 5390 | } |
| 5369 | 5391 | ||
| 5370 | inline fn shl(comptime Type: type, lhs: Type, rhs: Type) Type { | 5392 | inline fn shl(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5371 | const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs); | 5393 | const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs); |
| 5372 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); | 5394 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); |
| 5373 | return lhs << if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs; | 5395 | return lhs << if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs; |
| 5374 | } | 5396 | } |
| 5375 | test shl { | 5397 | test shl { |
| 5376 | const test_shl = binary(shl, .{}); | 5398 | const test_shl = binary(shl, .{}); |
| 5377 | try test_shl.testInts(); | 5399 | try test_shl.testInts(); |
| 5400 | try test_shl.testIntVectors(); | ||
| 5378 | } | 5401 | } |
| 5379 | 5402 | ||
| 5380 | inline fn shlExactUnsafe(comptime Type: type, lhs: Type, rhs: Type) Type { | 5403 | inline fn shlExactUnsafe(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5381 | @setRuntimeSafety(false); | 5404 | @setRuntimeSafety(false); |
| 5382 | const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs); | 5405 | const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs); |
| 5383 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); | 5406 | const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs); |
| 5384 | const final_rhs = if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs; | 5407 | const final_rhs = if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs; |
| 5385 | return @shlExact(lhs << final_rhs >> final_rhs, final_rhs); | 5408 | return @shlExact(lhs << final_rhs >> final_rhs, final_rhs); |
| 5386 | } | 5409 | } |
| 5387 | test shlExactUnsafe { | 5410 | test shlExactUnsafe { |
| 5388 | const test_shl_exact_unsafe = binary(shlExactUnsafe, .{}); | 5411 | const test_shl_exact_unsafe = binary(shlExactUnsafe, .{}); |
| 5389 | try test_shl_exact_unsafe.testInts(); | 5412 | try test_shl_exact_unsafe.testInts(); |
| 5413 | try test_shl_exact_unsafe.testIntVectors(); | ||
| 5390 | } | 5414 | } |
| 5391 | 5415 | ||
| 5392 | inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type { | 5416 | inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5393 | // workaround https://github.com/ziglang/zig/issues/23034 | 5417 | // workaround https://github.com/ziglang/zig/issues/23034 |
| 5394 | if (@inComptime()) { | 5418 | if (@inComptime()) { |
| 5395 | // workaround https://github.com/ziglang/zig/issues/23139 | 5419 | // workaround https://github.com/ziglang/zig/issues/23139 |
| 5396 | //return lhs <<| @min(@abs(rhs), imax(u64)); | 5420 | return lhs <<| @min(@abs(rhs), splat(ChangeScalar(Type, u64), imax(u64))); |
| 5397 | return lhs <<| @min(@abs(rhs), @as(u64, imax(u64))); | ||
| 5398 | } | 5421 | } |
| 5399 | // workaround https://github.com/ziglang/zig/issues/23033 | 5422 | // workaround https://github.com/ziglang/zig/issues/23033 |
| 5400 | @setRuntimeSafety(false); | 5423 | @setRuntimeSafety(false); |
| ... | @@ -5403,6 +5426,7 @@ inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type { | ... | @@ -5403,6 +5426,7 @@ inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type { |
| 5403 | test shlSat { | 5426 | test shlSat { |
| 5404 | const test_shl_sat = binary(shlSat, .{}); | 5427 | const test_shl_sat = binary(shlSat, .{}); |
| 5405 | try test_shl_sat.testInts(); | 5428 | try test_shl_sat.testInts(); |
| 5429 | try test_shl_sat.testIntVectors(); | ||
| 5406 | } | 5430 | } |
| 5407 | 5431 | ||
| 5408 | inline fn bitXor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs ^ rhs) { | 5432 | inline fn bitXor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs ^ rhs) { |
test/behavior/x86_64/math.zig+26-28| ... | @@ -8,8 +8,6 @@ pub const fmin = math.floatMin; | ... | @@ -8,8 +8,6 @@ pub const fmin = math.floatMin; |
| 8 | pub const imax = math.maxInt; | 8 | pub const imax = math.maxInt; |
| 9 | pub const imin = math.minInt; | 9 | pub const imin = math.minInt; |
| 10 | pub const inf = math.inf; | 10 | pub const inf = math.inf; |
| 11 | pub const Log2Int = math.Log2Int; | ||
| 12 | pub const Log2IntCeil = math.Log2IntCeil; | ||
| 13 | pub const nan = math.nan; | 11 | pub const nan = math.nan; |
| 14 | pub const next = math.nextAfter; | 12 | pub const next = math.nextAfter; |
| 15 | pub const tmin = math.floatTrueMin; | 13 | pub const tmin = math.floatTrueMin; |
| ... | @@ -30,38 +28,44 @@ pub fn Scalar(comptime Type: type) type { | ... | @@ -30,38 +28,44 @@ pub fn Scalar(comptime Type: type) type { |
| 30 | .vector => |info| info.child, | 28 | .vector => |info| info.child, |
| 31 | }; | 29 | }; |
| 32 | } | 30 | } |
| 31 | pub fn ChangeScalar(comptime Type: type, comptime NewScalar: type) type { | ||
| 32 | return switch (@typeInfo(Type)) { | ||
| 33 | else => NewScalar, | ||
| 34 | .vector => |vector| @Vector(vector.len, NewScalar), | ||
| 35 | }; | ||
| 36 | } | ||
| 37 | pub fn AsSignedness(comptime Type: type, comptime signedness: std.builtin.Signedness) type { | ||
| 38 | return ChangeScalar(Type, @Type(.{ .int = .{ | ||
| 39 | .signedness = signedness, | ||
| 40 | .bits = @typeInfo(Scalar(Type)).int.bits, | ||
| 41 | } })); | ||
| 42 | } | ||
| 33 | pub fn AddOneBit(comptime Type: type) type { | 43 | pub fn AddOneBit(comptime Type: type) type { |
| 34 | const ResultScalar = switch (@typeInfo(Scalar(Type))) { | 44 | return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) { |
| 35 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = 1 + int.bits } }), | 45 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = 1 + int.bits } }), |
| 36 | .float => Scalar(Type), | 46 | .float => Scalar(Type), |
| 37 | else => @compileError(@typeName(Type)), | 47 | else => @compileError(@typeName(Type)), |
| 38 | }; | 48 | }); |
| 39 | return switch (@typeInfo(Type)) { | ||
| 40 | else => ResultScalar, | ||
| 41 | .vector => |vector| @Vector(vector.len, ResultScalar), | ||
| 42 | }; | ||
| 43 | } | 49 | } |
| 44 | pub fn DoubleBits(comptime Type: type) type { | 50 | pub fn DoubleBits(comptime Type: type) type { |
| 45 | const ResultScalar = switch (@typeInfo(Scalar(Type))) { | 51 | return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) { |
| 46 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = int.bits * 2 } }), | 52 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = int.bits * 2 } }), |
| 47 | .float => Scalar(Type), | 53 | .float => Scalar(Type), |
| 48 | else => @compileError(@typeName(Type)), | 54 | else => @compileError(@typeName(Type)), |
| 49 | }; | 55 | }); |
| 50 | return switch (@typeInfo(Type)) { | ||
| 51 | else => ResultScalar, | ||
| 52 | .vector => |vector| @Vector(vector.len, ResultScalar), | ||
| 53 | }; | ||
| 54 | } | 56 | } |
| 55 | pub fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type { | 57 | pub fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type { |
| 56 | const ResultScalar = switch (@typeInfo(Scalar(Type))) { | 58 | return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) { |
| 57 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = std.mem.alignForward(u16, int.bits, multiple) } }), | 59 | .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = std.mem.alignForward(u16, int.bits, multiple) } }), |
| 58 | .float => Scalar(Type), | 60 | .float => Scalar(Type), |
| 59 | else => @compileError(@typeName(Type)), | 61 | else => @compileError(@typeName(Type)), |
| 60 | }; | 62 | }); |
| 61 | return switch (@typeInfo(Type)) { | 63 | } |
| 62 | else => ResultScalar, | 64 | pub fn Log2Int(comptime Type: type) type { |
| 63 | .vector => |vector| @Vector(vector.len, ResultScalar), | 65 | return ChangeScalar(Type, math.Log2Int(Scalar(Type))); |
| 64 | }; | 66 | } |
| 67 | pub fn Log2IntCeil(comptime Type: type) type { | ||
| 68 | return ChangeScalar(Type, math.Log2IntCeil(Scalar(Type))); | ||
| 65 | } | 69 | } |
| 66 | // inline to avoid a runtime `@splat` | 70 | // inline to avoid a runtime `@splat` |
| 67 | pub inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type { | 71 | pub inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type { |
| ... | @@ -78,18 +82,12 @@ inline fn select(cond: anytype, lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) { | ... | @@ -78,18 +82,12 @@ inline fn select(cond: anytype, lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) { |
| 78 | else => @compileError(@typeName(@TypeOf(cond))), | 82 | else => @compileError(@typeName(@TypeOf(cond))), |
| 79 | }; | 83 | }; |
| 80 | } | 84 | } |
| 81 | pub fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) { | 85 | pub fn sign(rhs: anytype) ChangeScalar(@TypeOf(rhs), bool) { |
| 82 | else => bool, | ||
| 83 | .vector => |vector| @Vector(vector.len, bool), | ||
| 84 | } { | ||
| 85 | const ScalarInt = @Type(.{ .int = .{ | 86 | const ScalarInt = @Type(.{ .int = .{ |
| 86 | .signedness = .unsigned, | 87 | .signedness = .unsigned, |
| 87 | .bits = @bitSizeOf(Scalar(@TypeOf(rhs))), | 88 | .bits = @bitSizeOf(Scalar(@TypeOf(rhs))), |
| 88 | } }); | 89 | } }); |
| 89 | const VectorInt = switch (@typeInfo(@TypeOf(rhs))) { | 90 | const VectorInt = ChangeScalar(@TypeOf(rhs), ScalarInt); |
| 90 | else => ScalarInt, | ||
| 91 | .vector => |vector| @Vector(vector.len, ScalarInt), | ||
| 92 | }; | ||
| 93 | return @as(VectorInt, @bitCast(rhs)) & splat(VectorInt, @as(ScalarInt, 1) << @bitSizeOf(ScalarInt) - 1) != splat(VectorInt, 0); | 91 | return @as(VectorInt, @bitCast(rhs)) & splat(VectorInt, @as(ScalarInt, 1) << @bitSizeOf(ScalarInt) - 1) != splat(VectorInt, 0); |
| 94 | } | 92 | } |
| 95 | fn boolAnd(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) { | 93 | fn boolAnd(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) { |
test/behavior/x86_64/unary.zig+4| ... | @@ -4828,6 +4828,7 @@ inline fn ctz(comptime Type: type, rhs: Type) @TypeOf(@ctz(rhs)) { | ... | @@ -4828,6 +4828,7 @@ inline fn ctz(comptime Type: type, rhs: Type) @TypeOf(@ctz(rhs)) { |
| 4828 | test ctz { | 4828 | test ctz { |
| 4829 | const test_ctz = unary(ctz, .{}); | 4829 | const test_ctz = unary(ctz, .{}); |
| 4830 | try test_ctz.testInts(); | 4830 | try test_ctz.testInts(); |
| 4831 | try test_ctz.testIntVectors(); | ||
| 4831 | } | 4832 | } |
| 4832 | 4833 | ||
| 4833 | inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) { | 4834 | inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) { |
| ... | @@ -4836,6 +4837,7 @@ inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) { | ... | @@ -4836,6 +4837,7 @@ inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) { |
| 4836 | test popCount { | 4837 | test popCount { |
| 4837 | const test_pop_count = unary(popCount, .{}); | 4838 | const test_pop_count = unary(popCount, .{}); |
| 4838 | try test_pop_count.testInts(); | 4839 | try test_pop_count.testInts(); |
| 4840 | try test_pop_count.testIntVectors(); | ||
| 4839 | } | 4841 | } |
| 4840 | 4842 | ||
| 4841 | inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) { | 4843 | inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) { |
| ... | @@ -4844,6 +4846,7 @@ inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) { | ... | @@ -4844,6 +4846,7 @@ inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) { |
| 4844 | test byteSwap { | 4846 | test byteSwap { |
| 4845 | const test_byte_swap = unary(byteSwap, .{}); | 4847 | const test_byte_swap = unary(byteSwap, .{}); |
| 4846 | try test_byte_swap.testInts(); | 4848 | try test_byte_swap.testInts(); |
| 4849 | try test_byte_swap.testIntVectors(); | ||
| 4847 | } | 4850 | } |
| 4848 | 4851 | ||
| 4849 | inline fn bitReverse(comptime Type: type, rhs: Type) @TypeOf(@bitReverse(rhs)) { | 4852 | inline fn bitReverse(comptime Type: type, rhs: Type) @TypeOf(@bitReverse(rhs)) { |
| ... | @@ -4852,6 +4855,7 @@ inline fn bitReverse(comptime Type: type, rhs: Type) @TypeOf(@bitReverse(rhs)) { | ... | @@ -4852,6 +4855,7 @@ inline fn bitReverse(comptime Type: type, rhs: Type) @TypeOf(@bitReverse(rhs)) { |
| 4852 | test bitReverse { | 4855 | test bitReverse { |
| 4853 | const test_bit_reverse = unary(bitReverse, .{}); | 4856 | const test_bit_reverse = unary(bitReverse, .{}); |
| 4854 | try test_bit_reverse.testInts(); | 4857 | try test_bit_reverse.testInts(); |
| 4858 | try test_bit_reverse.testIntVectors(); | ||
| 4855 | } | 4859 | } |
| 4856 | 4860 | ||
| 4857 | inline fn sqrt(comptime Type: type, rhs: Type) @TypeOf(@sqrt(rhs)) { | 4861 | inline fn sqrt(comptime Type: type, rhs: Type) @TypeOf(@sqrt(rhs)) { |
test/cases/compile_errors/@import_zon_bad_type.zig+3-3| ... | @@ -117,9 +117,9 @@ export fn testMutablePointer() void { | ... | @@ -117,9 +117,9 @@ export fn testMutablePointer() void { |
| 117 | // tmp.zig:37:38: note: imported here | 117 | // tmp.zig:37:38: note: imported here |
| 118 | // neg_inf.zon:1:1: error: expected type '?u8' | 118 | // neg_inf.zon:1:1: error: expected type '?u8' |
| 119 | // tmp.zig:57:28: note: imported here | 119 | // tmp.zig:57:28: note: imported here |
| 120 | // neg_inf.zon:1:1: error: expected type 'tmp.testNonExhaustiveEnum__enum_518' | 120 | // neg_inf.zon:1:1: error: expected type 'tmp.testNonExhaustiveEnum__enum_522' |
| 121 | // tmp.zig:62:39: note: imported here | 121 | // tmp.zig:62:39: note: imported here |
| 122 | // neg_inf.zon:1:1: error: expected type 'tmp.testUntaggedUnion__union_520' | 122 | // neg_inf.zon:1:1: error: expected type 'tmp.testUntaggedUnion__union_524' |
| 123 | // tmp.zig:67:44: note: imported here | 123 | // tmp.zig:67:44: note: imported here |
| 124 | // neg_inf.zon:1:1: error: expected type 'tmp.testTaggedUnionVoid__union_523' | 124 | // neg_inf.zon:1:1: error: expected type 'tmp.testTaggedUnionVoid__union_527' |
| 125 | // tmp.zig:72:50: note: imported here | 125 | // tmp.zig:72:50: note: imported here |
test/cases/compile_errors/anytype_param_requires_comptime.zig+1-1| ... | @@ -15,6 +15,6 @@ pub export fn entry() void { | ... | @@ -15,6 +15,6 @@ pub export fn entry() void { |
| 15 | // error | 15 | // error |
| 16 | // | 16 | // |
| 17 | // :7:25: error: unable to resolve comptime value | 17 | // :7:25: error: unable to resolve comptime value |
| 18 | // :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_492.C' must be comptime-known | 18 | // :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_496.C' must be comptime-known |
| 19 | // :4:16: note: struct requires comptime because of this field | 19 | // :4:16: note: struct requires comptime because of this field |
| 20 | // :4:16: note: types are not available at runtime | 20 | // :4:16: note: types are not available at runtime |
test/cases/compile_errors/bad_panic_call_signature.zig+1-4| ... | @@ -15,8 +15,7 @@ pub const panic = struct { | ... | @@ -15,8 +15,7 @@ pub const panic = struct { |
| 15 | pub const castToNull = simple_panic.castToNull; | 15 | pub const castToNull = simple_panic.castToNull; |
| 16 | pub const incorrectAlignment = simple_panic.incorrectAlignment; | 16 | pub const incorrectAlignment = simple_panic.incorrectAlignment; |
| 17 | pub const invalidErrorCode = simple_panic.invalidErrorCode; | 17 | pub const invalidErrorCode = simple_panic.invalidErrorCode; |
| 18 | pub const castTruncatedData = simple_panic.castTruncatedData; | 18 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; |
| 19 | pub const negativeToUnsigned = simple_panic.negativeToUnsigned; | ||
| 20 | pub const integerOverflow = simple_panic.integerOverflow; | 19 | pub const integerOverflow = simple_panic.integerOverflow; |
| 21 | pub const shlOverflow = simple_panic.shlOverflow; | 20 | pub const shlOverflow = simple_panic.shlOverflow; |
| 22 | pub const shrOverflow = simple_panic.shrOverflow; | 21 | pub const shrOverflow = simple_panic.shrOverflow; |
| ... | @@ -27,8 +26,6 @@ pub const panic = struct { | ... | @@ -27,8 +26,6 @@ pub const panic = struct { |
| 27 | pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig; | 26 | pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig; |
| 28 | pub const invalidEnumValue = simple_panic.invalidEnumValue; | 27 | pub const invalidEnumValue = simple_panic.invalidEnumValue; |
| 29 | pub const forLenMismatch = simple_panic.forLenMismatch; | 28 | pub const forLenMismatch = simple_panic.forLenMismatch; |
| 30 | /// Delete after next zig1.wasm update | ||
| 31 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 32 | pub const copyLenMismatch = simple_panic.copyLenMismatch; | 29 | pub const copyLenMismatch = simple_panic.copyLenMismatch; |
| 33 | pub const memcpyAlias = simple_panic.memcpyAlias; | 30 | pub const memcpyAlias = simple_panic.memcpyAlias; |
| 34 | pub const noreturnReturned = simple_panic.noreturnReturned; | 31 | pub const noreturnReturned = simple_panic.noreturnReturned; |
test/cases/compile_errors/bad_panic_generic_signature.zig+1-4| ... | @@ -11,8 +11,7 @@ pub const panic = struct { | ... | @@ -11,8 +11,7 @@ pub const panic = struct { |
| 11 | pub const castToNull = simple_panic.castToNull; | 11 | pub const castToNull = simple_panic.castToNull; |
| 12 | pub const incorrectAlignment = simple_panic.incorrectAlignment; | 12 | pub const incorrectAlignment = simple_panic.incorrectAlignment; |
| 13 | pub const invalidErrorCode = simple_panic.invalidErrorCode; | 13 | pub const invalidErrorCode = simple_panic.invalidErrorCode; |
| 14 | pub const castTruncatedData = simple_panic.castTruncatedData; | 14 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; |
| 15 | pub const negativeToUnsigned = simple_panic.negativeToUnsigned; | ||
| 16 | pub const integerOverflow = simple_panic.integerOverflow; | 15 | pub const integerOverflow = simple_panic.integerOverflow; |
| 17 | pub const shlOverflow = simple_panic.shlOverflow; | 16 | pub const shlOverflow = simple_panic.shlOverflow; |
| 18 | pub const shrOverflow = simple_panic.shrOverflow; | 17 | pub const shrOverflow = simple_panic.shrOverflow; |
| ... | @@ -23,8 +22,6 @@ pub const panic = struct { | ... | @@ -23,8 +22,6 @@ pub const panic = struct { |
| 23 | pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig; | 22 | pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig; |
| 24 | pub const invalidEnumValue = simple_panic.invalidEnumValue; | 23 | pub const invalidEnumValue = simple_panic.invalidEnumValue; |
| 25 | pub const forLenMismatch = simple_panic.forLenMismatch; | 24 | pub const forLenMismatch = simple_panic.forLenMismatch; |
| 26 | /// Delete after next zig1.wasm update | ||
| 27 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 28 | pub const copyLenMismatch = simple_panic.copyLenMismatch; | 25 | pub const copyLenMismatch = simple_panic.copyLenMismatch; |
| 29 | pub const memcpyAlias = simple_panic.memcpyAlias; | 26 | pub const memcpyAlias = simple_panic.memcpyAlias; |
| 30 | pub const noreturnReturned = simple_panic.noreturnReturned; | 27 | pub const noreturnReturned = simple_panic.noreturnReturned; |
test/cases/compile_errors/bogus_method_call_on_slice.zig+1-1| ... | @@ -16,5 +16,5 @@ pub export fn entry2() void { | ... | @@ -16,5 +16,5 @@ pub export fn entry2() void { |
| 16 | // | 16 | // |
| 17 | // :3:6: error: no field or member function named 'copy' in '[]const u8' | 17 | // :3:6: error: no field or member function named 'copy' in '[]const u8' |
| 18 | // :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})' | 18 | // :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})' |
| 19 | // :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_496' | 19 | // :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_500' |
| 20 | // :12:6: note: struct declared here | 20 | // :12:6: note: struct declared here |
test/cases/compile_errors/coerce_anon_struct.zig+1-1| ... | @@ -6,6 +6,6 @@ export fn foo() void { | ... | @@ -6,6 +6,6 @@ export fn foo() void { |
| 6 | 6 | ||
| 7 | // error | 7 | // error |
| 8 | // | 8 | // |
| 9 | // :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_485' | 9 | // :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_489' |
| 10 | // :3:16: note: struct declared here | 10 | // :3:16: note: struct declared here |
| 11 | // :1:11: note: struct declared here | 11 | // :1:11: note: struct declared here |
test/cases/compile_errors/redundant_try.zig+2-2| ... | @@ -44,9 +44,9 @@ comptime { | ... | @@ -44,9 +44,9 @@ comptime { |
| 44 | // | 44 | // |
| 45 | // :5:23: error: expected error union type, found 'comptime_int' | 45 | // :5:23: error: expected error union type, found 'comptime_int' |
| 46 | // :10:23: error: expected error union type, found '@TypeOf(.{})' | 46 | // :10:23: error: expected error union type, found '@TypeOf(.{})' |
| 47 | // :15:23: error: expected error union type, found 'tmp.test2__struct_522' | 47 | // :15:23: error: expected error union type, found 'tmp.test2__struct_526' |
| 48 | // :15:23: note: struct declared here | 48 | // :15:23: note: struct declared here |
| 49 | // :20:27: error: expected error union type, found 'tmp.test3__struct_524' | 49 | // :20:27: error: expected error union type, found 'tmp.test3__struct_528' |
| 50 | // :20:27: note: struct declared here | 50 | // :20:27: note: struct declared here |
| 51 | // :25:23: error: expected error union type, found 'struct { comptime *const [5:0]u8 = "hello" }' | 51 | // :25:23: error: expected error union type, found 'struct { comptime *const [5:0]u8 = "hello" }' |
| 52 | // :31:13: error: expected error union type, found 'u32' | 52 | // :31:13: error: expected error union type, found 'u32' |
test/cases/compile_errors/shuffle_with_selected_index_past_first_vector_length.zig+16-10| ... | @@ -1,14 +1,20 @@ | ... | @@ -1,14 +1,20 @@ |
| 1 | export fn entry() void { | 1 | export fn foo() void { |
| 2 | const v: @Vector(4, u32) = [4]u32{ 10, 11, 12, 13 }; | 2 | // Here, the bad index ('7') is not less than 'b.len', so the error shouldn't have a note suggesting a negative index. |
| 3 | const x: @Vector(4, u32) = [4]u32{ 14, 15, 16, 17 }; | 3 | const a: @Vector(4, u32) = .{ 10, 11, 12, 13 }; |
| 4 | const z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 }); | 4 | const b: @Vector(4, u32) = .{ 14, 15, 16, 17 }; |
| 5 | _ = z; | 5 | _ = @shuffle(u32, a, b, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 }); |
| 6 | } | ||
| 7 | export fn bar() void { | ||
| 8 | // Here, the bad index ('7') *is* less than 'b.len', so the error *should* have a note suggesting a negative index. | ||
| 9 | const a: @Vector(4, u32) = .{ 10, 11, 12, 13 }; | ||
| 10 | const b: @Vector(9, u32) = .{ 14, 15, 16, 17, 18, 19, 20, 21, 22 }; | ||
| 11 | _ = @shuffle(u32, a, b, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 }); | ||
| 6 | } | 12 | } |
| 7 | 13 | ||
| 8 | // error | 14 | // error |
| 9 | // backend=stage2 | ||
| 10 | // target=native | ||
| 11 | // | 15 | // |
| 12 | // :4:41: error: mask index '4' has out-of-bounds selection | 16 | // :5:35: error: mask element at index '4' selects out-of-bounds index |
| 13 | // :4:29: note: selected index '7' out of bounds of '@Vector(4, u32)' | 17 | // :5:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here |
| 14 | // :4:32: note: selections from the second vector are specified with negative numbers | 18 | // :11:35: error: mask element at index '4' selects out-of-bounds index |
| 19 | // :11:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here | ||
| 20 | // :11:26: note: use '~@as(u32, 7)' to index into second vector given here |
test/cases/safety/@intCast to u0.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/memmove_len_mismatch.zig+1-1| ... | @@ -15,5 +15,5 @@ pub fn main() !void { | ... | @@ -15,5 +15,5 @@ pub fn main() !void { |
| 15 | return error.TestFailed; | 15 | return error.TestFailed; |
| 16 | } | 16 | } |
| 17 | // run | 17 | // run |
| 18 | // backend=llvm | 18 | // backend=stage2,llvm |
| 19 | // target=native | 19 | // target=native |
test/cases/safety/signed integer not fitting in cast to unsigned integer - widening.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/signed integer not fitting in cast to unsigned integer.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/signed-unsigned vector cast.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/slice_cast_change_len_0.zig+2-1| ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu | ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu |
| 23 | const std = @import("std"); | 23 | const std = @import("std"); |
| 24 | 24 | ||
| 25 | // run | 25 | // run |
| 26 | // backend=llvm | 26 | // backend=stage2,llvm |
| 27 | // target=x86_64-linux |
test/cases/safety/slice_cast_change_len_1.zig+2-1| ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu | ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu |
| 23 | const std = @import("std"); | 23 | const std = @import("std"); |
| 24 | 24 | ||
| 25 | // run | 25 | // run |
| 26 | // backend=llvm | 26 | // backend=stage2,llvm |
| 27 | // target=x86_64-linux |
test/cases/safety/slice_cast_change_len_2.zig+2-1| ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu | ... | @@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu |
| 23 | const std = @import("std"); | 23 | const std = @import("std"); |
| 24 | 24 | ||
| 25 | // run | 25 | // run |
| 26 | // backend=llvm | 26 | // backend=stage2,llvm |
| 27 | // target=x86_64-linux |
test/cases/safety/truncating vector cast.zig	+2-2| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
| ... | @@ -17,5 +17,5 @@ pub fn main() !void { | ... | @@ -17,5 +17,5 @@ pub fn main() !void { |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | // run | 19 | // run |
| 20 | // backend=llvm | 20 | // backend=stage2,llvm |
| 21 | // target=native | 21 | // target=native |
test/cases/safety/unsigned integer not fitting in cast to signed integer - same bit count.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/unsigned-signed vector cast.zig	+2-2| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
| ... | @@ -17,5 +17,5 @@ pub fn main() !void { | ... | @@ -17,5 +17,5 @@ pub fn main() !void { |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | // run | 19 | // run |
| 20 | // backend=llvm | 20 | // backend=stage2,llvm |
| 21 | // target=native | 21 | // target=native |
test/cases/safety/value does not fit in shortening cast - u0.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/value does not fit in shortening cast.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "integer cast truncated bits")) { | 5 | if (std.mem.eql(u8, message, "integer does not fit in destination type")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/vector integer addition overflow.zig	+1-1| ... | @@ -18,5 +18,5 @@ fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) { | ... | @@ -18,5 +18,5 @@ fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) { |
| 18 | return a + b; | 18 | return a + b; |
| 19 | } | 19 | } |
| 20 | // run | 20 | // run |
| 21 | // backend=llvm | 21 | // backend=stage2,llvm |
| 22 | // target=native | 22 | // target=native |
test/cases/safety/vector integer multiplication overflow.zig	+1-1| ... | @@ -18,5 +18,5 @@ fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) { | ... | @@ -18,5 +18,5 @@ fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) { |
| 18 | return a * b; | 18 | return a * b; |
| 19 | } | 19 | } |
| 20 | // run | 20 | // run |
| 21 | // backend=llvm | 21 | // backend=stage2,llvm |
| 22 | // target=native | 22 | // target=native |
test/cases/safety/vector integer negation overflow.zig	+1-1| ... | @@ -18,5 +18,5 @@ fn neg(a: @Vector(4, i16)) @Vector(4, i16) { | ... | @@ -18,5 +18,5 @@ fn neg(a: @Vector(4, i16)) @Vector(4, i16) { |
| 18 | return -a; | 18 | return -a; |
| 19 | } | 19 | } |
| 20 | // run | 20 | // run |
| 21 | // backend=llvm | 21 | // backend=stage2,llvm |
| 22 | // target=native | 22 | // target=native |
test/cases/safety/vector integer subtraction overflow.zig	+1-1| ... | @@ -18,5 +18,5 @@ fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) { | ... | @@ -18,5 +18,5 @@ fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) { |
| 18 | return a - b; | 18 | return a - b; |
| 19 | } | 19 | } |
| 20 | // run | 20 | // run |
| 21 | // backend=llvm | 21 | // backend=stage2,llvm |
| 22 | // target=native | 22 | // target=native |
test/incremental/change_panic_handler_explicit+3-12| ... | @@ -26,8 +26,7 @@ pub const panic = struct { | ... | @@ -26,8 +26,7 @@ pub const panic = struct { |
| 26 | pub const castToNull = no_panic.castToNull; | 26 | pub const castToNull = no_panic.castToNull; |
| 27 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 27 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 28 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 28 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 29 | pub const castTruncatedData = no_panic.castTruncatedData; | 29 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 30 | pub const negativeToUnsigned = no_panic.negativeToUnsigned; | ||
| 31 | pub const shlOverflow = no_panic.shlOverflow; | 30 | pub const shlOverflow = no_panic.shlOverflow; |
| 32 | pub const shrOverflow = no_panic.shrOverflow; | 31 | pub const shrOverflow = no_panic.shrOverflow; |
| 33 | pub const divideByZero = no_panic.divideByZero; | 32 | pub const divideByZero = no_panic.divideByZero; |
| ... | @@ -37,8 +36,6 @@ pub const panic = struct { | ... | @@ -37,8 +36,6 @@ pub const panic = struct { |
| 37 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; | 36 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; |
| 38 | pub const invalidEnumValue = no_panic.invalidEnumValue; | 37 | pub const invalidEnumValue = no_panic.invalidEnumValue; |
| 39 | pub const forLenMismatch = no_panic.forLenMismatch; | 38 | pub const forLenMismatch = no_panic.forLenMismatch; |
| 40 | /// Delete after next zig1.wasm update | ||
| 41 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 42 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 39 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 43 | pub const memcpyAlias = no_panic.memcpyAlias; | 40 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 44 | pub const noreturnReturned = no_panic.noreturnReturned; | 41 | pub const noreturnReturned = no_panic.noreturnReturned; |
| ... | @@ -75,8 +72,7 @@ pub const panic = struct { | ... | @@ -75,8 +72,7 @@ pub const panic = struct { |
| 75 | pub const castToNull = no_panic.castToNull; | 72 | pub const castToNull = no_panic.castToNull; |
| 76 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 73 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 77 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 74 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 78 | pub const castTruncatedData = no_panic.castTruncatedData; | 75 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 79 | pub const negativeToUnsigned = no_panic.negativeToUnsigned; | ||
| 80 | pub const shlOverflow = no_panic.shlOverflow; | 76 | pub const shlOverflow = no_panic.shlOverflow; |
| 81 | pub const shrOverflow = no_panic.shrOverflow; | 77 | pub const shrOverflow = no_panic.shrOverflow; |
| 82 | pub const divideByZero = no_panic.divideByZero; | 78 | pub const divideByZero = no_panic.divideByZero; |
| ... | @@ -86,8 +82,6 @@ pub const panic = struct { | ... | @@ -86,8 +82,6 @@ pub const panic = struct { |
| 86 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; | 82 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; |
| 87 | pub const invalidEnumValue = no_panic.invalidEnumValue; | 83 | pub const invalidEnumValue = no_panic.invalidEnumValue; |
| 88 | pub const forLenMismatch = no_panic.forLenMismatch; | 84 | pub const forLenMismatch = no_panic.forLenMismatch; |
| 89 | /// Delete after next zig1.wasm update | ||
| 90 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 91 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 85 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 92 | pub const memcpyAlias = no_panic.memcpyAlias; | 86 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 93 | pub const noreturnReturned = no_panic.noreturnReturned; | 87 | pub const noreturnReturned = no_panic.noreturnReturned; |
| ... | @@ -124,8 +118,7 @@ pub const panic = struct { | ... | @@ -124,8 +118,7 @@ pub const panic = struct { |
| 124 | pub const castToNull = no_panic.castToNull; | 118 | pub const castToNull = no_panic.castToNull; |
| 125 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 119 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 126 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 120 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 127 | pub const castTruncatedData = no_panic.castTruncatedData; | 121 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 128 | pub const negativeToUnsigned = no_panic.negativeToUnsigned; | ||
| 129 | pub const shlOverflow = no_panic.shlOverflow; | 122 | pub const shlOverflow = no_panic.shlOverflow; |
| 130 | pub const shrOverflow = no_panic.shrOverflow; | 123 | pub const shrOverflow = no_panic.shrOverflow; |
| 131 | pub const divideByZero = no_panic.divideByZero; | 124 | pub const divideByZero = no_panic.divideByZero; |
| ... | @@ -135,8 +128,6 @@ pub const panic = struct { | ... | @@ -135,8 +128,6 @@ pub const panic = struct { |
| 135 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; | 128 | pub const shiftRhsTooBig = no_panic.shiftRhsTooBig; |
| 136 | pub const invalidEnumValue = no_panic.invalidEnumValue; | 129 | pub const invalidEnumValue = no_panic.invalidEnumValue; |
| 137 | pub const forLenMismatch = no_panic.forLenMismatch; | 130 | pub const forLenMismatch = no_panic.forLenMismatch; |
| 138 | /// Delete after next zig1.wasm update | ||
| 139 | pub const memcpyLenMismatch = copyLenMismatch; | ||
| 140 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 131 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 141 | pub const memcpyAlias = no_panic.memcpyAlias; | 132 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 142 | pub const noreturnReturned = no_panic.noreturnReturned; | 133 | pub const noreturnReturned = no_panic.noreturnReturned; |
test/src/Cases.zig+17-3| ... | @@ -400,7 +400,7 @@ fn addFromDirInner( | ... | @@ -400,7 +400,7 @@ fn addFromDirInner( |
| 400 | for (targets) |target_query| { | 400 | for (targets) |target_query| { |
| 401 | const output = try manifest.trailingLinesSplit(ctx.arena); | 401 | const output = try manifest.trailingLinesSplit(ctx.arena); |
| 402 | try ctx.translate.append(.{ | 402 | try ctx.translate.append(.{ |
| 403 | .name = std.fs.path.stem(filename), | 403 | .name = try caseNameFromPath(ctx.arena, filename), |
| 404 | .c_frontend = c_frontend, | 404 | .c_frontend = c_frontend, |
| 405 | .target = b.resolveTargetQuery(target_query), | 405 | .target = b.resolveTargetQuery(target_query), |
| 406 | .link_libc = link_libc, | 406 | .link_libc = link_libc, |
| ... | @@ -416,7 +416,7 @@ fn addFromDirInner( | ... | @@ -416,7 +416,7 @@ fn addFromDirInner( |
| 416 | for (targets) |target_query| { | 416 | for (targets) |target_query| { |
| 417 | const output = try manifest.trailingSplit(ctx.arena); | 417 | const output = try manifest.trailingSplit(ctx.arena); |
| 418 | try ctx.translate.append(.{ | 418 | try ctx.translate.append(.{ |
| 419 | .name = std.fs.path.stem(filename), | 419 | .name = try caseNameFromPath(ctx.arena, filename), |
| 420 | .c_frontend = c_frontend, | 420 | .c_frontend = c_frontend, |
| 421 | .target = b.resolveTargetQuery(target_query), | 421 | .target = b.resolveTargetQuery(target_query), |
| 422 | .link_libc = link_libc, | 422 | .link_libc = link_libc, |
| ... | @@ -454,7 +454,7 @@ fn addFromDirInner( | ... | @@ -454,7 +454,7 @@ fn addFromDirInner( |
| 454 | 454 | ||
| 455 | const next = ctx.cases.items.len; | 455 | const next = ctx.cases.items.len; |
| 456 | try ctx.cases.append(.{ | 456 | try ctx.cases.append(.{ |
| 457 | .name = std.fs.path.stem(filename), | 457 | .name = try caseNameFromPath(ctx.arena, filename), |
| 458 | .import_path = std.fs.path.dirname(filename), | 458 | .import_path = std.fs.path.dirname(filename), |
| 459 | .backend = backend, | 459 | .backend = backend, |
| 460 | .files = .init(ctx.arena), | 460 | .files = .init(ctx.arena), |
| ... | @@ -1138,3 +1138,17 @@ fn knownFileExtension(filename: []const u8) bool { | ... | @@ -1138,3 +1138,17 @@ fn knownFileExtension(filename: []const u8) bool { |
| 1138 | if (it.next() != null) return false; | 1138 | if (it.next() != null) return false; |
| 1139 | return false; | 1139 | return false; |
| 1140 | } | 1140 | } |
| 1141 | |||
| 1142 | /// `path` is a path relative to the root case directory. | ||
| 1143 | /// e.g. `compile_errors/undeclared_identifier.zig` | ||
| 1144 | /// The case name is computed by removing the extension and substituting path separators for dots. | ||
| 1145 | /// e.g. `compile_errors.undeclared_identifier` | ||
| 1146 | /// Including the directory components makes `-Dtest-filter` more useful, because you can filter | ||
| 1147 | /// based on subdirectory; e.g. `-Dtest-filter=compile_errors` to run the compile error tets. | ||
| 1148 | fn caseNameFromPath(arena: Allocator, path: []const u8) Allocator.Error![]const u8 { | ||
| 1149 | const ext_len = std.fs.path.extension(path).len; | ||
| 1150 | const path_sans_ext = path[0 .. path.len - ext_len]; | ||
| 1151 | const result = try arena.dupe(u8, path_sans_ext); | ||
| 1152 | std.mem.replaceScalar(u8, result, std.fs.path.sep, '.'); | ||
| 1153 | return result; | ||
| 1154 | } |
tools/lldb_pretty_printers.py+2-1| ... | @@ -601,7 +601,8 @@ type_tag_handlers = { | ... | @@ -601,7 +601,8 @@ type_tag_handlers = { |
| 601 | 'fn_void_no_args': lambda payload: 'fn() void', | 601 | 'fn_void_no_args': lambda payload: 'fn() void', |
| 602 | 'fn_naked_noreturn_no_args': lambda payload: 'fn() callconv(.naked) noreturn', | 602 | 'fn_naked_noreturn_no_args': lambda payload: 'fn() callconv(.naked) noreturn', |
| 603 | 'fn_ccc_void_no_args': lambda payload: 'fn() callconv(.c) void', | 603 | 'fn_ccc_void_no_args': lambda payload: 'fn() callconv(.c) void', |
| 604 | 'single_const_pointer_to_comptime_int': lambda payload: '*const comptime_int', | 604 | 'ptr_usize': lambda payload: '*usize', |
| 605 | 'ptr_const_comptime_int': lambda payload: '*const comptime_int', | ||
| 605 | 'manyptr_u8': lambda payload: '[*]u8', | 606 | 'manyptr_u8': lambda payload: '[*]u8', |
| 606 | 'manyptr_const_u8': lambda payload: '[*]const u8', | 607 | 'manyptr_const_u8': lambda payload: '[*]const u8', |
| 607 | 'manyptr_const_u8_sentinel_0': lambda payload: '[*:0]const u8', | 608 | 'manyptr_const_u8_sentinel_0': lambda payload: '[*:0]const u8', |