authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-01 22:02:34-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-06-01 22:02:34-04:00
log8dbd29cc4588cf118532a816d74b78f62999b636
tree0fc19e694d1ad7366dd2b7153dd0d4647d3a9159
parent0386730777da858908aaba4ef96fb5bd48faafc9
parent6a63c8653ae9121f1cbcee49d32ec4f8deaf0b65
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24011 from jacobly0/legalize-unary

Legalize: implement scalarization and safety check expansion

92 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 }));
443443
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}
77
8// test_error=cast truncated bits8// 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 {
12461246
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 }
12551251
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 {
12621258
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 }
12711263
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 }
12961288
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 };
13111296
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();
891891
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);
907898
...@@ -2116,7 +2107,7 @@ const IndexHeader = struct {...@@ -2116,7 +2107,7 @@ const IndexHeader = struct {
21162107
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 {
499fn ChaChaImpl(comptime rounds_nb: usize) type {499fn 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}
6767
68pub fn castTruncatedData() noreturn {68pub fn integerOutOfBounds() noreturn {
69 @branchHint(.cold);
70 @trap();
71}
72
73pub 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}
127122
128/// Delete after next zig1.wasm update
129pub const memcpyLenMismatch = copyLenMismatch;
130
131pub fn copyLenMismatch() noreturn {123pub 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}
7474
75pub fn castTruncatedData() noreturn {75pub fn integerOutOfBounds() noreturn {
76 call("integer cast truncated bits", null);76 call("integer does not fit in destination type", null);
77}
78
79pub fn negativeToUnsigned() noreturn {
80 call("attempt to cast negative value to unsigned integer", null);
81}77}
8278
83pub fn integerOverflow() noreturn {79pub 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}
122118
123/// Delete after next zig1.wasm update
124pub const memcpyLenMismatch = copyLenMismatch;
125
126pub fn copyLenMismatch() noreturn {119pub 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}
781781
782test "xxhash3" {782test "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/23807783 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
785784
786 const H = XxHash3;785 const H = XxHash3;
...@@ -814,7 +813,6 @@ test "xxhash3" {...@@ -814,7 +813,6 @@ test "xxhash3" {
814}813}
815814
816test "xxhash3 smhasher" {815test "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/23807816 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
819817
820 const Test = struct {818 const Test = struct {
...@@ -828,7 +826,6 @@ test "xxhash3 smhasher" {...@@ -828,7 +826,6 @@ test "xxhash3 smhasher" {
828}826}
829827
830test "xxhash3 iterative api" {828test "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/23807829 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
833830
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}
232232
233test "vector patterns" {233test "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 };
238236
...@@ -302,8 +300,6 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) {...@@ -302,8 +300,6 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) {
302}300}
303301
304test "vector shifting" {302test "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 };
308304
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}
369365
370test "vector searching" {366test "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 };
375368
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}
463456
464test "vector prefix scan" {457test "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/22060458 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/21893459 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 correct11267 => return result, // type of result is already correct
1126111268
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,
1127411294
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 _,
21442144
2145 pub const static_len = 118;2145 pub const static_len = 124;
21462146
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 AIR51 /// 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 more55 /// 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 AIR78 /// 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 more82 /// 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 AIR105 /// 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 more109 /// 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 }
11221134
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 };
11271139
...@@ -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};
13011313
1302pub const Shuffle = struct {
1303 a: Inst.Ref,
1304 b: Inst.Ref,
1305 mask: InternPool.Index,
1306 mask_len: u32,
1307};
1308
1309pub const VectorCmp = struct {1314pub 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};
13221327
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.
1330pub 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.
1356pub 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_len1387/// 0. `Inst.Ref` for every outputs_len
1325/// 1. `Inst.Ref` for every inputs_len1388/// 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 {
13931456
1394pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {1457pub 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,
14871550
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(),
15211585
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,
15781642
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,
16011665
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,
16071671
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,
16101674
1611 .tag_name, .error_name => return Type.slice_const_u8_sentinel_0,1675 .tag_name, .error_name => return .slice_const_u8_sentinel_0,
16121676
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 },
16171681
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)
16301694
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 },
16351699
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)
16411705
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 },
16461710
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,
16531717
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.
1697pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {1761pub 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}
20322097
2098pub 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
2118pub 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
2033pub const typesFullyResolved = types_resolved.typesFullyResolved;2140pub const typesFullyResolved = types_resolved.typesFullyResolved;
2034pub const typeFullyResolved = types_resolved.checkType;2141pub const typeFullyResolved = types_resolved.checkType;
2035pub const valFullyResolved = types_resolved.checkVal;2142pub const valFullyResolved = types_resolved.checkVal;
src/Air/Legalize.zig+1710-120
...@@ -1,147 +1,1737 @@...@@ -1,147 +1,1737 @@
1zcu: *const Zcu,1pt: Zcu.PerThread,
2air: Air,2air_instructions: std.MultiArrayList(Air.Inst),
3features: std.enums.EnumSet(Feature),3air_extra: std.ArrayListUnmanaged(u32),
4features: *const Features,
45
5pub const Feature = enum {6pub 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 bitcast88 /// 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};
11188
12pub const Features = std.enums.EnumFieldStruct(Feature, bool, false);189pub const Features = std.enums.EnumSet(Feature);
190
191pub const Error = std.mem.Allocator.Error;
13192
14pub fn legalize(air: *Air, backend: std.builtin.CompilerBackend, zcu: *const Zcu) std.mem.Allocator.Error!void {193pub 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,207fn 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}
44213
45fn legalizeBody(l: *Legalize, body: []const Air.Inst.Index) std.mem.Allocator.Error!void {214fn 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
218fn typeOfIndex(l: *const Legalize, inst: Air.Inst.Index) Type {
219 return l.getTmpAir().typeOfIndex(inst, &l.pt.zcu.intern_pool);
220}
221
222fn extraData(l: *const Legalize, comptime T: type, index: usize) @TypeOf(Air.extraData(undefined, T, undefined)) {
223 return l.getTmpAir().extraData(T, index);
224}
225
226fn 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,
52233 => {},
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
592const ScalarizeForm = enum { un_op, ty_op, bin_op, ty_pl_vector_cmp, pl_op_bin, shuffle_one, shuffle_two, select };
593inline 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}
596fn 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());
821037 _ = 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}
1059fn 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());
971207 _ = 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);1230fn 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}
1397fn 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
1488const 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
1606const 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
1631const 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
1656const 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
1696fn 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
1701fn 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
1712fn 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}
1321720
133// inline to propagate comptime `tag`s1721/// Returns `tag` to remind the caller to `continue :inst` the result.
134inline 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;1723inline 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}
1421729
143const Air = @import("../Air.zig");1730const Air = @import("../Air.zig");
144const codegen = @import("../codegen.zig");1731const assert = std.debug.assert;
1732const dev = @import("../dev.zig");
1733const InternPool = @import("../InternPool.zig");
145const Legalize = @This();1734const Legalize = @This();
146const std = @import("std");1735const std = @import("std");
1736const Type = @import("../Type.zig");
147const Zcu = @import("../Zcu.zig");1737const Zcu = @import("../Zcu.zig");
src/Air/Liveness.zig+24-9
...@@ -15,6 +15,7 @@ const Liveness = @This();...@@ -15,6 +15,7 @@ const Liveness = @This();
15const trace = @import("../tracy.zig").trace;15const trace = @import("../tracy.zig").trace;
16const Air = @import("../Air.zig");16const Air = @import("../Air.zig");
17const InternPool = @import("../InternPool.zig");17const InternPool = @import("../InternPool.zig");
18const Zcu = @import("../Zcu.zig");
1819
19pub const Verify = @import("Liveness/Verify.zig");20pub const Verify = @import("Liveness/Verify.zig");
2021
...@@ -136,12 +137,15 @@ fn LivenessPassData(comptime pass: LivenessPass) type {...@@ -136,12 +137,15 @@ fn LivenessPassData(comptime pass: LivenessPass) type {
136 };137 };
137}138}
138139
139pub fn analyze(gpa: Allocator, air: Air, intern_pool: *InternPool) Allocator.Error!Liveness {140pub 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();
142143
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 {
220pub fn categorizeOperand(224pub 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(
639649
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;
644654
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`.
825const Analysis = struct {835const 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.
22
3gpa: std.mem.Allocator,3gpa: std.mem.Allocator,
4zcu: *Zcu,
4air: Air,5air: Air,
5liveness: Liveness,6liveness: Liveness,
6live: LiveMap = .{},7live: 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);
639const Air = @import("../../Air.zig");643const Air = @import("../../Air.zig");
640const Liveness = @import("../Liveness.zig");644const Liveness = @import("../Liveness.zig");
641const InternPool = @import("../../InternPool.zig");645const InternPool = @import("../../InternPool.zig");
646const Zcu = @import("../../Zcu.zig");
642const Verify = @This();647const 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 },
251251
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 },
259269
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 {
25292529
2530pub fn clearMiscFailures(comp: *Compilation) void {2530pub 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 {
27952796
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 }
28012801
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,
45814581
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,
45884589
...@@ -4649,19 +4650,29 @@ pub const Index = enum(u32) {...@@ -4649,19 +4650,29 @@ pub const Index = enum(u32) {
46494650
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 },
50765087
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 // [*]u85102 // [*]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 } },
51035128
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 u85129 // []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 } },
52465262
5247 .{ .simple_value = .undefined },5263 .{ .simple_value = .undefined },
5264 .{ .undef = .bool_type },
5265 .{ .undef = .usize_type },
5266 .{ .undef = .u1_type },
52485267
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 } },
52585277
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 } },
52735297
5274 // one_u85298 .{ .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_u85307
5280 .{ .int = .{5308 .{ .int = .{
5281 .ty = .u8_type,5309 .ty = .u8_type,
5282 .storage = .{ .u64 = 4 },5310 .storage = .{ .u64 = 4 },
5283 } },5311 } },
5284 // negative_one5312
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 {
1190911938
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,
1191911949
11920 // This optimization on tags is needed so that indexToKey can call11950 // 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,
1218812218
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 {
1225112282
12252 // values, not types12283 // 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}
26432643
2644const align_ty = Type.u29;2644const align_ty: Type = .u29;
26452645
2646pub fn analyzeAsAlign(2646pub 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);
28242824
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);
37813781
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 wish3783 // 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,
38483848
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);
38523852
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 by5343 // 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();
58295829
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}
58335833
5834fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5834fn 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);
58485848
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}
58715871
5872fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5872fn 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 };
66426642
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));
66456645
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(
70057005
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;
70827082
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 }
70877087
...@@ -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 type7570 // 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();
86048604
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
89128912
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_poison9299 .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;
93219310
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(
96499638
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_type9860 bare_return_type
9872 else9861 else
9873 Type.fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index)));9862 .fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index)));
98749863
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}
1017910159
10180fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {10160fn 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);
1028510265
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}
1028810268
10289fn intCast(10269fn 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(
1031410292
10315 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {10293 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {
10316 // requirement: intCast(u0, input) iff input == 010294 // 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 }
1033710315
...@@ -10339,91 +10317,11 @@ fn intCast(...@@ -10339,91 +10317,11 @@ fn intCast(
10339 }10317 }
1034010318
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}
1065510543
10656fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {10544fn 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}
1068110569
...@@ -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!
1068510573
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}
1069110579
...@@ -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}
1073410622
...@@ -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;
1115511043
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]);
1115811046
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 hit11053 // 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;
1117111059
...@@ -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 }
1117911067
...@@ -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 };
1134211230
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 {
1136511253
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 false13058 } else false
13171 else13059 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 );
1350713395
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 }
1351113399
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 }
1433614224
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 else14240 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);
1435614243
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 }
1469114578
14692 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);14579 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
14693}14580}
1469414581
14695fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14582fn 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 });
1471714604
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
1489214779
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);
1490814795
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);
1493314820
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
1494314830
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 }
1511515002
15116 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);15003 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
15117}15004}
1511815005
15119fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15006fn 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
1516615053
15167 if (lhs_ty.isTuple(zcu)) {15054 if (lhs_ty.isTuple(zcu)) {
15168 // In `**` rhs must be comptime-known, but lhs can be runtime-known15055 // 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 };
1518915076
15190 // In `**` rhs must be comptime-known, but lhs can be runtime-known15077 // 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 });
1519215079
15193 const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch15080 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 }
1525215139
...@@ -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);
1613316020
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]);
1613616023
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 stored16031 // 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}
1630716193
16308fn 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
16326fn analyzeArithmetic(16194fn 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) catch16248 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 }
1649916367
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);
1691716751
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(
1702716861
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;
1703216866
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,
1711116945
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,
1715216986
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}
1717217006
17173fn zirThis(17007fn 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
1728517119
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}
1729017124
17291fn zirRetAddr(17125fn 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. #1493817133 // 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 };
1735517190
...@@ -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 };
1738117216
...@@ -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 };
1740717242
...@@ -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 };
1751717352
...@@ -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
1758017415
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 else17433 else
17599 try Type.fromInterned(info.child).lazyAbiAlignment(pt);17434 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1760017435
...@@ -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 };
1772917564
...@@ -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 else17656 else
17822 (try pt.intValue(Type.comptime_int, tag_index)).toIntern();17657 (try pt.intValue(.comptime_int, tag_index)).toIntern();
1782317658
17824 // TODO: write something like getCoercedInts to avoid needing to dupe17659 // 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 };
1785017685
...@@ -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 };
1789317728
...@@ -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 };
1795517790
...@@ -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 };
1800617841
...@@ -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 };
1807617911
...@@ -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 else17946 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 };
1814017975
...@@ -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 };
1820118036
...@@ -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}
1831018145
...@@ -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);
1851418349
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}
1852418357
18525fn zirBoolBr(18358fn 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 });
1854618379
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);
1854818381
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 }
1856418397
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);
1879818631
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);
1880118634
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, in19340 // 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;
1953219365
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;
1953919372
...@@ -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]);
1990619739
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);
2018520018
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 }
2031920152
20320 return block.addAggregateInit(Type.fromInterned(struct_ty), element_refs);20153 return block.addAggregateInit(.fromInterned(struct_ty), element_refs);
20321}20154}
2032220155
20323fn zirArrayInit(20156fn 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());
2044320276
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());
2045620289
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);
2050620339
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 }
2056320396
20564 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);20397 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
20565}20398}
2056620399
20567fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {20400fn 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 else20556 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}
2074520566
20746fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20567fn 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);
2075120572
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);
2099520816
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 ).?);
2104020861
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 }
2104420865
...@@ -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) orelse20997 const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse
21177 return Air.internedToRef(Type.anyerror.toIntern());20998 return .anyerror_type;
2117820999
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 });
2118021001
...@@ -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 error21597 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2177721598
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 }
2206121882
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 }
2206621887
...@@ -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}
2237622178
22377fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22179fn 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);
2238722189
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;
2239022191
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 }
2240322204
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}
2241722208
22418fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22209fn 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);
2243222223
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;
2243822229
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);
2244022231
...@@ -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 & mask22289 if (elem_ty.fnPtrMaskOrNull(zcu)) |mask|
22531 else22290 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 }
2254022303 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}
2254922305
22550fn ptrFromIntVal(22306fn ptrFromIntVal(
...@@ -22918,12 +22674,12 @@ fn ptrCastFull(...@@ -22918,12 +22674,12 @@ fn ptrCastFull(
22918 }22674 }
2291922675
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 -> []T22678 // *[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);
2292522681
22926 const dest_child = Type.fromInterned(dest_info.child);22682 const dest_child: Type = .fromInterned(dest_info.child);
2292722683
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 -> []T22714 // [*]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);
2328923045
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!
2365823414
23659fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23415fn 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}
2366323419
23664fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23420fn 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 structs23422 // 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}
2366923425
23670fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {23426fn 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 });
2451724266
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
2453924288 // 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);
2454824297 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
2455124300 // 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);
2455624305 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);
2457524318 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 }
2459024336
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 }
2461024339
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 we24341 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));
2462024342
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(.{
2463224388 .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}
2465524415
24656fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {24416fn 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;
2612025880
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;
2613325893
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 }
2622525985
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 }
2625026010
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);
2625326013
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 }
2648626246
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);
2648926249
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(
2676026520
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(
2678026540
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(
2717126931
27172 defer fail_block.instructions.deinit(gpa);26932 defer fail_block.instructions.deinit(gpa);
2717326933
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);
2717626936
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) orelse27530 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]);
2777327533
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;
2781927579
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() or27581 if (first_param_type.isGenericPoison() or
27822 (first_param_type.zigTypeTag(zcu) == .pointer and27582 (first_param_type.zigTypeTag(zcu) == .pointer and
27823 (first_param_type.ptrSize(zcu) == .one or27583 (first_param_type.ptrSize(zcu) == .one or
...@@ -28003,7 +27763,7 @@ fn structFieldPtr(...@@ -28003,7 +27763,7 @@ fn structFieldPtr(
2800327763
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 }
2813627896
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());
2814027900
...@@ -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() and28092 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).?);
2836828128
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);
2837128131
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() and28168 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(
2854028300
28541 // TODO in case of a vector of pointers, we need to detect whether the element28301 // 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);
2854428304
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(
2886028620
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(
2891728677
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 else28681 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;
2916628926
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 or29067 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;
2931029070
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(
2936429124
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(
2937829138
29379 if (dest_info.sentinel == .none or inst_info.sentinel == .none or29139 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;
2938329143
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 }
3066030420
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 }
3073730497
...@@ -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 location30650 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 };
3135931119
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(
3144831208
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;
3153731297
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 location31300 const src = inst_src; // TODO better source location
31541 const elem_src = inst_src; // TODO better source location31301 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);
3172231482
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 };
3173031490
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:
3188531645
31886fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {31646fn 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}
3215031910
32151fn analyzeIsNull(31911fn 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 }
3230932069
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 );
3241332166
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;
3251432267
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);
3251832271
...@@ -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));
3252732280
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 else32295 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 sentinel32310 // end_is_len is only true if we are NOT using the sentinel
32558 // length. For sentinel-length, we don't want the type to32311 // 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 else32340 else
...@@ -32602,8 +32355,8 @@ fn analyzeSlice(...@@ -32602,8 +32355,8 @@ fn analyzeSlice(
32602 // If the slice has a sentinel, we consider end_is_len32355 // If the slice has a sentinel, we consider end_is_len
32603 // is only true if it equals the length WITHOUT the32356 // 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 <= end32398 // 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 else32472 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(
3275332506
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_inst32513 slice_len_inst
32761 else32514 else
...@@ -32811,15 +32564,15 @@ fn analyzeSlice(...@@ -32811,15 +32564,15 @@ fn analyzeSlice(
3281132564
32812 // requirement: end <= len32565 // 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 the32570 // we don't need to add one for sentinels because the
32818 // underlying value data includes the sentinel32571 // 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 }
3282132574
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;
3282432577
32825 // we have to add one because slice lengths don't include the sentinel32578 // 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 }
3293632689
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;
3294032693
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 },
3379033543
33791 .optional => {33544 .optional => {
...@@ -34006,7 +33759,7 @@ fn resolvePeerTypesInner(...@@ -34006,7 +33759,7 @@ fn resolvePeerTypesInner(
34006 };33759 };
3400733760
34008 // Try peer -> cur, then cur -> peer33761 // 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 };
3415433907
34155 // We abstract array handling slightly so that tuple pointers can work like array pointers33908 // 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));
3415833911
34159 // This switch is just responsible for deciding the size and pointee (not including33912 // 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 -> [*]T33958 // 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 -> []T33971 // 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 -> [*]T33987 // 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" -> [*]T34017 // 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 -> []T34029 // 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 },
3448434237
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 },
3449834251
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_longdouble34354 // 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 anyway34473 // 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 });
3474534498
34746 return .{ .success = Type.fromInterned(final_ty) };34499 return .{ .success = .fromInterned(final_ty) };
34747 },34500 },
3474834501
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";
3490334656
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";
3495434707
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);
3500234755
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(
3523434987
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;
3523934992
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]);
3528635039
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?
3528835041
...@@ -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() and35060 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);
3531335066
...@@ -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.
3539335146
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 {
3542135174
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 with35306 // set. However, in the case of comptime/inline function calls with
35554 // inferred error sets, each call gets an adhoc InferredErrorSet object, which35307 // 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 used35761 // 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.
3601035763
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 }
3613635889
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 }
3628936042
36290 const field_ty: Type = if (!has_type)36043 const field_ty: Type = if (!has_type)
36291 Type.void36044 .void
36292 else if (field_type_ref == .none)36045 else if (field_type_ref == .none)
36293 Type.noreturn36046 .noreturn
36294 else36047 else
36295 try sema.resolveType(&block_scope, type_src, field_type_ref);36048 try sema.resolveType(&block_scope, type_src, field_type_ref);
3629636049
...@@ -36388,11 +36141,11 @@ fn unionFields(...@@ -36388,11 +36141,11 @@ fn unionFields(
3638836141
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 types36350 // 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 } }));
3670736466
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);
3677436533
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)))) orelse36535 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)) orelse36542 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;
3679836557
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 else36577 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;
3704236801
37043 // optionals of zero sized types behave like bools, not pointers36802 // 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();
3717736936
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());
3717936938
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));
3728337042
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 {
1043fn intAddWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {1043fn 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 {
1125fn intSubWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {1125fn 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 {
1211fn intMulWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {1211fn 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 };
4100pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type };4100pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type };
4101pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type };4101pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type };
41024102
4103pub const ptr_usize: Type = .{ .ip_index = .ptr_usize_type };
4104pub const ptr_const_comptime_int: Type = .{ .ip_index = .ptr_const_comptime_int_type };
4103pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type };4105pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type };
4104pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };4106pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };
4105pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type };4107pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type };
4106pub const single_const_pointer_to_comptime_int: Type = .{ .ip_index = .single_const_pointer_to_comptime_int_type };
4107pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };4108pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
4108pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };4109pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };
41094110
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 {
28952895
2896pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;2896pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;
28972897
2898pub const undef: Value = .{ .ip_index = .undef };
2899pub const undef_bool: Value = .{ .ip_index = .undef_bool };
2900pub const undef_usize: Value = .{ .ip_index = .undef_usize };
2901pub const undef_u1: Value = .{ .ip_index = .undef_u1 };
2902pub const zero_comptime_int: Value = .{ .ip_index = .zero };
2898pub const zero_usize: Value = .{ .ip_index = .zero_usize };2903pub const zero_usize: Value = .{ .ip_index = .zero_usize };
2904pub const zero_u1: Value = .{ .ip_index = .zero_u1 };
2899pub const zero_u8: Value = .{ .ip_index = .zero_u8 };2905pub const zero_u8: Value = .{ .ip_index = .zero_u8 };
2900pub const zero_comptime_int: Value = .{ .ip_index = .zero };
2901pub const one_comptime_int: Value = .{ .ip_index = .one };2906pub const one_comptime_int: Value = .{ .ip_index = .one };
2907pub const one_usize: Value = .{ .ip_index = .one_usize };
2908pub const one_u1: Value = .{ .ip_index = .one_u1 };
2909pub const one_u8: Value = .{ .ip_index = .one_u8 };
2910pub const four_u8: Value = .{ .ip_index = .four_u8 };
2902pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one };2911pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one };
2903pub const undef: Value = .{ .ip_index = .undef };
2904pub const @"void": Value = .{ .ip_index = .void_value };2912pub const @"void": Value = .{ .ip_index = .void_value };
2913pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };
2905pub const @"null": Value = .{ .ip_index = .null_value };2914pub const @"null": Value = .{ .ip_index = .null_value };
2906pub const @"false": Value = .{ .ip_index = .bool_false };
2907pub const @"true": Value = .{ .ip_index = .bool_true };2915pub const @"true": Value = .{ .ip_index = .bool_true };
2908pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };2916pub const @"false": Value = .{ .ip_index = .bool_false };
2909
2910pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type };
2911pub const empty_tuple: Value = .{ .ip_index = .empty_tuple };2917pub const empty_tuple: Value = .{ .ip_index = .empty_tuple };
29122918
2913pub fn makeBool(x: bool) Value {2919pub 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};
38533831
3854pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {3832pub 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 }
17431743
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 }
17461747
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);
17491750
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 }
30283030
...@@ -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}
38453847
3848/// `ty` is an integer or a vector of integers.
3849pub 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
3846pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type {3863pub 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;
4040
41const InnerError = CodeGenError || error{OutOfRegisters};41const InnerError = CodeGenError || error{OutOfRegisters};
4242
43pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
44 return null;
45}
46
43gpa: Allocator,47gpa: Allocator,
44pt: Zcu.PerThread,48pt: Zcu.PerThread,
45air: Air,49air: 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)));
28752884
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}
29943006
2995fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void {3007fn 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}
30003018
...@@ -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}
60346052
6035fn airShuffle(self: *Self, inst: Air.Inst.Index) InnerError!void {6053fn 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
6058fn 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}
60416062
6042fn airReduce(self: *Self, inst: Air.Inst.Index) InnerError!void {6063fn 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;
4141
42const InnerError = CodeGenError || error{OutOfRegisters};42const InnerError = CodeGenError || error{OutOfRegisters};
4343
44pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
45 return null;
46}
47
44gpa: Allocator,48gpa: Allocator,
45pt: Zcu.PerThread,49pt: Zcu.PerThread,
46air: Air,50air: 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));
18581863
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}
19791987
1980fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {1988fn 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}
19851999
...@@ -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}
60046024
6005fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {6025fn 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
6030fn airShuffleTwo(self: *Self, inst: Air.Inst.Index) !void {
6031 _ = inst;
6032 return self.fail("TODO implement airShuffleTwo for arm", .{});
6009}6033}
60106034
6011fn airReduce(self: *Self, inst: Air.Inst.Index) !void {6035fn 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");
10const assert = std.debug.assert;10const assert = std.debug.assert;
11const log = std.log.scoped(.codegen);11const log = std.log.scoped(.codegen);
1212
13pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
14 return null;
15}
16
13pub fn generate(17pub 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;
5151
52const InnerError = CodeGenError || error{OutOfRegisters};52const InnerError = CodeGenError || error{OutOfRegisters};
5353
54pub 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
54pt: Zcu.PerThread,63pt: Zcu.PerThread,
55air: Air,64air: Air,
56liveness: Air.Liveness,65liveness: 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);
27692780
...@@ -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}
32493260
3250fn airShlWithOverflow(func: *Func, inst: Air.Inst.Index) !void {3261fn 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}
32553272
...@@ -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}
32673284
3268fn airShlSat(func: *Func, inst: Air.Inst.Index) !void {3285fn 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}
32733296
...@@ -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}
80108033
8011fn airShuffle(func: *Func, inst: Air.Inst.Index) !void {8034fn 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
8039fn airShuffleTwo(func: *Func, inst: Air.Inst.Index) !void {
8040 _ = inst;
8041 return func.fail("TODO implement airShuffleTwo for riscv64", .{});
8015}8042}
80168043
8017fn airReduce(func: *Func, inst: Air.Inst.Index) !void {8044fn 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();
4141
42const InnerError = CodeGenError || error{OutOfRegisters};42const InnerError = CodeGenError || error{OutOfRegisters};
4343
44pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
45 return null;
46}
47
44const RegisterView = enum(u1) {48const 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}
22712276
2272fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {2277fn 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}
22772288
...@@ -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);
22882299
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(
30023016
3003 // Truncate if necessary3017 // 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;
31const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;31const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;
32const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;32const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
3333
34pub 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 code43/// Reference to the function declaration the code
35/// section belongs to44/// section belongs to
36owner_nav: InternPool.Nav.Index,45owner_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);
30573071
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 }
30613079
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}
51625180
5163fn airShuffle(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5181fn 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;
51695184
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);
51745189
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);
51775192
5178 // TODO: One of them could be by ref; handle in loop5193 // 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);
51815195
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", .{});
51845200
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}
51865212
5187 const loaded = if (value >= 0)5213fn 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 else5215 const zcu = pt.zcu;
5190 try cg.load(b, child_ty, @as(u32, @intCast(@as(i64, @intCast(elem_size)) * ~value)));
51915216
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);
51945222
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));
52085227
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 }
52135249 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 } });
52205260 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}
52245281
5225fn airReduce(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5282fn 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);
60696126
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 }
60736134
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 };
60786139
6079 // Ensure rhs is coerced to lhs as they must have the same WebAssembly types6140 // 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 {
69947055
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;
3232
33const InnerError = codegen.CodeGenError || error{OutOfRegisters};33const InnerError = codegen.CodeGenError || error{OutOfRegisters};
3434
35pub const legalize_features: Air.Legalize.Features = .{35pub 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}
39108
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/22419110/// 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 abi289 /// 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 memory430 => 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 dereferenceable464 => 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 valid484 => 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());
22402309
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);
22472322
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: off2506 // 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: on2509 // zig fmt: on
24352510
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) or162711 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 pointer168449 => 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 pointer168667 => 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 destination169154 => 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 destination172008 => 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 destination172431 => 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();
172276172582
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 }
173883174195
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}
174455174767
174456fn 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
174468fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {174768fn 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 destination175893 => 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(
180611180905
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 pointer181971 => 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};
2929
30fn devFeatureForBackend(comptime backend: std.builtin.CompilerBackend) dev.Feature {30fn 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}
3447
35pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type {48fn 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}
4964
65pub 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
50pub fn generateFunction(88pub 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.result126 zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
89 else127 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;
4const mem = std.mem;4const mem = std.mem;
5const log = std.log.scoped(.c);5const log = std.log.scoped(.c);
66
7const dev = @import("../dev.zig");
7const link = @import("../link.zig");8const link = @import("../link.zig");
8const Zcu = @import("../Zcu.zig");9const Zcu = @import("../Zcu.zig");
9const Module = @import("../Package/Module.zig");10const Module = @import("../Package/Module.zig");
...@@ -20,6 +21,15 @@ const Alignment = InternPool.Alignment;...@@ -20,6 +21,15 @@ const Alignment = InternPool.Alignment;
20const BigIntLimb = std.math.big.Limb;21const BigIntLimb = std.math.big.Limb;
21const BigInt = std.math.big.int;22const BigInt = std.math.big.int;
2223
24pub 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
23pub const CType = @import("c/Type.zig");33pub const CType = @import("c/Type.zig");
2434
25pub const CValue = union(enum) {35pub 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", {} },
268277
278 // stdbool.h
279 .{ "bool", {} },
280 .{ "false", {} },
281 .{ "true", {} },
282
269 // stddef.h283 // stddef.h
270 .{ "offsetof", {} },284 .{ "offsetof", {} },
271285
...@@ -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}
71517166
7152fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {7167fn 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;
71577170
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);
71617174 const inst_ty = unwrapped.result_ty;
7162 const inst_ty = f.typeOfIndex(inst);
71637175
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 operands7178 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 }
71727195
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
7199fn 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);
71757209
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 }
71817235
7182 return local;7236 return local;
...@@ -8311,11 +8365,11 @@ const Vectorize = struct {...@@ -8311,11 +8365,11 @@ const Vectorize = struct {
83118365
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();
83208374
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),
14101410
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 },
21582162
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
21762185
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;
3636
37const Error = error{ OutOfMemory, CodegenFail };37const Error = error{ OutOfMemory, CodegenFail };
3838
39pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
40 return null;
41}
42
39fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 {43fn 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 types3104 // 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);
89188929
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);
89218934
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);
89879000
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);
89909005
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 {
89979012
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;
90019017
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);
90049020
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", .{});
90069024
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 }
90109028
...@@ -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);
90249042
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);
90969116
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);
90999121
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));
91699191
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 };
91759193
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 }
91919209
...@@ -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);
92549270
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);
92609276
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 }
93449362
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 }
93489368 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 }
93529371
...@@ -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 }
1040110420
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);
1041310432 const llvm_operand_ty = try o.lowerType(operand_ty);
10414 // LLVM uses integers larger than the length of the first array to10433 const llvm_result_ty = try o.lowerType(unwrapped.result_ty);
10415 // index into the second array. This was deemed unnecessarily fragile10434 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu));
10416 // when changing code, so Zig uses negative numbers to index the10435 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 use10436 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.
1042110440 // 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 );
1043210504
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 }
1043910608
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");
2828
29const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);29const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);
3030
31pub 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
31pub const zig_call_abi_ver = 3;40pub const zig_call_abi_ver = 3;
32pub const big_int_bits = 32;41pub const big_int_bits = 32;
3342
...@@ -3243,7 +3252,8 @@ const NavGen = struct {...@@ -3243,7 +3252,8 @@ const NavGen = struct {
32433252
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),
32473257
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;
33823392
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);
33853399
...@@ -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;
38683882
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);
38713889
...@@ -4030,40 +4048,57 @@ const NavGen = struct {...@@ -4030,40 +4048,57 @@ const NavGen = struct {
4030 return result_id;4048 return result_id;
4031 }4049 }
40324050
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);
40414055
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);
40464061
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);
40494064
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 }
40564071
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 }
40644099
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 }
40684103
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 @@
1pub const Env = enum {1pub const Env = enum {
2 /// zig1 features2 /// zig1 features
3 /// - `-ofmt=c` only
4 /// - `-OReleaseFast` or `-OReleaseSmall` only
5 /// - no `@setRuntimeSafety(true)`
3 bootstrap,6 bootstrap,
47
5 /// zig2 features8 /// 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,
225231
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 }
501502
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 }
505518
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 }
511537
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 @@
481481
482zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);482zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
483zig_extern void *memset (void *, int, size_t);483zig_extern void *memset (void *, int, size_t);
484zig_extern void *memmove (void *, void const *, size_t);
484485
485/* ================ Bool and 8/16/32/64-bit Integer Support ================= */486/* ================ Bool and 8/16/32/64-bit Integer Support ================= */
486487
...@@ -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
18501852
1851static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {1853static 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}
18571862
1858static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {1863static 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}
18631873
1864static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {1874static 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; // TODO96 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO97 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO98 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;
10099
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 {
211test "@abs int vectors" {210test "@abs int vectors" {
212 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO211 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
213 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO212 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; // TODO213 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO215 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; // TODO837 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
838 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO838 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
839 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO839 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; // TODO840 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
842841
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; // TODO386 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;
388387
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; // TODO13 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;
1716
18 try comptime testBitReverse();17 try comptime testBitReverse();
...@@ -123,7 +122,6 @@ fn vector8() !void {...@@ -123,7 +122,6 @@ fn vector8() !void {
123122
124test "bitReverse vectors u8" {123test "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; // TODO127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -144,7 +142,6 @@ fn vector16() !void {...@@ -144,7 +142,6 @@ fn vector16() !void {
144142
145test "bitReverse vectors u16" {143test "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; // TODO147 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -165,7 +162,6 @@ fn vector24() !void {...@@ -165,7 +162,6 @@ fn vector24() !void {
165162
166test "bitReverse vectors u24" {163test "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; // TODO167 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;
4342
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 {
9594
96test "@byteSwap vectors u8" {95test "@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; // TODO99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -116,7 +114,6 @@ fn vector16() !void {...@@ -116,7 +114,6 @@ fn vector16() !void {
116114
117test "@byteSwap vectors u16" {115test "@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; // TODO119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -137,7 +134,6 @@ fn vector24() !void {...@@ -137,7 +134,6 @@ fn vector24() !void {
137134
138test "@byteSwap vectors u24" {135test "@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; // TODO139 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; // TODO617 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
618 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO618 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
619 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO619 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; // TODO2519 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2520 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;
25252523
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; // TODO2590 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2593 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2591 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;
25962593
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; // TODO2690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2694 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO2691 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2695 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2692 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;
5test "anyopaque extern symbol" {5test "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;
109
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}
1515
16test "add f16" {16test "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;
1918
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 {
123125
124test "cmp f16" {126test "cmp f16" {
125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO127 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/21234129 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
129130
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; // TODO140 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/21234141 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;
139142
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" {
144test "cmp f64" {147test "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; // TODO149 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/21234150 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
149151
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; // TODO342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO343 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
342 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO344 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;
345346
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; // TODO392 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
389 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
390 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO394 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;
394397
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; // TODO406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
402 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO408 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;
405410
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; // TODO1137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1133 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1134 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1139 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;
11371141
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; // TODO1273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1267 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1268 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1275 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;
12711277
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; // TODO1341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1333 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1342 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;
13361347
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; // TODO1374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1364 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1375 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1376 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;
13681378
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; // TODO1442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1430 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1443 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;
14331448
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; // TODO1475 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1461 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1462 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1477 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;
14651479
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; // TODO1543 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1527 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1544 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;
15301549
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; // TODO1565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1548 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1567 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;
15511569
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 failure1574 // 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; // TODO429 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO430 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;
433432
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; // TODO85 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
86 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO86 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;
9089
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 {
103102
104test "@clz vectors" {103test "@clz vectors" {
105 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO104 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; // TODO105 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
108 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO107 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}
174172
175test "@ctz 128-bit integers" {173test "@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; // TODO174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
178 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO175 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
179 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -193,7 +190,6 @@ fn testCtz128() !void {...@@ -193,7 +190,6 @@ fn testCtz128() !void {
193190
194test "@ctz vectors" {191test "@ctz vectors" {
195 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO192 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; // TODO193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
198 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
199 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO195 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; // TODO471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
477 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO473 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;
481476
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();
484482
...@@ -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; // TODO1621 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1624 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1625 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1623 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; // TODO1624 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;
16301628
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;
16961694
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" {
17851780
1786test "@clz works on both vector and scalar inputs" {1781test "@clz works on both vector and scalar inputs" {
1787 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1782 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; // TODO1783 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1790 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1784 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1791 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1785 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; // TODO1801 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1808 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1802 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/212341805 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
18131806
...@@ -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; // TODO1831 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1839 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1832 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/212341835 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
18441836
...@@ -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; // TODO1928 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;
19401934
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; // TODO34 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;
3837
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; // TODO89 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;
9492
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; // TODO204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO205 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;
210207
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; // TODO257 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO258 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;
264260
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; // TODO299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
304 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO300 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;
307302
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; // TODO370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
376 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO371 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;
379373
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; // TODO6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO8 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;
1211
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; // TODO139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO141 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;
143144
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; // TODO167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO169 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;
169172
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}
13091309
1310test "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
1310test "packed struct with signed field" {1321test "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 {
7777
78test "@popCount vectors" {78test "@popCount vectors" {
79 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO79 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; // TODO80 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO81 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO82 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; // TODO41 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;
4644
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 {
70test "@select compare result" {68test "@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;
7572
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; // TODO10 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;
1513
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" {
5351
54test "@shuffle int strange sizes" {52test "@shuffle int strange sizes" {
55 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO53 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; // TODO54 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -136,7 +133,6 @@ fn testShuffle(...@@ -136,7 +133,6 @@ fn testShuffle(
136133
137test "@shuffle bool 1" {134test "@shuffle bool 1" {
138 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO135 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; // TODO136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
141 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO138 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" {
160156
161test "@shuffle bool 2" {157test "@shuffle bool 2" {
162 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO158 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; // TODO159 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO161 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; // TODO284 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;
285286
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; // TODO31 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;
3534
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" {
7675
77test "vector int operators" {76test "vector int operators" {
78 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO77 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; // TODO78 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO80 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;
8584
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; // TODO248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
250 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO249 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;
254252
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" {
286287
287test "tuple to vector" {288test "tuple to vector" {
288 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO289 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; // TODO290 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
291 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO291 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO292 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;
294295
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" {
652test "vector bitwise not operator" {653test "vector bitwise not operator" {
653 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO654 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; // TODO656 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
657 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO657 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
658 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO658 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" {
684684
685test "vector shift operators" {685test "vector shift operators" {
686 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO686 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; // TODO687 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
689 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO688 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
690 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO689 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;
693693
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; // TODO908 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
909 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO909 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;
913911
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; // TODO932 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;
938935
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; // TODO966 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;
973969
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" {
989985
990test "saturating multiplication" {986test "saturating multiplication" {
991 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO987 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; // TODO988 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
994 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO989 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
995 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO990 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1018,12 +1013,12 @@ test "saturating multiplication" {...@@ -1018,12 +1013,12 @@ test "saturating multiplication" {
10181013
1019test "saturating shift-left" {1014test "saturating shift-left" {
1020 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1015 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; // TODO1016 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1023 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1024 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1018 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;
10271022
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" {
10431038
1044test "multiplication-assignment operator with an array operand" {1039test "multiplication-assignment operator with an array operand" {
1045 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1040 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; // TODO1041 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1048 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1042 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1049 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1043 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;
10521047
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" {
10651060
1066test "@addWithOverflow" {1061test "@addWithOverflow" {
1067 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1062 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; // TODO1063 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1070 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1064 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1071 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1065 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1116,7 +1110,6 @@ test "@addWithOverflow" {...@@ -1116,7 +1110,6 @@ test "@addWithOverflow" {
11161110
1117test "@subWithOverflow" {1111test "@subWithOverflow" {
1118 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1112 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; // TODO1113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1121 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1122 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1151,7 +1144,6 @@ test "@subWithOverflow" {...@@ -1151,7 +1144,6 @@ test "@subWithOverflow" {
11511144
1152test "@mulWithOverflow" {1145test "@mulWithOverflow" {
1153 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1146 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; // TODO1147 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1148 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1157 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1175,7 +1167,6 @@ test "@mulWithOverflow" {...@@ -1175,7 +1167,6 @@ test "@mulWithOverflow" {
11751167
1176test "@shlWithOverflow" {1168test "@shlWithOverflow" {
1177 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1169 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; // TODO1170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1172 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; // TODO1305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1315 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1316 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO1307 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1317 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1308 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
13181309
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; // TODO1353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1363 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1354 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1355 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;
13671357
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; // TODO1459 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1460 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1471 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1461 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; // TODO1462 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;
14751464
test/behavior/x86_64/binary.zig+40-16
...@@ -1,5 +1,7 @@...@@ -1,5 +1,7 @@
1const AddOneBit = math.AddOneBit;1const AddOneBit = math.AddOneBit;
2const AsSignedness = math.AsSignedness;
2const cast = math.cast;3const cast = math.cast;
4const ChangeScalar = math.ChangeScalar;
3const checkExpected = math.checkExpected;5const checkExpected = math.checkExpected;
4const Compare = math.Compare;6const Compare = math.Compare;
5const DoubleBits = math.DoubleBits;7const DoubleBits = math.DoubleBits;
...@@ -13,6 +15,7 @@ const math = @import("math.zig");...@@ -13,6 +15,7 @@ const math = @import("math.zig");
13const nan = math.nan;15const nan = math.nan;
14const Scalar = math.Scalar;16const Scalar = math.Scalar;
15const sign = math.sign;17const sign = math.sign;
18const splat = math.splat;
16const Sse = math.Sse;19const Sse = math.Sse;
17const tmin = math.tmin;20const tmin = math.tmin;
1821
...@@ -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 {
5141test mulSat {5144test 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}
51455149
5146inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) {5150inline 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}
52425246
5243inline fn addWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5247inline 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}
5246test addWithOverflow {5250test 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}
52505255
5251inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5256inline 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}
5254test subWithOverflow {5259test 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}
52585264
5259inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5265inline 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}
5262test mulWithOverflow {5268test 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}
52665273
5267inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5274inline 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}
5272test shlWithOverflow {5279test 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}
52765284
5277inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {5285inline 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) {
5280test equal {5288test 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}
52855295
5286inline fn notEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs != rhs) {5296inline 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
5289test notEqual {5299test 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}
52945306
5295inline fn lessThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs < rhs) {5307inline 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)
5298test lessThan {5310test 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}
53035317
5304inline fn lessThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs <= rhs) {5318inline 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
5307test lessThanOrEqual {5321test 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}
53125328
5313inline fn greaterThan(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs > rhs) {5329inline 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
5316test greaterThan {5332test 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}
53215339
5322inline fn greaterThanOrEqual(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs >= rhs) {5340inline 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(
5325test greaterThanOrEqual {5343test 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}
53305350
5331inline fn bitAnd(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs & rhs) {5351inline 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}
53485368
5349inline fn shr(comptime Type: type, lhs: Type, rhs: Type) Type {5369inline 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}
5354test shr {5374test 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}
53585379
5359inline fn shrExact(comptime Type: type, lhs: Type, rhs: Type) Type {5380inline 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}
5365test shrExact {5386test 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}
53695391
5370inline fn shl(comptime Type: type, lhs: Type, rhs: Type) Type {5392inline 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}
5375test shl {5397test 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}
53795402
5380inline fn shlExactUnsafe(comptime Type: type, lhs: Type, rhs: Type) Type {5403inline 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}
5387test shlExactUnsafe {5410test 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}
53915415
5392inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type {5416inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type {
5393 // workaround https://github.com/ziglang/zig/issues/230345417 // workaround https://github.com/ziglang/zig/issues/23034
5394 if (@inComptime()) {5418 if (@inComptime()) {
5395 // workaround https://github.com/ziglang/zig/issues/231395419 // 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/230335422 // 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 {
5403test shlSat {5426test 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}
54075431
5408inline fn bitXor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs ^ rhs) {5432inline 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;
8pub const imax = math.maxInt;8pub const imax = math.maxInt;
9pub const imin = math.minInt;9pub const imin = math.minInt;
10pub const inf = math.inf;10pub const inf = math.inf;
11pub const Log2Int = math.Log2Int;
12pub const Log2IntCeil = math.Log2IntCeil;
13pub const nan = math.nan;11pub const nan = math.nan;
14pub const next = math.nextAfter;12pub const next = math.nextAfter;
15pub const tmin = math.floatTrueMin;13pub 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}
31pub 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}
37pub 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}
33pub fn AddOneBit(comptime Type: type) type {43pub 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}
44pub fn DoubleBits(comptime Type: type) type {50pub 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}
55pub fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type {57pub 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,64pub fn Log2Int(comptime Type: type) type {
63 .vector => |vector| @Vector(vector.len, ResultScalar),65 return ChangeScalar(Type, math.Log2Int(Scalar(Type)));
64 };66}
67pub 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`
67pub inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type {71pub 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}
81pub fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) {85pub 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}
95fn boolAnd(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) {93fn 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)) {
4828test ctz {4828test 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}
48324833
4833inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) {4834inline 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)) {
4836test popCount {4837test 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}
48404842
4841inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) {4843inline 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) {
4844test byteSwap {4846test 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}
48484851
4849inline fn bitReverse(comptime Type: type, rhs: Type) @TypeOf(@bitReverse(rhs)) {4852inline 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)) {
4852test bitReverse {4855test 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}
48564860
4857inline fn sqrt(comptime Type: type, rhs: Type) @TypeOf(@sqrt(rhs)) {4861inline 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 here117// 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 here119// 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 here121// 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 here123// 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 here125// 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// error15// error
16//16//
17// :7:25: error: unable to resolve comptime value17// :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-known18// :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 field19// :4:16: note: struct requires comptime because of this field
20// :4:16: note: types are not available at runtime20// :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 here20// :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 {
66
7// error7// 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 here10// :3:16: note: struct declared here
11// :1:11: note: struct declared here11// :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 here48// :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 here50// :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 @@
1export fn entry() void {1export 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}
7export 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}
713
8// error14// error
9// backend=stage2
10// target=native
11//15//
12// :4:41: error: mask index '4' has out-of-bounds selection16// :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 numbers18// :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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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// run17// run
18// backend=llvm18// backend=stage2,llvm
19// target=native19// 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// 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
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// 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
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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}
1818
19// run19// run
20// backend=llvm20// backend=stage2,llvm
21// target=native21// 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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}
1818
19// run19// run
20// backend=llvm20// backend=stage2,llvm
21// target=native21// 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub 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// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// 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// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// 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// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// 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// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// 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(
454454
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.
1148fn 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',