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 {
437437 .skip_non_native = skip_non_native,
438438 .skip_libc = skip_libc,
439439 .use_llvm = use_llvm,
440 // 2262585344 was observed on an x86_64-linux-gnu host.
441 .max_rss = 2488843878,
440 // 2520100864 was observed on an x86_64-linux-gnu host.
441 .max_rss = 2772110950,
442442 }));
443443
444444 test_modules_step.dependOn(tests.addModuleTests(b, .{
doc/langref/test_intCast_builtin.zig+1-1
......@@ -5,4 +5,4 @@ test "integer cast panic" {
55 _ = b;
66}
77
8// test_error=cast truncated bits
8// test_error=integer does not fit in destination type
lib/std/Target.zig+6-21
......@@ -1246,11 +1246,7 @@ pub const Cpu = struct {
12461246
12471247 /// Adds the specified feature set but not its dependencies.
12481248 pub fn addFeatureSet(set: *Set, other_set: Set) void {
1249 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) {
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 }
1249 set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints);
12541250 }
12551251
12561252 /// Removes the specified feature but not its dependents.
......@@ -1262,11 +1258,7 @@ pub const Cpu = struct {
12621258
12631259 /// Removes the specified feature but not its dependents.
12641260 pub fn removeFeatureSet(set: *Set, other_set: Set) void {
1265 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) {
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 }
1261 set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints);
12701262 }
12711263
12721264 pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void {
......@@ -1295,17 +1287,10 @@ pub const Cpu = struct {
12951287 }
12961288
12971289 pub fn isSuperSetOf(set: Set, other_set: Set) bool {
1298 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) {
1299 var result = true;
1300 for (&set.ints, other_set.ints) |*set_int, other_set_int|
1301 result = result and (set_int.* & other_set_int) == other_set_int;
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 }
1290 const V = @Vector(usize_count, usize);
1291 const set_v: V = set.ints;
1292 const other_v: V = other_set.ints;
1293 return @reduce(.And, (set_v & other_v) == other_v);
13091294 }
13101295 };
13111296
lib/std/array_hash_map.zig+4-13
......@@ -889,19 +889,10 @@ pub fn ArrayHashMapUnmanaged(
889889 self.pointer_stability.lock();
890890 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
904892 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
905896 const new_bit_index = try IndexHeader.findBitIndex(new_capacity);
906897 const new_header = try IndexHeader.alloc(gpa, new_bit_index);
907898
......@@ -2116,7 +2107,7 @@ const IndexHeader = struct {
21162107
21172108 fn findBitIndex(desired_capacity: usize) Allocator.Error!u8 {
21182109 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));
21202111 if (desired_capacity > index_capacities[new_bit_index]) new_bit_index += 1;
21212112 if (new_bit_index < min_bit_index) new_bit_index = min_bit_index;
21222113 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 {
499499fn ChaChaImpl(comptime rounds_nb: usize) type {
500500 switch (builtin.cpu.arch) {
501501 .x86_64 => {
502 const has_avx2 = std.Target.x86.featureSetHas(builtin.cpu.features, .avx2);
503 const has_avx512f = std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);
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);
502 if (builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f)) return ChaChaVecImpl(rounds_nb, 4);
503 if (std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return ChaChaVecImpl(rounds_nb, 2);
506504 return ChaChaVecImpl(rounds_nb, 1);
507505 },
508506 .aarch64 => {
509 const has_neon = std.Target.aarch64.featureSetHas(builtin.cpu.features, .neon);
510 if (has_neon) return ChaChaVecImpl(rounds_nb, 4);
507 if (builtin.zig_backend != .stage2_aarch64 and std.Target.aarch64.featureSetHas(builtin.cpu.features, .neon)) return ChaChaVecImpl(rounds_nb, 4);
511508 return ChaChaNonVecImpl(rounds_nb);
512509 },
513510 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 {
7878 @branchHint(.cold);
7979 call("invalid error code", @returnAddress());
8080 }
81 pub fn castTruncatedData() noreturn {
81 pub fn integerOutOfBounds() noreturn {
8282 @branchHint(.cold);
83 call("integer cast truncated bits", @returnAddress());
84 }
85 pub fn negativeToUnsigned() noreturn {
86 @branchHint(.cold);
87 call("attempt to cast negative value to unsigned integer", @returnAddress());
83 call("integer does not fit in destination type", @returnAddress());
8884 }
8985 pub fn integerOverflow() noreturn {
9086 @branchHint(.cold);
......@@ -126,8 +122,6 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type {
126122 @branchHint(.cold);
127123 call("for loop over objects with non-equal lengths", @returnAddress());
128124 }
129 /// Delete after next zig1.wasm update
130 pub const memcpyLenMismatch = copyLenMismatch;
131125 pub fn copyLenMismatch() noreturn {
132126 @branchHint(.cold);
133127 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 {
6565 @trap();
6666}
6767
68pub fn castTruncatedData() noreturn {
69 @branchHint(.cold);
70 @trap();
71}
72
73pub fn negativeToUnsigned() noreturn {
68pub fn integerOutOfBounds() noreturn {
7469 @branchHint(.cold);
7570 @trap();
7671}
......@@ -125,9 +120,6 @@ pub fn forLenMismatch() noreturn {
125120 @trap();
126121}
127122
128/// Delete after next zig1.wasm update
129pub const memcpyLenMismatch = copyLenMismatch;
130
131123pub fn copyLenMismatch() noreturn {
132124 @branchHint(.cold);
133125 @trap();
lib/std/debug/simple_panic.zig+2-9
......@@ -72,12 +72,8 @@ pub fn invalidErrorCode() noreturn {
7272 call("invalid error code", null);
7373}
7474
75pub fn castTruncatedData() noreturn {
76 call("integer cast truncated bits", null);
77}
78
79pub fn negativeToUnsigned() noreturn {
80 call("attempt to cast negative value to unsigned integer", null);
75pub fn integerOutOfBounds() noreturn {
76 call("integer does not fit in destination type", null);
8177}
8278
8379pub fn integerOverflow() noreturn {
......@@ -120,9 +116,6 @@ pub fn forLenMismatch() noreturn {
120116 call("for loop over objects with non-equal lengths", null);
121117}
122118
123/// Delete after next zig1.wasm update
124pub const memcpyLenMismatch = copyLenMismatch;
125
126119pub fn copyLenMismatch() noreturn {
127120 call("source and destination have non-equal lengths", null);
128121}
lib/std/hash/xxhash.zig-3
......@@ -780,7 +780,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64)
780780}
781781
782782test "xxhash3" {
783 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
784783 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
785784
786785 const H = XxHash3;
......@@ -814,7 +813,6 @@ test "xxhash3" {
814813}
815814
816815test "xxhash3 smhasher" {
817 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
818816 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
819817
820818 const Test = struct {
......@@ -828,7 +826,6 @@ test "xxhash3 smhasher" {
828826}
829827
830828test "xxhash3 iterative api" {
831 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
832829 if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807
833830
834831 const Test = struct {
lib/std/simd.zig-8
......@@ -231,8 +231,6 @@ pub fn extract(
231231}
232232
233233test "vector patterns" {
234 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
235
236234 const base = @Vector(4, u32){ 10, 20, 30, 40 };
237235 const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
238236
......@@ -302,8 +300,6 @@ pub fn reverseOrder(vec: anytype) @TypeOf(vec) {
302300}
303301
304302test "vector shifting" {
305 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
306
307303 const base = @Vector(4, u32){ 10, 20, 30, 40 };
308304
309305 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)))
368364}
369365
370366test "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
374367 const base = @Vector(8, u32){ 6, 4, 7, 4, 4, 2, 3, 7 };
375368
376369 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
462455}
463456
464457test "vector prefix scan" {
465 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
466458 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
467459 if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893
468460 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(
1119411194 const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32;
1119511195 const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32;
1119611196 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;
1119711198 const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32;
1119811199 switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) {
1119911200 as_ty | @intFromEnum(Zir.Inst.Ref.u1_type),
......@@ -11237,10 +11238,11 @@ fn rvalueInner(
1123711238 as_ty | @intFromEnum(Zir.Inst.Ref.null_type),
1123811239 as_ty | @intFromEnum(Zir.Inst.Ref.undefined_type),
1123911240 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),
1124011243 as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_u8_type),
1124111244 as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_type),
1124211245 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),
1124411246 as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_type),
1124511247 as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type),
1124611248 as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type),
......@@ -11249,27 +11251,45 @@ fn rvalueInner(
1124911251 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),
1125011252 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),
1125111253 as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one),
11254 as_usize | @intFromEnum(Zir.Inst.Ref.undef_usize),
1125211255 as_usize | @intFromEnum(Zir.Inst.Ref.zero_usize),
1125311256 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),
1125411260 as_u8 | @intFromEnum(Zir.Inst.Ref.zero_u8),
1125511261 as_u8 | @intFromEnum(Zir.Inst.Ref.one_u8),
1125611262 as_u8 | @intFromEnum(Zir.Inst.Ref.four_u8),
11263 as_bool | @intFromEnum(Zir.Inst.Ref.undef_bool),
1125711264 as_bool | @intFromEnum(Zir.Inst.Ref.bool_true),
1125811265 as_bool | @intFromEnum(Zir.Inst.Ref.bool_false),
1125911266 as_void | @intFromEnum(Zir.Inst.Ref.void_value),
1126011267 => 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
1126211274 as_usize | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_usize,
11275 as_u1 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u1,
1126311276 as_u8 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u8,
1126411277 as_usize | @intFromEnum(Zir.Inst.Ref.one) => return .one_usize,
11278 as_u1 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u1,
1126511279 as_u8 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u8,
1126611280 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero,
11281 as_u1 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u1,
1126711282 as_u8 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u8,
1126811283 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one,
11284 as_u1 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u1,
1126911285 as_u8 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u8,
11286 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u1) => return .zero,
1127011287 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero,
11288 as_usize | @intFromEnum(Zir.Inst.Ref.zero_u1) => return .zero_usize,
1127111289 as_usize | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero_usize,
11290 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u1) => return .one,
1127211291 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one,
11292 as_usize | @intFromEnum(Zir.Inst.Ref.one_u1) => return .one_usize,
1127311293 as_usize | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one_usize,
1127411294
1127511295 // Need an explicit type coercion instruction.
lib/std/zig/Zir.zig+8-2
......@@ -2142,7 +2142,7 @@ pub const Inst = struct {
21422142 ref_start_index = static_len,
21432143 _,
21442144
2145 pub const static_len = 118;
2145 pub const static_len = 124;
21462146
21472147 pub fn toRef(i: Index) Inst.Ref {
21482148 return @enumFromInt(@intFromEnum(Index.ref_start_index) + @intFromEnum(i));
......@@ -2220,10 +2220,11 @@ pub const Inst = struct {
22202220 null_type,
22212221 undefined_type,
22222222 enum_literal_type,
2223 ptr_usize_type,
2224 ptr_const_comptime_int_type,
22232225 manyptr_u8_type,
22242226 manyptr_const_u8_type,
22252227 manyptr_const_u8_sentinel_0_type,
2226 single_const_pointer_to_comptime_int_type,
22272228 slice_const_u8_type,
22282229 slice_const_u8_sentinel_0_type,
22292230 vector_8_i8_type,
......@@ -2279,11 +2280,16 @@ pub const Inst = struct {
22792280 generic_poison_type,
22802281 empty_tuple_type,
22812282 undef,
2283 undef_bool,
2284 undef_usize,
2285 undef_u1,
22822286 zero,
22832287 zero_usize,
2288 zero_u1,
22842289 zero_u8,
22852290 one,
22862291 one_usize,
2292 one_u1,
22872293 one_u8,
22882294 four_u8,
22892295 negative_one,
src/Air.zig+144-37
......@@ -50,8 +50,6 @@ pub const Inst = struct {
5050 /// is the same as both operands.
5151 /// The panic handler function must be populated before lowering AIR
5252 /// that contains this instruction.
53 /// This instruction will only be emitted if the backend has the
54 /// feature `safety_checked_instructions`.
5553 /// Uses the `bin_op` field.
5654 add_safe,
5755 /// Float addition. The instruction is allowed to have equal or more
......@@ -79,8 +77,6 @@ pub const Inst = struct {
7977 /// is the same as both operands.
8078 /// The panic handler function must be populated before lowering AIR
8179 /// that contains this instruction.
82 /// This instruction will only be emitted if the backend has the
83 /// feature `safety_checked_instructions`.
8480 /// Uses the `bin_op` field.
8581 sub_safe,
8682 /// Float subtraction. The instruction is allowed to have equal or more
......@@ -108,8 +104,6 @@ pub const Inst = struct {
108104 /// is the same as both operands.
109105 /// The panic handler function must be populated before lowering AIR
110106 /// that contains this instruction.
111 /// This instruction will only be emitted if the backend has the
112 /// feature `safety_checked_instructions`.
113107 /// Uses the `bin_op` field.
114108 mul_safe,
115109 /// Float multiplication. The instruction is allowed to have equal or more
......@@ -705,9 +699,21 @@ pub const Inst = struct {
705699 /// equal to the scalar value.
706700 /// Uses the `ty_op` field.
707701 splat,
708 /// Constructs a vector by selecting elements from `a` and `b` based on `mask`.
709 /// Uses the `ty_pl` field with payload `Shuffle`.
710 shuffle,
702 /// Constructs a vector by selecting elements from a single vector based on a mask. Each
703 /// mask element is either an index into the vector, or a comptime-known value, or "undef".
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,
711717 /// Constructs a vector element-wise from `a` or `b` based on `pred`.
712718 /// Uses the `pl_op` field with `pred` as operand, and payload `Bin`.
713719 select,
......@@ -1011,10 +1017,11 @@ pub const Inst = struct {
10111017 null_type = @intFromEnum(InternPool.Index.null_type),
10121018 undefined_type = @intFromEnum(InternPool.Index.undefined_type),
10131019 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),
10141022 manyptr_u8_type = @intFromEnum(InternPool.Index.manyptr_u8_type),
10151023 manyptr_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_u8_type),
10161024 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),
10181025 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
10191026 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
10201027 vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type),
......@@ -1070,11 +1077,16 @@ pub const Inst = struct {
10701077 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
10711078 empty_tuple_type = @intFromEnum(InternPool.Index.empty_tuple_type),
10721079 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),
10731083 zero = @intFromEnum(InternPool.Index.zero),
10741084 zero_usize = @intFromEnum(InternPool.Index.zero_usize),
1085 zero_u1 = @intFromEnum(InternPool.Index.zero_u1),
10751086 zero_u8 = @intFromEnum(InternPool.Index.zero_u8),
10761087 one = @intFromEnum(InternPool.Index.one),
10771088 one_usize = @intFromEnum(InternPool.Index.one_usize),
1089 one_u1 = @intFromEnum(InternPool.Index.one_u1),
10781090 one_u8 = @intFromEnum(InternPool.Index.one_u8),
10791091 four_u8 = @intFromEnum(InternPool.Index.four_u8),
10801092 negative_one = @intFromEnum(InternPool.Index.negative_one),
......@@ -1121,7 +1133,7 @@ pub const Inst = struct {
11211133 }
11221134
11231135 pub fn toType(ref: Ref) Type {
1124 return Type.fromInterned(ref.toInterned().?);
1136 return .fromInterned(ref.toInterned().?);
11251137 }
11261138 };
11271139
......@@ -1241,10 +1253,10 @@ pub const CondBr = struct {
12411253 else_body_len: u32,
12421254 branch_hints: BranchHints,
12431255 pub const BranchHints = packed struct(u32) {
1244 true: std.builtin.BranchHint,
1245 false: std.builtin.BranchHint,
1246 then_cov: CoveragePoint,
1247 else_cov: CoveragePoint,
1256 true: std.builtin.BranchHint = .none,
1257 false: std.builtin.BranchHint = .none,
1258 then_cov: CoveragePoint = .none,
1259 else_cov: CoveragePoint = .none,
12481260 _: u24 = 0,
12491261 };
12501262};
......@@ -1299,13 +1311,6 @@ pub const FieldParentPtr = struct {
12991311 field_index: u32,
13001312};
13011313
1302pub const Shuffle = struct {
1303 a: Inst.Ref,
1304 b: Inst.Ref,
1305 mask: InternPool.Index,
1306 mask_len: u32,
1307};
1308
13091314pub const VectorCmp = struct {
13101315 lhs: Inst.Ref,
13111316 rhs: Inst.Ref,
......@@ -1320,6 +1325,64 @@ pub const VectorCmp = struct {
13201325 }
13211326};
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
13231386/// Trailing:
13241387/// 0. `Inst.Ref` for every outputs_len
13251388/// 1. `Inst.Ref` for every inputs_len
......@@ -1393,7 +1456,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
13931456
13941457pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {
13951458 if (inst.toInterned()) |ip_index| {
1396 return Type.fromInterned(ip.typeOf(ip_index));
1459 return .fromInterned(ip.typeOf(ip_index));
13971460 } else {
13981461 return air.typeOfIndex(inst.toIndex().?, ip);
13991462 }
......@@ -1483,7 +1546,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
14831546 .is_non_err_ptr,
14841547 .is_named_enum_value,
14851548 .error_set_has_value,
1486 => return Type.bool,
1549 => return .bool,
14871550
14881551 .alloc,
14891552 .ret_ptr,
......@@ -1503,7 +1566,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
15031566 .cmpxchg_weak,
15041567 .cmpxchg_strong,
15051568 .slice,
1506 .shuffle,
15071569 .aggregate_init,
15081570 .union_init,
15091571 .field_parent_ptr,
......@@ -1517,6 +1579,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
15171579 .ptr_sub,
15181580 .try_ptr,
15191581 .try_ptr_cold,
1582 .shuffle_one,
1583 .shuffle_two,
15201584 => return datas[@intFromEnum(inst)].ty_pl.ty.toType(),
15211585
15221586 .not,
......@@ -1574,7 +1638,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
15741638 .ret_load,
15751639 .unreach,
15761640 .trap,
1577 => return Type.noreturn,
1641 => return .noreturn,
15781642
15791643 .breakpoint,
15801644 .dbg_stmt,
......@@ -1597,22 +1661,22 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
15971661 .set_err_return_trace,
15981662 .vector_store_elem,
15991663 .c_va_end,
1600 => return Type.void,
1664 => return .void,
16011665
16021666 .slice_len,
16031667 .ret_addr,
16041668 .frame_addr,
16051669 .save_err_return_trace_index,
1606 => return Type.usize,
1670 => return .usize,
16071671
1608 .wasm_memory_grow => return Type.isize,
1609 .wasm_memory_size => return Type.usize,
1672 .wasm_memory_grow => return .isize,
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
16131677 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
16141678 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()));
16161680 },
16171681
16181682 .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)
16301694
16311695 .reduce, .reduce_optimized => {
16321696 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);
16341698 },
16351699
16361700 .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)
16411705
16421706 .@"try", .try_cold => {
16431707 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);
16451709 },
16461710
16471711 .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)
16491713 .work_item_id,
16501714 .work_group_size,
16511715 .work_group_id,
1652 => return Type.u32,
1716 => return .u32,
16531717
16541718 .inferred_alloc => unreachable,
16551719 .inferred_alloc_comptime => unreachable,
......@@ -1696,7 +1760,7 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {
16961760/// Returns `null` if runtime-known.
16971761pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {
16981762 if (inst.toInterned()) |ip_index| {
1699 return Value.fromInterned(ip_index);
1763 return .fromInterned(ip_index);
17001764 }
17011765 const index = inst.toIndex().?;
17021766 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 {
19031967 .reduce,
19041968 .reduce_optimized,
19051969 .splat,
1906 .shuffle,
1970 .shuffle_one,
1971 .shuffle_two,
19071972 .select,
19081973 .is_named_enum_value,
19091974 .tag_name,
......@@ -2030,6 +2095,48 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch {
20302095 };
20312096}
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
20332140pub const typesFullyResolved = types_resolved.typesFullyResolved;
20342141pub const typeFullyResolved = types_resolved.checkType;
20352142pub const valFullyResolved = types_resolved.checkVal;
src/Air/Legalize.zig+1710-120
......@@ -1,147 +1,1737 @@
1zcu: *const Zcu,
2air: Air,
3features: std.enums.EnumSet(Feature),
1pt: Zcu.PerThread,
2air_instructions: std.MultiArrayList(Air.Inst),
3air_extra: std.ArrayListUnmanaged(u32),
4features: *const Features,
45
56pub 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
686 /// Legalize (shift lhs, (splat rhs)) -> (shift lhs, rhs)
7 remove_shift_vector_rhs_splat,
87 unsplat_shift_rhs,
888 /// Legalize reduce of a one element vector to a bitcast
989 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 }
10187};
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
15196 var l: Legalize = .{
16 .zcu = zcu,
17 .air = air.*,
18 .features = features: switch (backend) {
19 .other, .stage1 => unreachable,
20 inline .stage2_llvm,
21 .stage2_c,
22 .stage2_wasm,
23 .stage2_arm,
24 .stage2_x86_64,
25 .stage2_aarch64,
26 .stage2_x86,
27 .stage2_riscv64,
28 .stage2_sparc64,
29 .stage2_spirv64,
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 },
197 .pt = pt,
198 .air_instructions = air.instructions.toMultiArrayList(),
199 .air_extra = air.extra,
200 .features = features,
201 };
202 defer air.* = l.getTmpAir();
203 const main_extra = l.extraData(Air.Block, l.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)]);
204 try l.legalizeBody(main_extra.end, main_extra.data.body_len);
205}
206
207fn getTmpAir(l: *const Legalize) Air {
208 return .{
209 .instructions = l.air_instructions.slice(),
210 .extra = l.air_extra,
40211 };
41 defer air.* = l.air;
42 if (!l.features.bits.eql(.initEmpty())) try l.legalizeBody(l.air.getMainBody());
43212}
44213
45fn legalizeBody(l: *Legalize, body: []const Air.Inst.Index) std.mem.Allocator.Error!void {
46 const zcu = l.zcu;
214fn typeOf(l: *const Legalize, ref: Air.Inst.Ref) Type {
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;
47228 const ip = &zcu.intern_pool;
48 const tags = l.air.instructions.items(.tag);
49 const data = l.air.instructions.items(.data);
50 for (body) |inst| inst: switch (tags[@intFromEnum(inst)]) {
51 else => {},
52
53 .shl,
54 .shl_exact,
55 .shl_sat,
56 .shr,
57 .shr_exact,
58 => |air_tag| if (l.features.contains(.remove_shift_vector_rhs_splat)) done: {
59 const bin_op = data[@intFromEnum(inst)].bin_op;
60 const ty = l.air.typeOf(bin_op.rhs, ip);
61 if (!ty.isVector(zcu)) break :done;
62 if (bin_op.rhs.toInterned()) |rhs_ip_index| switch (ip.indexToKey(rhs_ip_index)) {
63 else => {},
64 .aggregate => |aggregate| switch (aggregate.storage) {
65 else => {},
66 .repeated_elem => |splat| continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{
67 .lhs = bin_op.lhs,
68 .rhs = Air.internedToRef(splat),
69 } }),
70 },
71 } else {
72 const rhs_inst = bin_op.rhs.toIndex().?;
73 switch (tags[@intFromEnum(rhs_inst)]) {
74 else => {},
75 .splat => continue :inst l.replaceInst(inst, air_tag, .{ .bin_op = .{
76 .lhs = bin_op.lhs,
77 .rhs = data[@intFromEnum(rhs_inst)].ty_op.operand,
229 for (0..body_len) |body_index| {
230 const inst: Air.Inst.Index = @enumFromInt(l.air_extra.items[body_start + body_index]);
231 inst: switch (l.air_instructions.items(.tag)[@intFromEnum(inst)]) {
232 .arg,
233 => {},
234 inline .add,
235 .add_optimized,
236 .add_wrap,
237 .add_sat,
238 .sub,
239 .sub_optimized,
240 .sub_wrap,
241 .sub_sat,
242 .mul,
243 .mul_optimized,
244 .mul_wrap,
245 .mul_sat,
246 .div_float,
247 .div_float_optimized,
248 .div_trunc,
249 .div_trunc_optimized,
250 .div_floor,
251 .div_floor_optimized,
252 .div_exact,
253 .div_exact_optimized,
254 .rem,
255 .rem_optimized,
256 .mod,
257 .mod_optimized,
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,
78536 } }),
537 else => break :done,
79538 }
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 });
801035 }
81 },
82
83 .reduce,
84 .reduce_optimized,
85 => if (l.features.contains(.reduce_one_elem_to_bitcast)) done: {
86 const reduce = data[@intFromEnum(inst)].reduce;
87 const vector_ty = l.air.typeOf(reduce.operand, ip);
88 switch (vector_ty.vectorLen(zcu)) {
89 0 => unreachable,
90 1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{
91 .ty = Air.internedToRef(vector_ty.scalarType(zcu).toIntern()),
92 .operand = reduce.operand,
93 } }),
94 else => break :done,
1036 loop_cond_br.else_block = .init(loop_cond_br.then_block.stealRemainingCapacity());
1037 _ = loop_cond_br.else_block.add(l, .{
1038 .tag = .br,
1039 .data = .{ .br = .{
1040 .block_inst = orig_inst,
1041 .operand = loop_cond_br.else_block.add(l, .{
1042 .tag = .load,
1043 .data = .{ .ty_op = .{
1044 .ty = Air.internedToRef(res_ty.toIntern()),
1045 .operand = res_alloc_inst.toRef(),
1046 } },
1047 }).toRef(),
1048 } },
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 });
951205 }
96 },
97
98 .@"try", .try_cold => {
99 const pl_op = data[@intFromEnum(inst)].pl_op;
100 const extra = l.air.extraData(Air.Try, pl_op.payload);
101 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len]));
102 },
103 .try_ptr, .try_ptr_cold => {
104 const ty_pl = data[@intFromEnum(inst)].ty_pl;
105 const extra = l.air.extraData(Air.TryPtr, ty_pl.payload);
106 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len]));
107 },
108 .block, .loop => {
109 const ty_pl = data[@intFromEnum(inst)].ty_pl;
110 const extra = l.air.extraData(Air.Block, ty_pl.payload);
111 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len]));
112 },
113 .dbg_inline_block => {
114 const ty_pl = data[@intFromEnum(inst)].ty_pl;
115 const extra = l.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
116 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.body_len]));
117 },
118 .cond_br => {
119 const pl_op = data[@intFromEnum(inst)].pl_op;
120 const extra = l.air.extraData(Air.CondBr, pl_op.payload);
121 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end..][0..extra.data.then_body_len]));
122 try l.legalizeBody(@ptrCast(l.air.extra.items[extra.end + extra.data.then_body_len ..][0..extra.data.else_body_len]));
123 },
124 .switch_br, .loop_switch_br => {
125 const switch_br = l.air.unwrapSwitch(inst);
126 var it = switch_br.iterateCases();
127 while (it.next()) |case| try l.legalizeBody(case.body);
128 try l.legalizeBody(it.elseBody());
129 },
1206 loop_cond_br.else_block = .init(loop_cond_br.then_block.stealRemainingCapacity());
1207 _ = loop_cond_br.else_block.add(l, .{
1208 .tag = .br,
1209 .data = .{ .br = .{
1210 .block_inst = orig_inst,
1211 .operand = loop_cond_br.else_block.add(l, .{
1212 .tag = .load,
1213 .data = .{ .ty_op = .{
1214 .ty = Air.internedToRef(res_ty.toIntern()),
1215 .operand = res_alloc_inst.toRef(),
1216 } },
1217 }).toRef(),
1218 } },
1219 });
1220 try loop_cond_br.finish(l);
1221 }
1222 try loop.finish(l);
1223 }
1224 return .{ .ty_pl = .{
1225 .ty = Air.internedToRef(res_ty.toIntern()),
1226 .payload = try l.addBlockBody(res_block.body()),
1227 } };
1228}
1229
1230fn safeIntcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data {
1231 const pt = l.pt;
1232 const zcu = pt.zcu;
1233 const ty_op = l.air_instructions.items(.data)[@intFromEnum(orig_inst)].ty_op;
1234
1235 const operand_ref = ty_op.operand;
1236 const operand_ty = l.typeOf(operand_ref);
1237 const dest_ty = ty_op.ty.toType();
1238
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 };
1301262 };
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);
1311719}
1321720
133// inline to propagate comptime `tag`s
134inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag {
135 const ip = &l.zcu.intern_pool;
136 const orig_ty = if (std.debug.runtime_safety) l.air.typeOfIndex(inst, ip) else {};
137 l.air.instructions.items(.tag)[@intFromEnum(inst)] = tag;
138 l.air.instructions.items(.data)[@intFromEnum(inst)] = data;
139 if (std.debug.runtime_safety) std.debug.assert(l.air.typeOfIndex(inst, ip).toIntern() == orig_ty.toIntern());
1721/// Returns `tag` to remind the caller to `continue :inst` the result.
1722/// This is inline to propagate the comptime-known `tag`.
1723inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, comptime tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag {
1724 const orig_ty = if (std.debug.runtime_safety) l.typeOfIndex(inst) else {};
1725 l.air_instructions.set(@intFromEnum(inst), .{ .tag = tag, .data = data });
1726 if (std.debug.runtime_safety) assert(l.typeOfIndex(inst).toIntern() == orig_ty.toIntern());
1401727 return tag;
1411728}
1421729
1431730const Air = @import("../Air.zig");
144const codegen = @import("../codegen.zig");
1731const assert = std.debug.assert;
1732const dev = @import("../dev.zig");
1733const InternPool = @import("../InternPool.zig");
1451734const Legalize = @This();
1461735const std = @import("std");
1736const Type = @import("../Type.zig");
1471737const Zcu = @import("../Zcu.zig");
src/Air/Liveness.zig+24-9
......@@ -15,6 +15,7 @@ const Liveness = @This();
1515const trace = @import("../tracy.zig").trace;
1616const Air = @import("../Air.zig");
1717const InternPool = @import("../InternPool.zig");
18const Zcu = @import("../Zcu.zig");
1819
1920pub const Verify = @import("Liveness/Verify.zig");
2021
......@@ -136,12 +137,15 @@ fn LivenessPassData(comptime pass: LivenessPass) type {
136137 };
137138}
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 {
140141 const tracy = trace(@src());
141142 defer tracy.end();
142143
144 const gpa = zcu.gpa;
145
143146 var a: Analysis = .{
144147 .gpa = gpa,
148 .zcu = zcu,
145149 .air = air,
146150 .tomb_bits = try gpa.alloc(
147151 usize,
......@@ -220,6 +224,7 @@ const OperandCategory = enum {
220224pub fn categorizeOperand(
221225 l: Liveness,
222226 air: Air,
227 zcu: *Zcu,
223228 inst: Air.Inst.Index,
224229 operand: Air.Inst.Index,
225230 ip: *const InternPool,
......@@ -511,10 +516,15 @@ pub fn categorizeOperand(
511516 if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .none);
512517 return .none;
513518 },
514 .shuffle => {
515 const extra = air.extraData(Air.Shuffle, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
516 if (extra.a == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
517 if (extra.b == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
519 .shuffle_one => {
520 const unwrapped = air.unwrapShuffleOne(zcu, inst);
521 if (unwrapped.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .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);
518528 return .none;
519529 },
520530 .reduce, .reduce_optimized => {
......@@ -639,7 +649,7 @@ pub fn categorizeOperand(
639649
640650 var operand_live: bool = true;
641651 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)
643653 operand_live = false;
644654
645655 switch (air_tags[@intFromEnum(cond_inst)]) {
......@@ -824,6 +834,7 @@ pub const BigTomb = struct {
824834/// In-progress data; on successful analysis converted into `Liveness`.
825835const Analysis = struct {
826836 gpa: Allocator,
837 zcu: *Zcu,
827838 air: Air,
828839 intern_pool: *InternPool,
829840 tomb_bits: []usize,
......@@ -1119,9 +1130,13 @@ fn analyzeInst(
11191130 const extra = a.air.extraData(Air.Bin, pl_op.payload).data;
11201131 return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.lhs, extra.rhs });
11211132 },
1122 .shuffle => {
1123 const extra = a.air.extraData(Air.Shuffle, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
1124 return analyzeOperands(a, pass, data, inst, .{ extra.a, extra.b, .none });
1133 .shuffle_one => {
1134 const unwrapped = a.air.unwrapShuffleOne(a.zcu, inst);
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 });
11251140 },
11261141 .reduce, .reduce_optimized => {
11271142 const reduce = inst_datas[@intFromEnum(inst)].reduce;
src/Air/Liveness/Verify.zig+9-4
......@@ -1,6 +1,7 @@
11//! Verifies that Liveness information is valid.
22
33gpa: std.mem.Allocator,
4zcu: *Zcu,
45air: Air,
56liveness: Liveness,
67live: LiveMap = .{},
......@@ -287,10 +288,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
287288 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
288289 try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
289290 },
290 .shuffle => {
291 const ty_pl = data[@intFromEnum(inst)].ty_pl;
292 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
293 try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none });
291 .shuffle_one => {
292 const unwrapped = self.air.unwrapShuffleOne(self.zcu, inst);
293 try self.verifyInstOperands(inst, .{ unwrapped.operand, .none, .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 });
294298 },
295299 .cmp_vector,
296300 .cmp_vector_optimized,
......@@ -639,4 +643,5 @@ const log = std.log.scoped(.liveness_verify);
639643const Air = @import("../../Air.zig");
640644const Liveness = @import("../Liveness.zig");
641645const InternPool = @import("../../InternPool.zig");
646const Zcu = @import("../../Zcu.zig");
642647const 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 {
249249 if (!checkRef(extra.struct_operand, zcu)) return false;
250250 },
251251
252 .shuffle => {
253 const extra = air.extraData(Air.Shuffle, data.ty_pl.payload).data;
254 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
255 if (!checkRef(extra.a, zcu)) return false;
256 if (!checkRef(extra.b, zcu)) return false;
257 if (!checkVal(Value.fromInterned(extra.mask), zcu)) return false;
252 .shuffle_one => {
253 const unwrapped = air.unwrapShuffleOne(zcu, inst);
254 if (!checkType(unwrapped.result_ty, zcu)) return false;
255 if (!checkRef(unwrapped.operand, zcu)) return false;
256 for (unwrapped.mask) |m| switch (m.unwrap()) {
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
258268 },
259269
260270 .cmpxchg_weak,
src/Compilation.zig+1-1
......@@ -2529,6 +2529,7 @@ pub fn destroy(comp: *Compilation) void {
25292529
25302530pub fn clearMiscFailures(comp: *Compilation) void {
25312531 comp.alloc_failure_occurred = false;
2532 comp.link_diags.flags = .{};
25322533 for (comp.misc_failures.values()) |*value| {
25332534 value.deinit(comp.gpa);
25342535 }
......@@ -2795,7 +2796,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
27952796
27962797 if (anyErrors(comp)) {
27972798 // Skip flushing and keep source files loaded for error reporting.
2798 comp.link_diags.flags = .{};
27992799 return;
28002800 }
28012801
src/InternPool.zig+60-24
......@@ -4579,10 +4579,11 @@ pub const Index = enum(u32) {
45794579 undefined_type,
45804580 enum_literal_type,
45814581
4582 ptr_usize_type,
4583 ptr_const_comptime_int_type,
45824584 manyptr_u8_type,
45834585 manyptr_const_u8_type,
45844586 manyptr_const_u8_sentinel_0_type,
4585 single_const_pointer_to_comptime_int_type,
45864587 slice_const_u8_type,
45874588 slice_const_u8_sentinel_0_type,
45884589
......@@ -4649,19 +4650,29 @@ pub const Index = enum(u32) {
46494650
46504651 /// `undefined` (untyped)
46514652 undef,
4653 /// `@as(bool, undefined)`
4654 undef_bool,
4655 /// `@as(usize, undefined)`
4656 undef_usize,
4657 /// `@as(u1, undefined)`
4658 undef_u1,
46524659 /// `0` (comptime_int)
46534660 zero,
4654 /// `0` (usize)
4661 /// `@as(usize, 0)`
46554662 zero_usize,
4656 /// `0` (u8)
4663 /// `@as(u1, 0)`
4664 zero_u1,
4665 /// `@as(u8, 0)`
46574666 zero_u8,
46584667 /// `1` (comptime_int)
46594668 one,
4660 /// `1` (usize)
4669 /// `@as(usize, 1)`
46614670 one_usize,
4662 /// `1` (u8)
4671 /// `@as(u1, 1)`
4672 one_u1,
4673 /// `@as(u8, 1)`
46634674 one_u8,
4664 /// `4` (u8)
4675 /// `@as(u8, 4)`
46654676 four_u8,
46664677 /// `-1` (comptime_int)
46674678 negative_one,
......@@ -5074,6 +5085,20 @@ pub const static_keys: [static_len]Key = .{
50745085 .{ .simple_type = .undefined },
50755086 .{ .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
50775102 // [*]u8
50785103 .{ .ptr_type = .{
50795104 .child = .u8_type,
......@@ -5101,15 +5126,6 @@ pub const static_keys: [static_len]Key = .{
51015126 },
51025127 } },
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
51135129 // []const u8
51145130 .{ .ptr_type = .{
51155131 .child = .u8_type,
......@@ -5245,6 +5261,9 @@ pub const static_keys: [static_len]Key = .{
52455261 } },
52465262
52475263 .{ .simple_value = .undefined },
5264 .{ .undef = .bool_type },
5265 .{ .undef = .usize_type },
5266 .{ .undef = .u1_type },
52485267
52495268 .{ .int = .{
52505269 .ty = .comptime_int_type,
......@@ -5256,6 +5275,11 @@ pub const static_keys: [static_len]Key = .{
52565275 .storage = .{ .u64 = 0 },
52575276 } },
52585277
5278 .{ .int = .{
5279 .ty = .u1_type,
5280 .storage = .{ .u64 = 0 },
5281 } },
5282
52595283 .{ .int = .{
52605284 .ty = .u8_type,
52615285 .storage = .{ .u64 = 0 },
......@@ -5271,17 +5295,21 @@ pub const static_keys: [static_len]Key = .{
52715295 .storage = .{ .u64 = 1 },
52725296 } },
52735297
5274 // one_u8
5298 .{ .int = .{
5299 .ty = .u1_type,
5300 .storage = .{ .u64 = 1 },
5301 } },
5302
52755303 .{ .int = .{
52765304 .ty = .u8_type,
52775305 .storage = .{ .u64 = 1 },
52785306 } },
5279 // four_u8
5307
52805308 .{ .int = .{
52815309 .ty = .u8_type,
52825310 .storage = .{ .u64 = 4 },
52835311 } },
5284 // negative_one
5312
52855313 .{ .int = .{
52865314 .ty = .comptime_int_type,
52875315 .storage = .{ .i64 = -1 },
......@@ -10482,7 +10510,7 @@ pub fn getCoerced(
1048210510 .base_addr = .int,
1048310511 .byte_offset = 0,
1048410512 } }),
10485 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
10513 .len = .undef_usize,
1048610514 } }),
1048710515 };
1048810516 },
......@@ -10601,7 +10629,7 @@ pub fn getCoerced(
1060110629 .base_addr = .int,
1060210630 .byte_offset = 0,
1060310631 } }),
10604 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
10632 .len = .undef_usize,
1060510633 } }),
1060610634 },
1060710635 else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty),
......@@ -11847,10 +11875,11 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1184711875 .null_type,
1184811876 .undefined_type,
1184911877 .enum_literal_type,
11878 .ptr_usize_type,
11879 .ptr_const_comptime_int_type,
1185011880 .manyptr_u8_type,
1185111881 .manyptr_const_u8_type,
1185211882 .manyptr_const_u8_sentinel_0_type,
11853 .single_const_pointer_to_comptime_int_type,
1185411883 .slice_const_u8_type,
1185511884 .slice_const_u8_sentinel_0_type,
1185611885 .vector_8_i8_type,
......@@ -11909,12 +11938,13 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1190911938
1191011939 .undef => .undefined_type,
1191111940 .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,
1191311943 .zero_u8, .one_u8, .four_u8 => .u8_type,
1191411944 .void_value => .void_type,
1191511945 .unreachable_value => .noreturn_type,
1191611946 .null_value => .null_type,
11917 .bool_true, .bool_false => .bool_type,
11947 .undef_bool, .bool_true, .bool_false => .bool_type,
1191811948 .empty_tuple => .empty_tuple_type,
1191911949
1192011950 // 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 {
1218612216 .undefined_type => .undefined,
1218712217 .enum_literal_type => .enum_literal,
1218812218
12219 .ptr_usize_type,
12220 .ptr_const_comptime_int_type,
1218912221 .manyptr_u8_type,
1219012222 .manyptr_const_u8_type,
1219112223 .manyptr_const_u8_sentinel_0_type,
12192 .single_const_pointer_to_comptime_int_type,
1219312224 .slice_const_u8_type,
1219412225 .slice_const_u8_sentinel_0_type,
1219512226 => .pointer,
......@@ -12251,11 +12282,16 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1225112282
1225212283 // values, not types
1225312284 .undef => unreachable,
12285 .undef_bool => unreachable,
12286 .undef_usize => unreachable,
12287 .undef_u1 => unreachable,
1225412288 .zero => unreachable,
1225512289 .zero_usize => unreachable,
12290 .zero_u1 => unreachable,
1225612291 .zero_u8 => unreachable,
1225712292 .one => unreachable,
1225812293 .one_usize => unreachable,
12294 .one_u1 => unreachable,
1225912295 .one_u8 => unreachable,
1226012296 .four_u8 => unreachable,
1226112297 .negative_one => unreachable,
src/Sema.zig+553-795
......@@ -1881,7 +1881,7 @@ fn analyzeBodyInner(
18811881 extra.data.else_body_len,
18821882 );
18831883 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);
18851885 const cond_val = try sema.resolveConstDefinedValue(
18861886 block,
18871887 cond_src,
......@@ -2012,7 +2012,7 @@ fn resolveConstBool(
20122012 reason: ComptimeReason,
20132013) !bool {
20142014 const air_inst = try sema.resolveInst(zir_ref);
2015 const wanted_type = Type.bool;
2015 const wanted_type: Type = .bool;
20162016 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
20172017 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
20182018 return val.toBool();
......@@ -2037,7 +2037,7 @@ pub fn toConstString(
20372037 reason: ComptimeReason,
20382038) ![]u8 {
20392039 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);
20412041 const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
20422042 const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
20432043 return arr_val.toAllocatedBytes(arr_val.typeOf(pt.zcu), sema.arena, pt);
......@@ -2051,7 +2051,7 @@ pub fn resolveConstStringIntern(
20512051 reason: ComptimeReason,
20522052) !InternPool.NullTerminatedString {
20532053 const air_inst = try sema.resolveInst(zir_ref);
2054 const wanted_type = Type.slice_const_u8;
2054 const wanted_type: Type = .slice_const_u8;
20552055 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
20562056 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
20572057 return sema.sliceToIpString(block, src, val, reason);
......@@ -2180,7 +2180,7 @@ fn analyzeAsType(
21802180 src: LazySrcLoc,
21812181 air_inst: Air.Inst.Ref,
21822182) !Type {
2183 const wanted_type = Type.type;
2183 const wanted_type: Type = .type;
21842184 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
21852185 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, .{ .simple = .type });
21862186 return val.toType();
......@@ -2641,7 +2641,7 @@ fn reparentOwnedErrorMsg(
26412641 msg.msg = msg_str;
26422642}
26432643
2644const align_ty = Type.u29;
2644const align_ty: Type = .u29;
26452645
26462646pub fn analyzeAsAlign(
26472647 sema: *Sema,
......@@ -2819,7 +2819,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
28192819 const pt = sema.pt;
28202820 const zcu = pt.zcu;
28212821 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);
28232823 const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu);
28242824
28252825 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
37773777 const alloc = try sema.resolveInst(inst_data.operand);
37783778 const alloc_ty = sema.typeOf(alloc);
37793779 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
37823782 // If the alloc was created in a comptime scope, we already created a comptime alloc for it.
37833783 // 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,
38483848
38493849 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);
38503850 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
38533853 const alloc_inst = alloc.toIndex() orelse return null;
38543854 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,
40244024 // As this is a union field, we must store to the pointer now to set the tag.
40254025 // If the payload is OPV, there will not be a payload store, so we store that value.
40264026 // 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]);
40284028 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);
40304030 const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val);
40314031 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
40324032 }
......@@ -4050,7 +4050,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
40504050 const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;
40514051 const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?;
40524052 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())));
40544054 },
40554055 else => unreachable,
40564056 }
......@@ -4284,7 +4284,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42844284 else => unreachable,
42854285 };
42864286 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));
42884288 if (try ty.fnHasRuntimeBitsSema(pt)) {
42894289 try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = val }));
42904290 try zcu.ensureFuncBodyAnalysisQueued(val);
......@@ -4447,14 +4447,14 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
44474447 const range_end = try sema.resolveInst(zir_arg_pair[1]);
44484448 break :l try sema.analyzeArithmetic(block, .sub, range_end, range_start, arg_src, arg_src, arg_src, true);
44494449 };
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);
44514451 if (len == .none) {
44524452 len = arg_len;
44534453 len_idx = i;
44544454 }
44554455 if (try sema.resolveDefinedValue(block, src, arg_len)) |arg_val| {
44564456 if (len_val) |v| {
4457 if (!(try sema.valuesEqual(arg_val, v, Type.usize))) {
4457 if (!(try sema.valuesEqual(arg_val, v, .usize))) {
44584458 const msg = msg: {
44594459 const msg = try sema.errMsg(src, "non-matching for loop lengths", .{});
44604460 errdefer msg.destroy(gpa);
......@@ -5343,7 +5343,7 @@ fn zirValidatePtrArrayInit(
53435343 // sentinel-terminated array, the sentinel will not have been populated by
53445344 // any ZIR instructions at comptime; we need to do that here.
53455345 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);
53475347 const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true);
53485348 const sentinel = Air.internedToRef(sentinel_val.toIntern());
53495349 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
58285828 defer tracy.end();
58295829
58305830 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);
58325832}
58335833
58345834fn 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.
58465846 const limbs = try sema.arena.alloc(std.math.big.Limb, int.len);
58475847 @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, .{
58505850 .limbs = limbs,
58515851 .positive = true,
58525852 })).toIntern());
......@@ -5856,7 +5856,7 @@ fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
58565856 _ = block;
58575857 const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float;
58585858 return Air.internedToRef((try sema.pt.floatValue(
5859 Type.comptime_float,
5859 .comptime_float,
58605860 number,
58615861 )).toIntern());
58625862}
......@@ -5866,7 +5866,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
58665866 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
58675867 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
58685868 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());
58705870}
58715871
58725872fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -6641,7 +6641,7 @@ pub fn analyzeExport(
66416641 };
66426642
66436643 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
66466646 if (!try sema.validateExternType(export_ty, .other)) {
66476647 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -7005,7 +7005,7 @@ fn lookupInNamespace(
70057005
70067006 for (usingnamespaces.items) |sub_ns_nav| {
70077007 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);
70097009 const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu));
70107010 try checked_namespaces.put(gpa, sub_ns, {});
70117011 }
......@@ -7081,7 +7081,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
70817081 const gpa = sema.gpa;
70827082
70837083 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);
70857085 return Air.internedToRef(index_val.toIntern());
70867086 }
70877087
......@@ -7326,13 +7326,13 @@ fn checkCallArgumentCount(
73267326) !Type {
73277327 const pt = sema.pt;
73287328 const zcu = pt.zcu;
7329 const func_ty = func_ty: {
7329 const func_ty: Type = func_ty: {
73307330 switch (callee_ty.zigTypeTag(zcu)) {
73317331 .@"fn" => break :func_ty callee_ty,
73327332 .pointer => {
73337333 const ptr_info = callee_ty.ptrInfo(zcu);
73347334 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);
73367336 }
73377337 },
73387338 .optional => {
......@@ -7405,13 +7405,13 @@ fn callBuiltin(
74057405 const pt = sema.pt;
74067406 const zcu = pt.zcu;
74077407 const callee_ty = sema.typeOf(builtin_fn);
7408 const func_ty = func_ty: {
7408 const func_ty: Type = func_ty: {
74097409 switch (callee_ty.zigTypeTag(zcu)) {
74107410 .@"fn" => break :func_ty callee_ty,
74117411 .pointer => {
74127412 const ptr_info = callee_ty.ptrInfo(zcu);
74137413 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);
74157415 }
74167416 },
74177417 else => {},
......@@ -7568,7 +7568,7 @@ const CallArgsInfo = union(enum) {
75687568 }
75697569 }
75707570 // 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;
75727572 sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(provide_param_ty.toIntern()));
75737573 // Resolve the arg!
75747574 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
83538353 @tagName(backend), @tagName(target.cpu.arch),
83548354 });
83558355 }
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);
83578357 if (owner_func_ty.toIntern() != func_ty.toIntern()) {
83588358 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
83598359 func_ty.fmt(pt), owner_func_ty.fmt(pt),
......@@ -8452,7 +8452,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
84528452 const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);
84538453 const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);
84548454 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 }));
84568456 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
84578457 try sema.checkVectorElemType(block, elem_type_src, elem_type);
84588458 const vector_type = try sema.pt.vectorType(.{
......@@ -8470,7 +8470,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
84708470 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
84718471 const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node });
84728472 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 });
84748474 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
84758475 try sema.validateArrayElemType(block, elem_type, elem_src);
84768476 const array_ty = try sema.pt.arrayType(.{
......@@ -8490,7 +8490,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
84908490 const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node });
84918491 const sentinel_src = block.src(.{ .node_offset_array_type_sentinel = inst_data.src_node });
84928492 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 });
84948494 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);
84958495 try sema.validateArrayElemType(block, elem_type, elem_src);
84968496 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
......@@ -8599,7 +8599,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
85998599 const src = block.nodeOffset(extra.node);
86008600 const operand_src = block.builtinCallArgSrc(extra.node, 0);
86018601 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);
86038603 const err_int_ty = try pt.errorIntType();
86048604
86058605 if (try sema.resolveValue(operand)) |val| {
......@@ -8912,21 +8912,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89128912
89138913 try sema.requireRuntimeBlock(block, src, operand_src);
89148914 if (block.wantSafety()) {
8915 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {
8915 if (zcu.backendSupportsFeature(.panic_fn)) {
89168916 _ = 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;
89298917 }
8918 return block.addTyOp(.intcast_safe, dest_ty, operand);
89308919 }
89318920 return block.addTyOp(.intcast, dest_ty, operand);
89328921}
......@@ -9309,7 +9298,7 @@ fn zirFunc(
93099298 const ret_ty: Type = if (extra.data.ret_ty.is_generic)
93109299 .generic_poison
93119300 else switch (extra.data.ret_ty.body_len) {
9312 0 => Type.void,
9301 0 => .void,
93139302 1 => blk: {
93149303 const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
93159304 extra_index += 1;
......@@ -9319,7 +9308,7 @@ fn zirFunc(
93199308 const ret_ty_body = sema.code.bodySlice(extra_index, extra.data.ret_ty.body_len);
93209309 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 });
93239312 break :blk ret_ty_val.toType();
93249313 },
93259314 };
......@@ -9649,7 +9638,7 @@ fn funcCommon(
96499638
96509639 var comptime_bits: u32 = 0;
96519640 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);
96539642 const is_noalias = blk: {
96549643 const index = std.math.cast(u5, i) orelse break :blk false;
96559644 break :blk @as(u1, @truncate(noalias_bits >> index)) != 0;
......@@ -9870,7 +9859,7 @@ fn finishFunc(
98709859 const return_type: Type = if (opt_func_index == .none or ret_poison)
98719860 bare_return_type
98729861 else
9873 Type.fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index)));
9862 .fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index)));
98749863
98759864 if (!return_type.isValidReturnType(zcu)) {
98769865 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!
1013010119 if (try sema.resolveValue(operand)) |operand_val| ct: {
1013110120 if (!is_vector) {
1013210121 if (operand_val.isUndef(zcu)) {
10133 return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern());
10122 return .undef_usize;
1013410123 }
1013510124 const addr = try operand_val.getUnsignedIntSema(pt) orelse {
1013610125 // Wasn't an integer pointer. This is a runtime operation.
1013710126 break :ct;
1013810127 };
1013910128 return Air.internedToRef((try pt.intValue(
10140 Type.usize,
10129 .usize,
1014110130 addr,
1014210131 )).toIntern());
1014310132 }
......@@ -10145,7 +10134,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1014510134 for (new_elems, 0..) |*new_elem, i| {
1014610135 const ptr_val = try operand_val.elemValue(pt, i);
1014710136 if (ptr_val.isUndef(zcu)) {
10148 new_elem.* = (try pt.undefValue(Type.usize)).toIntern();
10137 new_elem.* = .undef_usize;
1014910138 continue;
1015010139 }
1015110140 const addr = try ptr_val.getUnsignedIntSema(pt) orelse {
......@@ -10153,7 +10142,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1015310142 break :ct;
1015410143 };
1015510144 new_elem.* = (try pt.intValue(
10156 Type.usize,
10145 .usize,
1015710146 addr,
1015810147 )).toIntern();
1015910148 }
......@@ -10165,16 +10154,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1016510154 try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src);
1016610155 try sema.validateRuntimeValue(block, ptr_src, operand);
1016710156 try sema.checkLogicalPtrOperation(block, ptr_src, ptr_ty);
10168 if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
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);
10157 return block.addBitCast(dest_ty, operand);
1017810158}
1017910159
1018010160fn 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
1028310263 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast");
1028410264 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);
1028710267}
1028810268
1028910269fn intCast(
......@@ -10294,8 +10274,6 @@ fn intCast(
1029410274 dest_ty_src: LazySrcLoc,
1029510275 operand: Air.Inst.Ref,
1029610276 operand_src: LazySrcLoc,
10297 runtime_safety: bool,
10298 safety_panics_are_enum: bool,
1029910277) CompileError!Air.Inst.Ref {
1030010278 const pt = sema.pt;
1030110279 const zcu = pt.zcu;
......@@ -10314,7 +10292,7 @@ fn intCast(
1031410292
1031510293 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {
1031610294 // requirement: intCast(u0, input) iff input == 0
10317 if (runtime_safety and block.wantSafety()) {
10295 if (block.wantSafety()) {
1031810296 try sema.requireRuntimeBlock(block, src, operand_src);
1031910297 const wanted_info = dest_scalar_ty.intInfo(zcu);
1032010298 const wanted_bits = wanted_info.bits;
......@@ -10331,7 +10309,7 @@ fn intCast(
1033110309 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
1033210310 break :ok is_in_range;
1033310311 };
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);
1033510313 }
1033610314 }
1033710315
......@@ -10339,91 +10317,11 @@ fn intCast(
1033910317 }
1034010318
1034110319 try sema.requireRuntimeBlock(block, src, operand_src);
10342 if (runtime_safety and block.wantSafety()) {
10343 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {
10344 _ = try sema.preparePanicId(src, .negative_to_unsigned);
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);
10320 if (block.wantSafety()) {
10321 if (zcu.backendSupportsFeature(.panic_fn)) {
10322 _ = try sema.preparePanicId(src, .integer_out_of_bounds);
1042610323 }
10324 return block.addTyOp(.intcast_safe, dest_ty, operand);
1042710325 }
1042810326 return block.addTyOp(.intcast, dest_ty, operand);
1042910327}
......@@ -10640,17 +10538,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1064010538 if (dst_bits >= src_bits) {
1064110539 return sema.coerce(block, dest_ty, operand, operand_src);
1064210540 }
10643 if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
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);
10541 return block.addTyOp(.fptrunc, dest_ty, operand);
1065410542}
1065510543
1065610544fn 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
1067510563 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1067610564 const array = try sema.resolveInst(extra.lhs);
1067710565 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);
1067910567 return sema.elemVal(block, src, array, elem_index, elem_index_src, true);
1068010568}
1068110569
......@@ -10685,7 +10573,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1068510573
1068610574 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
1068710575 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);
1068910577 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
1069010578}
1069110579
......@@ -10728,7 +10616,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1072810616 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1072910617 const array_ptr = try sema.resolveInst(extra.lhs);
1073010618 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);
1073210620 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true);
1073310621}
1073410622
......@@ -10742,7 +10630,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
1074210630 const src = block.nodeOffset(inst_data.src_node);
1074310631 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
1074410632 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);
1074610634 const array_ty = sema.typeOf(array_ptr).childType(zcu);
1074710635 switch (array_ty.zigTypeTag(zcu)) {
1074810636 .array, .vector => {},
......@@ -11104,7 +10992,7 @@ const SwitchProngAnalysis = struct {
1110410992 if (operand_ty.zigTypeTag(zcu) == .@"union") {
1110510993 const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);
1110610994 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]);
1110810996 if (capture_byref) {
1110910997 const ptr_field_ty = try pt.ptrTypeSema(.{
1111010998 .child = field_ty.toIntern(),
......@@ -11154,7 +11042,7 @@ const SwitchProngAnalysis = struct {
1115411042 const first_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;
1115511043
1115611044 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
1115911047 const field_indices = try sema.arena.alloc(u32, case_vals.len);
1116011048 for (case_vals, field_indices) |item, *field_idx| {
......@@ -11165,7 +11053,7 @@ const SwitchProngAnalysis = struct {
1116511053 // Fast path: if all the operands are the same type already, we don't need to hit
1116611054 // PTR! This will also allow us to emit simpler code.
1116711055 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]);
1116911057 if (!field_ty.eql(first_field_ty, zcu)) break false;
1117011058 } else true;
1117111059
......@@ -11173,7 +11061,7 @@ const SwitchProngAnalysis = struct {
1117311061 // We need values to run PTR on, so make a bunch of undef constants.
1117411062 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
1117511063 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]);
1117711065 dummy.* = try pt.undefRef(field_ty);
1117811066 }
1117911067
......@@ -11208,7 +11096,7 @@ const SwitchProngAnalysis = struct {
1120811096 // We need values to run PTR on, so make a bunch of undef constants.
1120911097 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
1121011098 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]);
1121211100 const field_ptr_ty = try pt.ptrTypeSema(.{
1121311101 .child = field_ty.toIntern(),
1121411102 .flags = .{
......@@ -11271,7 +11159,7 @@ const SwitchProngAnalysis = struct {
1127111159 // If we can, try to avoid that using in-memory coercions.
1127211160 const first_non_imc = in_mem: {
1127311161 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]);
1127511163 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) {
1127611164 break :in_mem i;
1127711165 }
......@@ -11294,7 +11182,7 @@ const SwitchProngAnalysis = struct {
1129411182 {
1129511183 const next = first_non_imc + 1;
1129611184 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]);
1129811186 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) {
1129911187 in_mem_coercible.unset(i);
1130011188 }
......@@ -11341,7 +11229,7 @@ const SwitchProngAnalysis = struct {
1134111229 };
1134211230
1134311231 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]);
1134511233 const uncoerced = try coerce_block.addStructFieldVal(operand_val, field_idx, field_ty);
1134611234 const coerced = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src);
1134711235 _ = try coerce_block.addBr(capture_block_inst, coerced);
......@@ -11365,7 +11253,7 @@ const SwitchProngAnalysis = struct {
1136511253
1136611254 const first_imc_item_idx = in_mem_coercible.findFirstSet().?;
1136711255 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]);
1136911257 const uncoerced = try coerce_block.addStructFieldVal(operand_val, first_imc_field_idx, first_imc_field_ty);
1137011258 const coerced = try coerce_block.addBitCast(capture_ty, uncoerced);
1137111259 _ = try coerce_block.addBr(capture_block_inst, coerced);
......@@ -13165,7 +13053,7 @@ fn analyzeSwitchRuntimeBlock(
1316513053 for (seen_enum_fields, 0..) |seen_field, index| {
1316613054 if (seen_field != null) continue;
1316713055 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]);
1316913057 if (field_ty.zigTypeTag(zcu) != .noreturn) break true;
1317013058 } else false
1317113059 else
......@@ -13490,7 +13378,7 @@ const RangeSetUnhandledIterator = struct {
1349013378 inline .u64, .i64 => |val_int| {
1349113379 const next_int = @addWithOverflow(val_int, 1);
1349213380 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();
1349413382 },
1349513383 .big_int => {},
1349613384 .lazy_align, .lazy_size => unreachable,
......@@ -13506,7 +13394,7 @@ const RangeSetUnhandledIterator = struct {
1350613394 );
1350713395
1350813396 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();
1351013398 }
1351113399
1351213400 fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index {
......@@ -13636,7 +13524,7 @@ fn validateErrSetSwitch(
1363613524 .{},
1363713525 );
1363813526 }
13639 return Type.anyerror;
13527 return .anyerror;
1364013528 },
1364113529 else => |err_set_ty_index| else_validation: {
1364213530 const error_names = ip.indexToKey(err_set_ty_index).error_set_type.names;
......@@ -13839,7 +13727,7 @@ fn validateSwitchItemBool(
1383913727 item_ref: Zir.Inst.Ref,
1384013728 item_src: LazySrcLoc,
1384113729) 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);
1384313731 if (Value.fromInterned(item.val).toBool()) {
1384413732 true_count.* += 1;
1384513733 } else {
......@@ -14224,7 +14112,7 @@ fn zirShl(
1422414112 return lhs;
1422514113 }
1422614114 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);
1422814116 if (rhs_ty.zigTypeTag(zcu) == .vector) {
1422914117 var i: usize = 0;
1423014118 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
......@@ -14335,7 +14223,7 @@ fn zirShl(
1433514223 }
1433614224
1433714225 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);
1433914227 const op_ov = try block.addInst(.{
1434014228 .tag = .shl_with_overflow,
1434114229 .data = .{ .ty_pl = .{
......@@ -14351,8 +14239,7 @@ fn zirShl(
1435114239 try block.addReduce(ov_bit, .Or)
1435214240 else
1435314241 ov_bit;
14354 const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
14355 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
14242 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, .zero_u1);
1435614243
1435714244 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);
1435814245 return sema.tupleFieldValByIndex(block, op_ov, 0, op_ov_tuple_ty);
......@@ -14406,7 +14293,7 @@ fn zirShr(
1440614293 return lhs;
1440714294 }
1440814295 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);
1441014297 if (rhs_ty.zigTypeTag(zcu) == .vector) {
1441114298 var i: usize = 0;
1441214299 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
......@@ -14689,7 +14576,7 @@ fn analyzeTupleCat(
1468914576 try sema.tupleFieldValByIndex(block, rhs, i, rhs_ty);
1469014577 }
1469114578
14692 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);
14579 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
1469314580}
1469414581
1469514582fn 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
1471614603 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1471714604
1471814605 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;
1472014607 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
1472114608 };
1472214609 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
1489214779
1489314780 // lhs_dest_slice = dest[0..lhs.len]
1489414781 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);
1489614783 const lhs_dest_slice = try block.addInst(.{
1489714784 .tag = .slice,
1489814785 .data = .{ .ty_pl = .{
......@@ -14907,7 +14794,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1490714794 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
1490814795
1490914796 // 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);
1491114798 const rhs_dest_offset = try block.addInst(.{
1491214799 .tag = .ptr_add,
1491314800 .data = .{ .ty_pl = .{
......@@ -14932,7 +14819,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1493214819 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
1493314820
1493414821 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);
1493614823 const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty);
1493714824 const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern());
1493814825 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
1494314830
1494414831 var elem_i: u32 = 0;
1494514832 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);
1494714834 const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty);
1494814835 const operand_src = block.src(.{ .array_cat_lhs = .{
1494914836 .array_cat_offset = inst_data.src_node,
......@@ -14954,8 +14841,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1495414841 }
1495514842 while (elem_i < result_len) : (elem_i += 1) {
1495614843 const rhs_elem_i = elem_i - lhs_len;
14957 const elem_index = try pt.intRef(Type.usize, elem_i);
14958 const rhs_index = try pt.intRef(Type.usize, rhs_elem_i);
14844 const elem_index = try pt.intRef(.usize, elem_i);
14845 const rhs_index = try pt.intRef(.usize, rhs_elem_i);
1495914846 const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty);
1496014847 const operand_src = block.src(.{ .array_cat_rhs = .{
1496114848 .array_cat_offset = inst_data.src_node,
......@@ -14965,7 +14852,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1496514852 try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);
1496614853 }
1496714854 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);
1496914856 const elem_ptr = try block.addPtrElemPtr(mutable_alloc, elem_index, elem_ptr_ty);
1497014857 const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern());
1497114858 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
1497814865 {
1497914866 var elem_i: u32 = 0;
1498014867 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);
1498214869 const operand_src = block.src(.{ .array_cat_lhs = .{
1498314870 .array_cat_offset = inst_data.src_node,
1498414871 .elem_index = elem_i,
......@@ -14988,7 +14875,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1498814875 }
1498914876 while (elem_i < result_len) : (elem_i += 1) {
1499014877 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);
1499214879 const operand_src = block.src(.{ .array_cat_rhs = .{
1499314880 .array_cat_offset = inst_data.src_node,
1499414881 .elem_index = @intCast(rhs_elem_i),
......@@ -15012,8 +14899,8 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1501214899 switch (ptr_info.flags.size) {
1501314900 .slice => {
1501414901 const val = try sema.resolveConstDefinedValue(block, src, operand, .{ .simple = .slice_cat_operand });
15015 return Type.ArrayInfo{
15016 .elem_type = Type.fromInterned(ptr_info.child),
14902 return .{
14903 .elem_type = .fromInterned(ptr_info.child),
1501714904 .sentinel = switch (ptr_info.sentinel) {
1501814905 .none => null,
1501914906 else => Value.fromInterned(ptr_info.sentinel),
......@@ -15113,7 +15000,7 @@ fn analyzeTupleMul(
1511315000 @memcpy(element_refs[tuple_len * i ..][0..tuple_len], element_refs[0..tuple_len]);
1511415001 }
1511515002
15116 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);
15003 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
1511715004}
1511815005
1511915006fn 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
1516615053
1516715054 if (lhs_ty.isTuple(zcu)) {
1516815055 // 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 });
1517015057 const factor_casted = try sema.usizeCast(block, rhs_src, factor);
1517115058 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor_casted);
1517215059 }
......@@ -15188,7 +15075,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1518815075 };
1518915076
1519015077 // 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
1519315080 const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch
1519415081 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
1524615133 // to get the same elem values.
1524715134 const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len);
1524815135 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);
1525015137 lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false);
1525115138 }
1525215139
......@@ -15267,14 +15154,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1526715154 var elem_i: usize = 0;
1526815155 while (elem_i < result_len) {
1526915156 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);
1527115158 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
1527215159 try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store);
1527315160 elem_i += 1;
1527415161 }
1527515162 }
1527615163 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);
1527815165 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
1527915166 const init = Air.internedToRef(sent_val.toIntern());
1528015167 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
......@@ -16131,15 +16018,14 @@ fn zirOverflowArithmetic(
1613116018 const maybe_lhs_val = try sema.resolveValue(lhs);
1613216019 const maybe_rhs_val = try sema.resolveValue(rhs);
1613316020
16134 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
16135 const overflow_ty = Type.fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);
16021 const tuple_ty = try pt.overflowArithmeticTupleType(dest_ty);
16022 const overflow_ty: Type = .fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);
1613616023
1613716024 var result: struct {
1613816025 inst: Air.Inst.Ref = .none,
1613916026 wrapped: Value = Value.@"unreachable",
1614016027 overflow_bit: Value,
1614116028 } = result: {
16142 const zero_bit = try pt.intValue(Type.u1, 0);
1614316029 switch (zir_tag) {
1614416030 .add_with_overflow => {
1614516031 // If either of the arguments is zero, `false` is returned and the other is stored
......@@ -16147,12 +16033,12 @@ fn zirOverflowArithmetic(
1614716033 // Otherwise, if either of the argument is undefined, undefined is returned.
1614816034 if (maybe_lhs_val) |lhs_val| {
1614916035 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 };
1615116037 }
1615216038 }
1615316039 if (maybe_rhs_val) |rhs_val| {
1615416040 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 };
1615616042 }
1615716043 }
1615816044 if (maybe_lhs_val) |lhs_val| {
......@@ -16173,7 +16059,7 @@ fn zirOverflowArithmetic(
1617316059 if (rhs_val.isUndef(zcu)) {
1617416060 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1617516061 } 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 };
1617716063 } else if (maybe_lhs_val) |lhs_val| {
1617816064 if (lhs_val.isUndef(zcu)) {
1617916065 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
......@@ -16192,9 +16078,9 @@ fn zirOverflowArithmetic(
1619216078 if (maybe_lhs_val) |lhs_val| {
1619316079 if (!lhs_val.isUndef(zcu)) {
1619416080 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 };
1619616082 } 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 };
1619816084 }
1619916085 }
1620016086 }
......@@ -16202,9 +16088,9 @@ fn zirOverflowArithmetic(
1620216088 if (maybe_rhs_val) |rhs_val| {
1620316089 if (!rhs_val.isUndef(zcu)) {
1620416090 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 };
1620616092 } 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 };
1620816094 }
1620916095 }
1621016096 }
......@@ -16226,12 +16112,12 @@ fn zirOverflowArithmetic(
1622616112 // Oterhwise if either of the arguments is undefined, both results are undefined.
1622716113 if (maybe_lhs_val) |lhs_val| {
1622816114 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 };
1623016116 }
1623116117 }
1623216118 if (maybe_rhs_val) |rhs_val| {
1623316119 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 };
1623516121 }
1623616122 }
1623716123 if (maybe_lhs_val) |lhs_val| {
......@@ -16305,24 +16191,6 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
1630516191 return Value.fromInterned(repeated);
1630616192}
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
1632616194fn analyzeArithmetic(
1632716195 sema: *Sema,
1632816196 block: *Block,
......@@ -16380,7 +16248,7 @@ fn analyzeArithmetic(
1638016248 const address = std.math.sub(u64, lhs_ptr.byte_offset, rhs_ptr.byte_offset) catch
1638116249 return sema.fail(block, src, "operation results in overflow", .{});
1638216250 const result = address / elem_size;
16383 return try pt.intRef(Type.usize, result);
16251 return try pt.intRef(.usize, result);
1638416252 } else {
1638516253 break :runtime_src lhs_src;
1638616254 }
......@@ -16395,7 +16263,7 @@ fn analyzeArithmetic(
1639516263 const lhs_int = try block.addBitCast(.usize, lhs);
1639616264 const rhs_int = try block.addBitCast(.usize, rhs);
1639716265 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));
1639916267 }
1640016268 } else {
1640116269 switch (lhs_ty.ptrSize(zcu)) {
......@@ -16498,42 +16366,10 @@ fn analyzeArithmetic(
1649816366 }
1649916367
1650016368 if (block.wantSafety() and want_safety and scalar_tag == .int) {
16501 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {
16502 if (air_tag != air_tag_safe) {
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 }
16369 if (air_tag != air_tag_safe and zcu.backendSupportsFeature(.panic_fn)) {
16370 _ = try sema.preparePanicId(src, .integer_overflow);
1653616371 }
16372 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
1653716373 }
1653816374 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
1653916375}
......@@ -16550,7 +16386,7 @@ fn analyzePtrArithmetic(
1655016386) CompileError!Air.Inst.Ref {
1655116387 // TODO if the operand is comptime-known to be negative, or is a negative int,
1655216388 // 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);
1655416390 const pt = sema.pt;
1655516391 const zcu = pt.zcu;
1655616392 const opt_ptr_val = try sema.resolveValue(ptr);
......@@ -16736,8 +16572,8 @@ fn zirAsm(
1673616572 const uncasted_arg = try sema.resolveInst(input.data.operand);
1673716573 const uncasted_arg_ty = sema.typeOf(uncasted_arg);
1673816574 switch (uncasted_arg_ty.zigTypeTag(zcu)) {
16739 .comptime_int => arg.* = try sema.coerce(block, Type.usize, uncasted_arg, src),
16740 .comptime_float => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src),
16575 .comptime_int => arg.* = try sema.coerce(block, .usize, uncasted_arg, src),
16576 .comptime_float => arg.* = try sema.coerce(block, .f64, uncasted_arg, src),
1674116577 else => {
1674216578 arg.* = uncasted_arg;
1674316579 },
......@@ -16860,9 +16696,7 @@ fn zirCmpEq(
1686016696 const runtime_src: LazySrcLoc = src: {
1686116697 if (try sema.resolveValue(lhs)) |lval| {
1686216698 if (try sema.resolveValue(rhs)) |rval| {
16863 if (lval.isUndef(zcu) or rval.isUndef(zcu)) {
16864 return pt.undefRef(Type.bool);
16865 }
16699 if (lval.isUndef(zcu) or rval.isUndef(zcu)) return .undef_bool;
1686616700 const lkey = zcu.intern_pool.indexToKey(lval.toIntern());
1686716701 const rkey = zcu.intern_pool.indexToKey(rval.toIntern());
1686816702 return if ((lkey.err.name == rkey.err.name) == (op == .eq))
......@@ -16916,7 +16750,7 @@ fn analyzeCmpUnionTag(
1691616750 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1691716751
1691816752 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;
1692016754 const field_ty = union_ty.unionFieldType(enum_val, zcu).?;
1692116755 if (field_ty.zigTypeTag(zcu) == .noreturn) {
1692216756 return .bool_false;
......@@ -17027,8 +16861,8 @@ fn cmpSelf(
1702716861
1702816862 const maybe_lhs_val = try sema.resolveValue(casted_lhs);
1702916863 const maybe_rhs_val = try sema.resolveValue(casted_rhs);
17030 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool);
17031 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool);
16864 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
16865 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
1703216866
1703316867 const runtime_src: LazySrcLoc = src: {
1703416868 if (maybe_lhs_val) |lhs_val| {
......@@ -17083,7 +16917,7 @@ fn runtimeBoolCmp(
1708316917) CompileError!Air.Inst.Ref {
1708416918 if ((op == .neq) == rhs) {
1708516919 try sema.requireRuntimeBlock(block, src, runtime_src);
17086 return block.addTyOp(.not, Type.bool, lhs);
16920 return block.addTyOp(.not, .bool, lhs);
1708716921 } else {
1708816922 return lhs;
1708916923 }
......@@ -17107,7 +16941,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1710716941 .comptime_float,
1710816942 .comptime_int,
1710916943 .void,
17110 => return pt.intRef(Type.comptime_int, 0),
16944 => return .zero,
1711116945
1711216946 .bool,
1711316947 .int,
......@@ -17148,7 +16982,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1714816982 .comptime_float,
1714916983 .comptime_int,
1715016984 .void,
17151 => return pt.intRef(Type.comptime_int, 0),
16985 => return .zero,
1715216986
1715316987 .bool,
1715416988 .int,
......@@ -17167,7 +17001,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1716717001 => {},
1716817002 }
1716917003 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);
1717117005}
1717217006
1717317007fn zirThis(
......@@ -17285,7 +17119,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1728517119
1728617120 assert(block.is_typeof);
1728717121 // 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));
1728917123}
1729017124
1729117125fn zirRetAddr(
......@@ -17293,10 +17127,11 @@ fn zirRetAddr(
1729317127 block: *Block,
1729417128 extended: Zir.Inst.Extended.InstData,
1729517129) CompileError!Air.Inst.Ref {
17130 _ = sema;
1729617131 _ = extended;
1729717132 if (block.isComptime()) {
1729817133 // TODO: we could give a meaningful lazy value here. #14938
17299 return sema.pt.intRef(Type.usize, 0);
17134 return .zero_usize;
1730017135 } else {
1730117136 return block.addNoOp(.ret_addr);
1730217137 }
......@@ -17349,7 +17184,7 @@ fn zirBuiltinSrc(
1734917184 } },
1735017185 .byte_offset = 0,
1735117186 } }),
17352 .len = (try pt.intValue(Type.usize, func_name_len)).toIntern(),
17187 .len = (try pt.intValue(.usize, func_name_len)).toIntern(),
1735317188 } });
1735417189 };
1735517190
......@@ -17375,7 +17210,7 @@ fn zirBuiltinSrc(
1737517210 } },
1737617211 .byte_offset = 0,
1737717212 } }),
17378 .len = (try pt.intValue(Type.usize, module_name.len)).toIntern(),
17213 .len = (try pt.intValue(.usize, module_name.len)).toIntern(),
1737917214 } });
1738017215 };
1738117216
......@@ -17401,7 +17236,7 @@ fn zirBuiltinSrc(
1740117236 } },
1740217237 .byte_offset = 0,
1740317238 } }),
17404 .len = (try pt.intValue(Type.usize, file_name.len)).toIntern(),
17239 .len = (try pt.intValue(.usize, file_name.len)).toIntern(),
1740517240 } });
1740617241 };
1740717242
......@@ -17414,9 +17249,9 @@ fn zirBuiltinSrc(
1741417249 // fn_name: [:0]const u8,
1741517250 func_name_val,
1741617251 // line: u32,
17417 (try pt.intValue(Type.u32, extra.line + 1)).toIntern(),
17252 (try pt.intValue(.u32, extra.line + 1)).toIntern(),
1741817253 // column: u32,
17419 (try pt.intValue(Type.u32, extra.column + 1)).toIntern(),
17254 (try pt.intValue(.u32, extra.column + 1)).toIntern(),
1742017255 };
1742117256 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
1742217257 .ty = src_loc_ty.toIntern(),
......@@ -17511,7 +17346,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1751117346 } },
1751217347 .byte_offset = 0,
1751317348 } }),
17514 .len = (try pt.intValue(Type.usize, param_vals.len)).toIntern(),
17349 .len = (try pt.intValue(.usize, param_vals.len)).toIntern(),
1751517350 } });
1751617351 };
1751717352
......@@ -17564,7 +17399,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1756417399 // signedness: Signedness,
1756517400 (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),
1756617401 // bits: u16,
17567 (try pt.intValue(Type.u16, info.bits)).toIntern(),
17402 (try pt.intValue(.u16, info.bits)).toIntern(),
1756817403 };
1756917404 return Air.internedToRef((try pt.internUnion(.{
1757017405 .ty = type_info_ty.toIntern(),
......@@ -17580,7 +17415,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1758017415
1758117416 const field_vals = .{
1758217417 // bits: u16,
17583 (try pt.intValue(Type.u16, ty.bitSize(zcu))).toIntern(),
17418 (try pt.intValue(.u16, ty.bitSize(zcu))).toIntern(),
1758417419 };
1758517420 return Air.internedToRef((try pt.internUnion(.{
1758617421 .ty = type_info_ty.toIntern(),
......@@ -17594,7 +17429,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1759417429 .pointer => {
1759517430 const info = ty.ptrInfo(zcu);
1759617431 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|
17597 try pt.intValue(Type.comptime_int, alignment)
17432 try pt.intValue(.comptime_int, alignment)
1759817433 else
1759917434 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1760017435
......@@ -17638,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1763817473 const info = ty.arrayInfo(zcu);
1763917474 const field_values = .{
1764017475 // len: comptime_int,
17641 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17476 (try pt.intValue(.comptime_int, info.len)).toIntern(),
1764217477 // child: type,
1764317478 info.elem_type.toIntern(),
1764417479 // sentinel: ?*const anyopaque,
......@@ -17659,7 +17494,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1765917494 const info = ty.arrayInfo(zcu);
1766017495 const field_values = .{
1766117496 // len: comptime_int,
17662 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17497 (try pt.intValue(.comptime_int, info.len)).toIntern(),
1766317498 // child: type,
1766417499 info.elem_type.toIntern(),
1766517500 };
......@@ -17723,7 +17558,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1772317558 } },
1772417559 .byte_offset = 0,
1772517560 } }),
17726 .len = (try pt.intValue(Type.usize, error_name_len)).toIntern(),
17561 .len = (try pt.intValue(.usize, error_name_len)).toIntern(),
1772717562 } });
1772817563 };
1772917564
......@@ -17770,7 +17605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1777017605 } },
1777117606 .byte_offset = 0,
1777217607 } }),
17773 .len = (try pt.intValue(Type.usize, vals.len)).toIntern(),
17608 .len = (try pt.intValue(.usize, vals.len)).toIntern(),
1777417609 } });
1777517610 } else .none;
1777617611 const errors_val = try pt.intern(.{ .opt = .{
......@@ -17819,7 +17654,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1781917654 .comptime_int_type,
1782017655 )
1782117656 else
17822 (try pt.intValue(Type.comptime_int, tag_index)).toIntern();
17657 (try pt.intValue(.comptime_int, tag_index)).toIntern();
1782317658
1782417659 // TODO: write something like getCoercedInts to avoid needing to dupe
1782517660 const name_val = v: {
......@@ -17844,7 +17679,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1784417679 } },
1784517680 .byte_offset = 0,
1784617681 } }),
17847 .len = (try pt.intValue(Type.usize, tag_name_len)).toIntern(),
17682 .len = (try pt.intValue(.usize, tag_name_len)).toIntern(),
1784817683 } });
1784917684 };
1785017685
......@@ -17887,7 +17722,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1788717722 } },
1788817723 .byte_offset = 0,
1788917724 } }),
17890 .len = (try pt.intValue(Type.usize, enum_field_vals.len)).toIntern(),
17725 .len = (try pt.intValue(.usize, enum_field_vals.len)).toIntern(),
1789117726 } });
1789217727 };
1789317728
......@@ -17949,7 +17784,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1794917784 } },
1795017785 .byte_offset = 0,
1795117786 } }),
17952 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
17787 .len = (try pt.intValue(.usize, field_name_len)).toIntern(),
1795317788 } });
1795417789 };
1795517790
......@@ -17965,7 +17800,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1796517800 // type: type,
1796617801 field_ty,
1796717802 // 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(),
1796917804 };
1797017805 field_val.* = try pt.intern(.{ .aggregate = .{
1797117806 .ty = union_field_ty.toIntern(),
......@@ -18000,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1800017835 } },
1800117836 .byte_offset = 0,
1800217837 } }),
18003 .len = (try pt.intValue(Type.usize, union_field_vals.len)).toIntern(),
17838 .len = (try pt.intValue(.usize, union_field_vals.len)).toIntern(),
1800417839 } });
1800517840 };
1800617841
......@@ -18070,7 +17905,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1807017905 } },
1807117906 .byte_offset = 0,
1807217907 } }),
18073 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
17908 .len = (try pt.intValue(.usize, field_name_len)).toIntern(),
1807417909 } });
1807517910 };
1807617911
......@@ -18089,7 +17924,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1808917924 // is_comptime: bool,
1809017925 Value.makeBool(is_comptime).toIntern(),
1809117926 // 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(),
1809317928 };
1809417929 struct_field_val.* = try pt.intern(.{ .aggregate = .{
1809517930 .ty = struct_field_ty.toIntern(),
......@@ -18111,7 +17946,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1811117946 else
1811217947 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
1811317948 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]);
1811517950 const field_init = struct_type.fieldInit(ip, field_index);
1811617951 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
1811717952 const name_val = v: {
......@@ -18134,7 +17969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1813417969 } },
1813517970 .byte_offset = 0,
1813617971 } }),
18137 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
17972 .len = (try pt.intValue(.usize, field_name_len)).toIntern(),
1813817973 } });
1813917974 };
1814017975
......@@ -18159,7 +17994,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1815917994 // is_comptime: bool,
1816017995 Value.makeBool(field_is_comptime).toIntern(),
1816117996 // 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(),
1816317998 };
1816417999 field_val.* = try pt.intern(.{ .aggregate = .{
1816518000 .ty = struct_field_ty.toIntern(),
......@@ -18195,7 +18030,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1819518030 } },
1819618031 .byte_offset = 0,
1819718032 } }),
18198 .len = (try pt.intValue(Type.usize, struct_field_vals.len)).toIntern(),
18033 .len = (try pt.intValue(.usize, struct_field_vals.len)).toIntern(),
1819918034 } });
1820018035 };
1820118036
......@@ -18304,7 +18139,7 @@ fn typeInfoDecls(
1830418139 } },
1830518140 .byte_offset = 0,
1830618141 } }),
18307 .len = (try pt.intValue(Type.usize, decl_vals.items.len)).toIntern(),
18142 .len = (try pt.intValue(.usize, decl_vals.items.len)).toIntern(),
1830818143 } });
1830918144}
1831018145
......@@ -18354,7 +18189,7 @@ fn typeInfoNamespaceDecls(
1835418189 .byte_offset = 0,
1835518190 },
1835618191 }),
18357 .len = (try pt.intValue(Type.usize, name_len)).toIntern(),
18192 .len = (try pt.intValue(.usize, name_len)).toIntern(),
1835818193 },
1835918194 });
1836018195 };
......@@ -18373,7 +18208,7 @@ fn typeInfoNamespaceDecls(
1837318208 continue;
1837418209 }
1837518210 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);
1837718212 try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces);
1837818213 }
1837918214}
......@@ -18424,7 +18259,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1842418259 const pt = sema.pt;
1842518260 const zcu = pt.zcu;
1842618261 switch (operand.zigTypeTag(zcu)) {
18427 .comptime_int => return Type.comptime_int,
18262 .comptime_int => return .comptime_int,
1842818263 .int => {
1842918264 const bits = operand.bitSize(zcu);
1843018265 const count = if (bits == 0)
......@@ -18512,14 +18347,12 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1851218347 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
1851318348 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);
1851618351 if (try sema.resolveValue(operand)) |val| {
18517 return if (val.isUndef(zcu))
18518 pt.undefRef(Type.bool)
18519 else if (val.toBool()) .bool_false else .bool_true;
18352 return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;
1852018353 }
1852118354 try sema.requireRuntimeBlock(block, src, null);
18522 return block.addTyOp(.not, Type.bool, operand);
18355 return block.addTyOp(.not, .bool, operand);
1852318356}
1852418357
1852518358fn zirBoolBr(
......@@ -18544,7 +18377,7 @@ fn zirBoolBr(
1854418377 const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1854518378 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
1854918382 if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| {
1855018383 if (is_bool_or and lhs_val.toBool()) {
......@@ -18559,7 +18392,7 @@ fn zirBoolBr(
1855918392 if (sema.typeOf(rhs_result).isNoReturn(zcu)) {
1856018393 return rhs_result;
1856118394 }
18562 return sema.coerce(parent_block, Type.bool, rhs_result, rhs_src);
18395 return sema.coerce(parent_block, .bool, rhs_result, rhs_src);
1856318396 }
1856418397
1856518398 const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
......@@ -18596,7 +18429,7 @@ fn zirBoolBr(
1859618429 const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst);
1859718430 const rhs_noret = sema.typeOf(rhs_result).isNoReturn(zcu);
1859818431 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);
1860018433 _ = try rhs_block.addBr(block_inst, coerced_result);
1860118434 break :rhs coerced_result;
1860218435 } else rhs_result;
......@@ -18797,7 +18630,7 @@ fn zirCondbr(
1879718630 const else_body = sema.code.bodySlice(extra.end + then_body.len, extra.data.else_body_len);
1879818631
1879918632 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
1880218635 if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {
1880318636 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
1950219335 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
1950319336 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
1950419337 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);
1950619339 const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" });
1950719340 // Check if this happens to be the lazy alignment of our element type, in
1950819341 // 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
1952619359 const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: {
1952719360 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
1952819361 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 });
1953019363 break :blk @intCast(bit_offset);
1953119364 } else 0;
1953219365
1953319366 const host_size: u16 = if (inst_data.flags.has_bit_range) blk: {
1953419367 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
1953519368 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 });
1953719370 break :blk @intCast(host_size);
1953819371 } else 0;
1953919372
......@@ -19767,7 +19600,7 @@ fn unionInit(
1976719600 const zcu = pt.zcu;
1976819601 const ip = &zcu.intern_pool;
1976919602 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]);
1977119604 const init = try sema.coerce(block, field_ty, uncasted_init, init_src);
1977219605 _ = union_ty_src;
1977319606 return unionInitFromEnumTag(sema, block, init_src, union_ty, field_index, init);
......@@ -19902,7 +19735,7 @@ fn zirStructInit(
1990219735 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
1990319736 const tag_ty = resolved_ty.unionTagTypeHypothetical(zcu);
1990419737 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
1990719740 if (field_ty.zigTypeTag(zcu) == .noreturn) {
1990819741 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -19990,7 +19823,7 @@ fn finishStructInit(
1999019823 .init_node_offset = init_src.offset.node_offset.x,
1999119824 .elem_index = @intCast(i),
1999219825 } });
19993 const field_ty = Type.fromInterned(tuple.types.get(ip)[i]);
19826 const field_ty: Type = .fromInterned(tuple.types.get(ip)[i]);
1999419827 field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
1999519828 continue;
1999619829 }
......@@ -20018,7 +19851,7 @@ fn finishStructInit(
2001819851 .init_node_offset = init_src.offset.node_offset.x,
2001919852 .elem_index = @intCast(i),
2002019853 } });
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]);
2002219855 field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
2002319856 continue;
2002419857 }
......@@ -20183,7 +20016,7 @@ fn structInitAnon(
2018320016 const msg = try sema.errMsg(field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
2018420017 errdefer msg.destroy(sema.gpa);
2018520018
20186 try sema.addDeclaredHereNote(msg, Type.fromInterned(field_ty.*));
20019 try sema.addDeclaredHereNote(msg, .fromInterned(field_ty.*));
2018720020 break :msg msg;
2018820021 };
2018920022 return sema.failWithOwnedErrorMsg(block, msg);
......@@ -20317,7 +20150,7 @@ fn structInitAnon(
2031720150 element_refs[i] = try sema.resolveInst(item.data.init);
2031820151 }
2031920152
20320 return block.addAggregateInit(Type.fromInterned(struct_ty), element_refs);
20153 return block.addAggregateInit(.fromInterned(struct_ty), element_refs);
2032120154}
2032220155
2032320156fn zirArrayInit(
......@@ -20441,7 +20274,7 @@ fn zirArrayInit(
2044120274 });
2044220275 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);
2044520278 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
2044620279 _ = try block.addBinOp(.store, elem_ptr, arg);
2044720280 }
......@@ -20455,7 +20288,7 @@ fn zirArrayInit(
2045520288 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
2045620289
2045720290 for (resolved_args, 0..) |arg, i| {
20458 const index = try pt.intRef(Type.usize, i);
20291 const index = try pt.intRef(.usize, i);
2045920292 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
2046020293 _ = try block.addBinOp(.store, elem_ptr, arg);
2046120294 }
......@@ -20504,7 +20337,7 @@ fn arrayInitAnon(
2050420337 const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
2050520338 errdefer msg.destroy(gpa);
2050620339
20507 try sema.addDeclaredHereNote(msg, Type.fromInterned(types[i]));
20340 try sema.addDeclaredHereNote(msg, .fromInterned(types[i]));
2050820341 break :msg msg;
2050920342 };
2051020343 return sema.failWithOwnedErrorMsg(block, msg);
......@@ -20561,7 +20394,7 @@ fn arrayInitAnon(
2056120394 element_refs[i] = try sema.resolveInst(operand);
2056220395 }
2056320396
20564 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);
20397 return block.addAggregateInit(.fromInterned(tuple_ty), element_refs);
2056520398}
2056620399
2056720400fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
......@@ -20632,7 +20465,7 @@ fn fieldType(
2063220465 .optional => {
2063320466 // Struct/array init through optional requires the child type to not be a pointer.
2063420467 // 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);
2063620469 continue;
2063720470 },
2063820471 .error_union => {
......@@ -20710,44 +20543,32 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2071020543 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .u1_type, .len = len }) else .u1;
2071120544 if (try sema.resolveValue(operand)) |val| {
2071220545 if (!is_vector) {
20713 if (val.isUndef(zcu)) return pt.undefRef(Type.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());
20546 return if (val.isUndef(zcu)) .undef_u1 else if (val.toBool()) .one_u1 else .zero_u1;
2071620547 }
2071720548 if (val.isUndef(zcu)) return pt.undefRef(dest_ty);
2071820549 const new_elems = try sema.arena.alloc(InternPool.Index, len);
2071920550 for (new_elems, 0..) |*new_elem, i| {
2072020551 const old_elem = try val.elemValue(pt, i);
20721 const new_val = if (old_elem.isUndef(zcu))
20722 try pt.undefValue(Type.u1)
20552 new_elem.* = if (old_elem.isUndef(zcu))
20553 .undef_u1
2072320554 else if (old_elem.toBool())
20724 try pt.intValue(Type.u1, 1)
20555 .one_u1
2072520556 else
20726 try pt.intValue(Type.u1, 0);
20727 new_elem.* = new_val.toIntern();
20557 .zero_u1;
2072820558 }
2072920559 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
2073020560 .ty = dest_ty.toIntern(),
2073120561 .storage = .{ .elems = new_elems },
2073220562 } }));
2073320563 }
20734 if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
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);
20564 return block.addBitCast(dest_ty, operand);
2074420565}
2074520566
2074620567fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2074720568 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2074820569 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2074920570 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
2075220573 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
2075320574 const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name;
......@@ -20993,12 +20814,12 @@ fn zirReify(
2099320814 .float => {
2099420815 const float = try sema.interpretBuiltinType(block, operand_src, .fromInterned(union_val.val), std.builtin.Type.Float);
2099520816
20996 const ty = switch (float.bits) {
20997 16 => Type.f16,
20998 32 => Type.f32,
20999 64 => Type.f64,
21000 80 => Type.f80,
21001 128 => Type.f128,
20817 const ty: Type = switch (float.bits) {
20818 16 => .f16,
20819 32 => .f32,
20820 64 => .f64,
20821 80 => .f80,
20822 128 => .f128,
2100220823 else => return sema.fail(block, src, "{}-bit float unsupported", .{float.bits}),
2100320824 };
2100420825 return Air.internedToRef(ty.toIntern());
......@@ -21038,7 +20859,7 @@ fn zirReify(
2103820859 try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls),
2103920860 ).?);
2104020861
21041 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
20862 if (!try sema.intFitsInType(alignment_val, .u32, null)) {
2104220863 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2104320864 }
2104420865
......@@ -21174,7 +20995,7 @@ fn zirReify(
2117420995 },
2117520996 .error_set => {
2117620997 const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse
21177 return Air.internedToRef(Type.anyerror.toIntern());
20998 return .anyerror_type;
2117820999
2117921000 const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ .simple = .error_set_contents });
2118021001
......@@ -21776,7 +21597,7 @@ fn reifyUnion(
2177621597 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2177721598
2177821599 for (field_types) |field_ty_ip| {
21779 const field_ty = Type.fromInterned(field_ty_ip);
21600 const field_ty: Type = .fromInterned(field_ty_ip);
2178021601 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
2178121602 return sema.failWithOwnedErrorMsg(block, msg: {
2178221603 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(
2206021881 }
2206121882
2206221883 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)) {
2206421885 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2206521886 }
2206621887
......@@ -22149,7 +21970,7 @@ fn reifyStruct(
2214921970 if (layout == .@"packed") {
2215021971 var fields_bit_sum: u64 = 0;
2215121972 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]);
2215321974 field_ty.resolveLayout(pt) catch |err| switch (err) {
2215421975 error.AnalysisFail => {
2215521976 const msg = sema.err orelse return err;
......@@ -22325,7 +22146,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2232522146 if (block.wantSafety()) {
2232622147 const len = dest_ty.vectorLen(zcu);
2232722148 for (0..len) |i| {
22328 const idx_ref = try pt.intRef(Type.usize, i);
22149 const idx_ref = try pt.intRef(.usize, i);
2232922150 const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref);
2233022151 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()));
2233122152 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
2233622157 .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() },
2233722158 } }));
2233822159 }
22339 if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
22340 const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_ty, operand);
22341 if (block.wantSafety()) {
22342 const back = try block.addTyOp(.float_from_int, operand_ty, result);
22343 const diff = try block.addBinOp(if (block.float_mode == .optimized) .sub_optimized else .sub, operand, back);
22344 const ok = if (is_vector) ok: {
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);
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);
22347 const ok = try block.addBinOp(.bit_and, ok_pos, ok_neg);
22348 break :ok try block.addReduce(ok, .And);
22349 } else ok: {
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()));
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()));
22352 break :ok try block.addBinOp(.bool_and, ok_pos, ok_neg);
22353 };
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;
22160 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()) {
22162 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);
22164 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);
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);
22167 const ok = try block.addBinOp(.bit_and, ok_pos, ok_neg);
22168 break :ok try block.addReduce(ok, .And);
22169 } 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()));
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()));
22172 break :ok try block.addBinOp(.bool_and, ok_pos, ok_neg);
22173 };
22174 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
2237322175 }
22374 return block.addAggregateInit(dest_ty, new_elems);
22176 return result;
2237522177}
2237622178
2237722179fn 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
2238622188 const operand_ty = sema.typeOf(operand);
2238722189
2238822190 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src);
22389 const is_vector = dest_ty.zigTypeTag(zcu) == .vector;
2239022191
2239122192 const dest_scalar_ty = dest_ty.scalarType(zcu);
2239222193 const operand_scalar_ty = operand_ty.scalarType(zcu);
......@@ -22402,17 +22203,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2240222203 }
2240322204
2240422205 try sema.requireRuntimeBlock(block, src, operand_src);
22405 if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
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);
22206 return block.addTyOp(.float_from_int, dest_ty, operand);
2241622207}
2241722208
2241822209fn 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!
2243122222 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, uncoerced_operand_ty, src, operand_src);
2243222223
2243322224 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: {
2243522226 const len = dest_ty.vectorLen(zcu);
2243622227 break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len });
22437 } else Type.usize;
22228 } else .usize;
2243822229
2243922230 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!
2248222273 }
2248322274 try sema.requireRuntimeBlock(block, src, operand_src);
2248422275 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);
2251722276 if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) {
22518 for (0..len) |i| {
22519 const idx_ref = try pt.intRef(Type.usize, i);
22520 const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);
22521 if (!ptr_ty.isAllowzeroPtr(zcu)) {
22522 const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize);
22523 try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null);
22524 }
22525 if (ptr_align.compare(.gt, .@"1")) {
22526 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;
22527 const align_mask = Air.internedToRef((try pt.intValue(
22528 Type.usize,
22529 if (elem_ty.fnPtrMaskOrNull(zcu)) |mask|
22530 align_bytes_minus_1 & mask
22531 else
22532 align_bytes_minus_1,
22533 )).toIntern());
22534 const remainder = try block.addBinOp(.bit_and, elem_coerced, align_mask);
22535 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22536 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
22537 }
22277 if (!ptr_ty.isAllowzeroPtr(zcu)) {
22278 const is_non_zero = if (is_vector) all_non_zero: {
22279 const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());
22280 const is_non_zero = try block.addCmpVector(operand_coerced, zero_usize, .neq);
22281 break :all_non_zero try block.addReduce(is_non_zero, .And);
22282 } else try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
22283 try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null);
22284 }
22285 if (ptr_align.compare(.gt, .@"1")) {
22286 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;
22287 const align_mask = Air.internedToRef((try sema.splat(operand_ty, try pt.intValue(
22288 .usize,
22289 if (elem_ty.fnPtrMaskOrNull(zcu)) |mask|
22290 align_bytes_minus_1 & mask
22291 else
22292 align_bytes_minus_1,
22293 ))).toIntern());
22294 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_mask);
22295 const is_aligned = if (is_vector) all_aligned: {
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);
2253822301 }
2253922302 }
22540
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);
22303 return block.addBitCast(dest_ty, operand_coerced);
2254822304}
2254922305
2255022306fn ptrFromIntVal(
......@@ -22918,12 +22674,12 @@ fn ptrCastFull(
2291822674 }
2291922675
2292022676 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: {
2292222678 // *[n]T -> []T
2292322679 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
2292822684 const imc_res = try sema.coerceInMemoryAllowed(
2292922685 block,
......@@ -22956,7 +22712,7 @@ fn ptrCastFull(
2295622712 }
2295722713 if (is_array_ptr_to_slice) {
2295822714 // [*]nT -> []T
22959 const arr_ty = Type.fromInterned(src_info.child);
22715 const arr_ty: Type = .fromInterned(src_info.child);
2296022716 if (arr_ty.sentinel(zcu)) |src_sentinel| {
2296122717 const coerced_sent = try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child);
2296222718 if (dest_info.sentinel == coerced_sent) break :check_sent;
......@@ -23158,7 +22914,7 @@ fn ptrCastFull(
2315822914 if (dest_info.flags.size == .slice) {
2315922915 // Because the operand is comptime-known and not `null`, the slice length has already been computed:
2316022916 const len: Value = switch (dest_slice_len.?) {
23161 .undef => try pt.undefValue(.usize),
22917 .undef => .undef_usize,
2316222918 .constant => |n| try pt.intValue(.usize, n),
2316322919 .equal_runtime_src_slice => unreachable,
2316422920 .change_runtime_src_slice => unreachable,
......@@ -23267,7 +23023,7 @@ fn ptrCastFull(
2326723023 if (need_align_check) {
2326823024 assert(operand_ptr_int != .none);
2326923025 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);
2327123027 break :mask (dest_align.toByteUnits().? - 1) & target_ptr_mask;
2327223028 });
2327323029 const ptr_masked = try block.addBinOp(.bit_and, operand_ptr_int, align_mask);
......@@ -23288,7 +23044,7 @@ fn ptrCastFull(
2328823044 assert(need_operand_ptr);
2328923045
2329023046 const result_len: Air.Inst.Ref = switch (dest_slice_len.?) {
23291 .undef => try pt.undefRef(.usize),
23047 .undef => .undef_usize,
2329223048 .constant => |n| try pt.intRef(.usize, n),
2329323049 .equal_runtime_src_slice => len: {
2329423050 assert(need_operand_len);
......@@ -23658,13 +23414,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2365823414
2365923415fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2366023416 const offset = try sema.bitOffsetOf(block, inst);
23661 return sema.pt.intRef(Type.comptime_int, offset);
23417 return sema.pt.intRef(.comptime_int, offset);
2366223418}
2366323419
2366423420fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2366523421 const offset = try sema.bitOffsetOf(block, inst);
2366623422 // 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);
2366823424}
2366923425
2367023426fn 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
2370523461 if (i == field_index) {
2370623462 return bit_sum;
2370723463 }
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]);
2370923465 bit_sum += field_ty.bitSize(zcu);
2371023466 } else unreachable;
2371123467 },
......@@ -24497,8 +24253,8 @@ fn analyzeShuffle(
2449724253 block: *Block,
2449824254 src_node: std.zig.Ast.Node.Offset,
2449924255 elem_ty: Type,
24500 a_arg: Air.Inst.Ref,
24501 b_arg: Air.Inst.Ref,
24256 a_uncoerced: Air.Inst.Ref,
24257 b_uncoerced: Air.Inst.Ref,
2450224258 mask: Value,
2450324259 mask_len: u32,
2450424260) CompileError!Air.Inst.Ref {
......@@ -24507,150 +24263,154 @@ fn analyzeShuffle(
2450724263 const a_src = block.builtinCallArgSrc(src_node, 1);
2450824264 const b_src = block.builtinCallArgSrc(src_node, 2);
2450924265 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)) {
24519 .array, .vector => sema.typeOf(a).arrayLen(zcu),
24520 .undefined => null,
24521 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{
24522 elem_ty.fmt(pt),
24523 sema.typeOf(a).fmt(pt),
24524 }),
24525 };
24526 const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(zcu)) {
24527 .array, .vector => sema.typeOf(b).arrayLen(zcu),
24528 .undefined => null,
24529 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{
24530 elem_ty.fmt(pt),
24531 sema.typeOf(b).fmt(pt),
24532 }),
24533 };
24534 if (maybe_a_len == null and maybe_b_len == null) {
24535 return pt.undefRef(res_ty);
24536 }
24537 const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?);
24538 const b_len: u32 = @intCast(maybe_b_len orelse a_len);
24539
24540 const a_ty = try pt.vectorType(.{
24541 .len = a_len,
24542 .child = elem_ty.toIntern(),
24543 });
24544 const b_ty = try pt.vectorType(.{
24545 .len = b_len,
24546 .child = elem_ty.toIntern(),
24547 });
24548
24549 if (maybe_a_len == null) a = try pt.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src);
24550 if (maybe_b_len == null) b = try pt.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src);
24551
24552 const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){
24553 .{ a_len, a_src, a_ty },
24554 .{ b_len, b_src, b_ty },
24555 };
24556
24557 for (0..@intCast(mask_len)) |i| {
24558 const elem = try mask.elemValue(pt, i);
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;
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.
24268 const a_len: u32 = switch (sema.typeOf(a_uncoerced).zigTypeTag(zcu)) {
24269 .array, .vector => @intCast(sema.typeOf(a_uncoerced).arrayLen(zcu)),
24270 .undefined => 0,
24271 else => return sema.fail(block, a_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(a_uncoerced).fmt(pt) }),
24272 };
24273 const a_ty = try pt.vectorType(.{ .len = a_len, .child = elem_ty.toIntern() });
24274 const a_coerced = try sema.coerce(block, a_ty, a_uncoerced, a_src);
24275
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.
24277 const b_len: u32 = switch (sema.typeOf(b_uncoerced).zigTypeTag(zcu)) {
24278 .array, .vector => @intCast(sema.typeOf(b_uncoerced).arrayLen(zcu)),
24279 .undefined => 0,
24280 else => return sema.fail(block, b_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(b_uncoerced).fmt(pt) }),
24281 };
24282 const b_ty = try pt.vectorType(.{ .len = b_len, .child = elem_ty.toIntern() });
24283 const b_coerced = try sema.coerce(block, b_ty, b_uncoerced, b_src);
24284
24285 const result_ty = try pt.vectorType(.{ .len = mask_len, .child = elem_ty.toIntern() });
24286
24287 // We're going to pre-emptively reserve space in `sema.air_extra`. The reason for this is we need
24288 // a `u32` buffer of length `mask_len` anyway, and putting it in `sema.air_extra` avoids a copy
24289 // in the runtime case. If the result is comptime-known, we'll shrink `air_extra` back.
24290 const air_extra_idx: u32 = @intCast(sema.air_extra.items.len);
24291 const air_mask_buf = try sema.air_extra.addManyAsSlice(sema.gpa, mask_len);
24292
24293 // We want to interpret that buffer in `air_extra` in a few ways. Initially, we'll consider its
24294 // elements as `Air.Inst.ShuffleTwoMask`, essentially representing the raw mask values; then, we'll
24295 // convert it to `InternPool.Index` or `Air.Inst.ShuffleOneMask` if there are comptime-known operands.
24296 const mask_ip_index: []InternPool.Index = @ptrCast(air_mask_buf);
24297 const mask_shuffle_one: []Air.ShuffleOneMask = @ptrCast(air_mask_buf);
24298 const mask_shuffle_two: []Air.ShuffleTwoMask = @ptrCast(air_mask_buf);
24299
24300 // Initial loop: check mask elements, populate `mask_shuffle_two`.
24301 var a_used = false;
24302 var b_used = false;
24303 for (mask_shuffle_two, 0..mask_len) |*out, mask_idx| {
24304 const mask_val = try mask.elemValue(pt, mask_idx);
24305 if (mask_val.isUndef(zcu)) {
24306 out.* = .undef;
24307 continue;
2457024308 }
24571 if (unsigned >= operand_info[chosen][0]) {
24572 const msg = msg: {
24573 const msg = try sema.errMsg(mask_src, "mask index '{d}' has out-of-bounds selection", .{i});
24309 // Safe because mask elements are `i32` and we already checked for undef:
24310 const raw = (try sema.resolveLazyValue(mask_val)).toSignedInt(zcu);
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});
2457424317 errdefer msg.destroy(sema.gpa);
24575
24576 try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{
24577 unsigned,
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", .{});
24318 try sema.errNote(a_src, msg, "index '{d}' exceeds bounds of '{}' given here", .{ idx, a_ty.fmt(pt) });
24319 if (idx < b_len) {
24320 try sema.errNote(b_src, msg, "use '~@as(u32, {d})' to index into second vector given here", .{idx});
2458324321 }
24584
2458524322 break :msg msg;
24586 };
24587 return sema.failWithOwnedErrorMsg(block, msg);
24323 });
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 });
2458824334 }
2458924335 }
2459024336
24591 if (try sema.resolveValue(a)) |a_val| {
24592 if (try sema.resolveValue(b)) |b_val| {
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 }
24337 const maybe_a_val = try sema.resolveValue(a_coerced);
24338 const maybe_b_val = try sema.resolveValue(b_coerced);
2461024339
24611 // All static analysis passed, and not comptime.
24612 // For runtime codegen, vectors a and b must be the same length. Here we
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));
24340 const a_rt = a_used and maybe_a_val == null;
24341 const b_rt = b_used and maybe_b_val == null;
2462024342
24621 const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len);
24622 for (@intCast(0)..@intCast(min_len)) |i| {
24623 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, i)).toIntern();
24343 if (a_rt and b_rt) {
24344 // Both operands are needed and runtime-known. We need a `[]ShuffleTwomask`... which is
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 };
2462424364 }
24625 for (@intCast(min_len)..@intCast(max_len)) |i| {
24626 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, -1)).toIntern();
24365 // Now just append our single runtime operand, and we're done.
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 };
2462724383 }
24628 const expand_mask = try pt.intern(.{ .aggregate = .{
24629 .ty = (try pt.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(),
24630 .storage = .{ .elems = expand_mask_values },
24631 } });
24632
24633 if (a_len < b_len) {
24634 const undef = try pt.undefRef(a_ty);
24635 a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24636 } else {
24637 const undef = try pt.undefRef(b_ty);
24638 b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24384 // Now just append our single runtime operand, and we're done.
24385 try sema.air_extra.ensureUnusedCapacity(sema.gpa, 1);
24386 sema.appendRefsAssumeCapacity(&.{b_coerced});
24387 return block.addInst(.{
24388 .tag = .shuffle_one,
24389 .data = .{ .ty_pl = .{
24390 .ty = Air.internedToRef(result_ty.toIntern()),
24391 .payload = air_extra_idx,
24392 } },
24393 });
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();
2463924404 }
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);
2464024413 }
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 });
2465424414}
2465524415
2465624416fn 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
2508724847 if (parent_ptr_info.flags.size != .one) {
2508824848 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)});
2508924849 }
25090 const parent_ty = Type.fromInterned(parent_ptr_info.child);
24850 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
2509124851 switch (parent_ty.zigTypeTag(zcu)) {
2509224852 .@"struct", .@"union" => {},
2509324853 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(
2574125501 if (try sema.resolveDefinedValue(block, dest_src, dest_len)) |dest_len_val| {
2574225502 len_val = dest_len_val;
2574325503 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))) {
2574525505 const msg = msg: {
2574625506 const msg = try sema.errMsg(src, "non-matching copy lengths", .{});
2574725507 errdefer msg.destroy(sema.gpa);
......@@ -25952,7 +25712,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2595225712 const dest_elem_ty: Type = dest_elem_ty: {
2595325713 const ptr_info = dest_ptr_ty.ptrInfo(zcu);
2595425714 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),
2595625716 .one => {
2595725717 if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .array) {
2595825718 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
2611825878 extra_index += body.len;
2611925879 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 });
2612225882 const ty = val.toType();
2612325883 break :blk ty;
2612425884 } 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
2612925889 const ret_ty_air_ref = try sema.resolveInst(ret_ty_ref);
2613025890 const ret_ty_val = try sema.resolveConstDefinedValue(block, ret_src, ret_ty_air_ref, .{ .simple = .function_ret_ty });
2613125891 break :blk ret_ty_val.toType();
26132 } else Type.void;
25892 } else .void;
2613325893
2613425894 const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: {
2613525895 const x = sema.code.extra[extra_index];
......@@ -26223,7 +25983,7 @@ fn zirWasmMemorySize(
2622325983 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
2622425984 }
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 }));
2622725987 try sema.requireRuntimeBlock(block, builtin_src, null);
2622825988 return block.addInst(.{
2622925989 .tag = .wasm_memory_size,
......@@ -26248,8 +26008,8 @@ fn zirWasmMemoryGrow(
2624826008 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
2624926009 }
2625026010
26251 const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, Type.u32, .{ .simple = .wasm_memory_index }));
26252 const delta = try sema.coerce(block, Type.usize, try sema.resolveInst(extra.rhs), delta_src);
26011 const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, .u32, .{ .simple = .wasm_memory_index }));
26012 const delta = try sema.coerce(block, .usize, try sema.resolveInst(extra.rhs), delta_src);
2625326013
2625426014 try sema.requireRuntimeBlock(block, builtin_src, null);
2625526015 return block.addInst(.{
......@@ -26484,7 +26244,7 @@ fn zirWorkItem(
2648426244 },
2648526245 }
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 }));
2648826248 try sema.requireRuntimeBlock(block, builtin_src, null);
2648926249
2649026250 return block.addInst(.{
......@@ -26552,7 +26312,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2655226312 const inline_tag_val = try pt.enumValue(
2655326313 callconv_tag_ty,
2655426314 (try pt.intValue(
26555 Type.u8,
26315 .u8,
2655626316 @intFromEnum(std.builtin.CallingConvention.@"inline"),
2655726317 )).toIntern(),
2655826318 );
......@@ -26760,7 +26520,7 @@ fn explainWhyTypeIsComptimeInner(
2676026520
2676126521 if (zcu.typeToStruct(ty)) |struct_type| {
2676226522 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]);
2676426524 const field_src: LazySrcLoc = .{
2676526525 .base_node_inst = struct_type.zir_index,
2676626526 .offset = .{ .container_field_type = @intCast(i) },
......@@ -26780,7 +26540,7 @@ fn explainWhyTypeIsComptimeInner(
2678026540
2678126541 if (zcu.typeToUnion(ty)) |union_obj| {
2678226542 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]);
2678426544 const field_src: LazySrcLoc = .{
2678526545 .base_node_inst = union_obj.zir_index,
2678626546 .offset = .{ .container_field_type = @intCast(i) },
......@@ -27171,7 +26931,7 @@ fn addSafetyCheckUnwrapError(
2717126931
2717226932 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);
2717526935 try safetyPanicUnwrapError(sema, &fail_block, src, err);
2717626936
2717726937 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
......@@ -27344,7 +27104,7 @@ fn fieldVal(
2734427104 switch (inner_ty.zigTypeTag(zcu)) {
2734527105 .array => {
2734627106 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());
2734827108 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2734927109 const ptr_info = object_ty.ptrInfo(zcu);
2735027110 const result_ty = try pt.ptrTypeSema(.{
......@@ -27527,7 +27287,7 @@ fn fieldPtr(
2752727287 switch (inner_ty.zigTypeTag(zcu)) {
2752827288 .array => {
2752927289 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));
2753127291 return uavRef(sema, int_val.toIntern());
2753227292 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2753327293 const ptr_info = object_ty.ptrInfo(zcu);
......@@ -27769,12 +27529,12 @@ fn fieldCallBind(
2776927529 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
2777027530 const field_index = struct_type.nameIndex(ip, field_name) orelse
2777127531 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
2777427534 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
2777527535 } else if (concrete_ty.isTuple(zcu)) {
2777627536 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)) };
2777827538 }
2777927539 if (field_name.toUnsigned(ip)) |field_index| {
2778027540 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;
......@@ -27817,7 +27577,7 @@ fn fieldCallBind(
2781727577 if (zcu.typeToFunc(decl_type)) |func_type| f: {
2781827578 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]);
2782127581 if (first_param_type.isGenericPoison() or
2782227582 (first_param_type.zigTypeTag(zcu) == .pointer and
2782327583 (first_param_type.ptrSize(zcu) == .one or
......@@ -28003,7 +27763,7 @@ fn structFieldPtr(
2800327763
2800427764 if (struct_ty.isTuple(zcu)) {
2800527765 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));
2800727767 return sema.analyzeRef(block, src, len_inst);
2800827768 }
2800927769 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
......@@ -28134,7 +27894,7 @@ fn structFieldVal(
2813427894 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
2813527895 }
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]);
2813827898 if (try sema.typeHasOnePossibleValue(field_ty)) |field_val|
2813927899 return Air.internedToRef(field_val.toIntern());
2814027900
......@@ -28167,7 +27927,7 @@ fn tupleFieldVal(
2816727927 const pt = sema.pt;
2816827928 const zcu = pt.zcu;
2816927929 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));
2817127931 }
2817227932 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);
2817327933 return sema.tupleFieldValByIndex(block, tuple_byval, field_index, tuple_ty);
......@@ -28220,7 +27980,7 @@ fn tupleFieldValByIndex(
2822027980 return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) {
2822127981 .undef => pt.undefRef(field_ty),
2822227982 .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)),
2822427984 .elems => |elems| Value.fromInterned(elems[field_index]),
2822527985 .repeated_elem => |elem| Value.fromInterned(elem),
2822627986 }.toIntern()),
......@@ -28253,7 +28013,7 @@ fn unionFieldPtr(
2825328013 try union_ty.resolveFields(pt);
2825428014 const union_obj = zcu.typeToUnion(union_ty).?;
2825528015 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]);
2825728017 const ptr_field_ty = try pt.ptrTypeSema(.{
2825828018 .child = field_ty.toIntern(),
2825928019 .flags = .{
......@@ -28295,8 +28055,8 @@ fn unionFieldPtr(
2829528055 break :ct;
2829628056 }
2829728057 // 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);
28299 const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28058 const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28059 const payload_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
2830028060 const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty));
2830128061 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);
2830228062 } else {
......@@ -28306,7 +28066,7 @@ fn unionFieldPtr(
2830628066 return sema.failWithUseOfUndef(block, src);
2830728067 }
2830828068 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);
2831028070 const tag_matches = un.tag == field_tag.toIntern();
2831128071 if (!tag_matches) {
2831228072 const msg = msg: {
......@@ -28332,11 +28092,11 @@ fn unionFieldPtr(
2833228092 if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
2833328093 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
2833428094 {
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);
2833628096 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
2833728097 // TODO would it be better if get_union_tag supported pointers to unions?
2833828098 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);
2834028100 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag);
2834128101 }
2834228102 if (field_ty.zigTypeTag(zcu) == .noreturn) {
......@@ -28363,14 +28123,14 @@ fn unionFieldVal(
2836328123 try union_ty.resolveFields(pt);
2836428124 const union_obj = zcu.typeToUnion(union_ty).?;
2836528125 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]);
2836728127 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);
2836828128
2836928129 if (try sema.resolveValue(union_byval)) |union_val| {
2837028130 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);
2837128131
2837228132 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);
2837428134 const tag_matches = un.tag == field_tag.toIntern();
2837528135 switch (union_obj.flagsUnordered(ip).layout) {
2837628136 .auto => {
......@@ -28408,9 +28168,9 @@ fn unionFieldVal(
2840828168 if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
2840928169 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
2841028170 {
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);
2841228172 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);
2841428174 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag);
2841528175 }
2841628176 if (field_ty.zigTypeTag(zcu) == .noreturn) {
......@@ -28540,7 +28300,7 @@ fn elemVal(
2854028300
2854128301 // TODO in case of a vector of pointers, we need to detect whether the element
2854228302 // 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
2854528305 switch (indexable_ty.zigTypeTag(zcu)) {
2854628306 .pointer => switch (indexable_ty.ptrSize(zcu)) {
......@@ -28795,7 +28555,7 @@ fn elemValArray(
2879528555 if (oob_safety and block.wantSafety()) {
2879628556 // Runtime check is only needed if unable to comptime check.
2879728557 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);
2879928559 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;
2880028560 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
2880128561 }
......@@ -28860,7 +28620,7 @@ fn elemPtrArray(
2886028620
2886128621 // Runtime check is only needed if unable to comptime check.
2886228622 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);
2886428624 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
2886528625 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
2886628626 }
......@@ -28917,9 +28677,9 @@ fn elemValSlice(
2891728677
2891828678 if (oob_safety and block.wantSafety()) {
2891928679 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))
2892128681 else
28922 try block.addTyOp(.slice_len, Type.usize, slice);
28682 try block.addTyOp(.slice_len, .usize, slice);
2892328683 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
2892428684 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
2892528685 }
......@@ -28976,8 +28736,8 @@ fn elemPtrSlice(
2897628736 const len_inst = len: {
2897728737 if (maybe_undef_slice_val) |slice_val|
2897828738 if (!slice_val.isUndef(zcu))
28979 break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt));
28980 break :len try block.addTyOp(.slice_len, Type.usize, slice);
28739 break :len try pt.intRef(.usize, try slice_val.sliceLen(pt));
28740 break :len try block.addTyOp(.slice_len, .usize, slice);
2898128741 };
2898228742 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
2898328743 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
......@@ -29142,7 +28902,7 @@ fn coerceExtra(
2914228902 if (!inst_ty.isSinglePointer(zcu)) break :single_item;
2914328903 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2914428904 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);
2914628906 if (array_ty.zigTypeTag(zcu) != .array) break :single_item;
2914728907 const array_elem_ty = array_ty.childType(zcu);
2914828908 if (array_ty.arrayLen(zcu) != 1) break :single_item;
......@@ -29164,7 +28924,7 @@ fn coerceExtra(
2916428924 const array_elem_type = array_ty.childType(zcu);
2916528925 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);
2916828928 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);
2916928929 switch (elem_res) {
2917028930 .ok => {},
......@@ -29225,7 +28985,7 @@ fn coerceExtra(
2922528985 // could be null.
2922628986 const src_elem_ty = inst_ty.childType(zcu);
2922728987 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);
2922928989 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) {
2923028990 .ok => {},
2923128991 else => break :src_c_ptr,
......@@ -29265,16 +29025,16 @@ fn coerceExtra(
2926529025 .byte_offset = 0,
2926629026 } })),
2926729027 .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) {
2926929029 error.NotCoercible => break :pointer,
2927029030 else => |e| return e,
2927129031 };
2927229032 return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src);
2927329033 },
2927429034 .int => {
29275 const ptr_size_ty = switch (inst_ty.intInfo(zcu).signedness) {
29276 .signed => Type.isize,
29277 .unsigned => Type.usize,
29035 const ptr_size_ty: Type = switch (inst_ty.intInfo(zcu).signedness) {
29036 .signed => .isize,
29037 .unsigned => .usize,
2927829038 };
2927929039 const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
2928029040 error.NotCoercible => {
......@@ -29291,8 +29051,8 @@ fn coerceExtra(
2929129051 const inst_info = inst_ty.ptrInfo(zcu);
2929229052 switch (try sema.coerceInMemoryAllowed(
2929329053 block,
29294 Type.fromInterned(dest_info.child),
29295 Type.fromInterned(inst_info.child),
29054 .fromInterned(dest_info.child),
29055 .fromInterned(inst_info.child),
2929629056 !dest_info.flags.is_const,
2929729057 target,
2929829058 dest_ty_src,
......@@ -29305,7 +29065,7 @@ fn coerceExtra(
2930529065 if (inst_info.flags.size == .slice) {
2930629066 assert(dest_info.sentinel == .none);
2930729067 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())
2930929069 break :p;
2931029070
2931129071 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -29364,8 +29124,8 @@ fn coerceExtra(
2936429124
2936529125 switch (try sema.coerceInMemoryAllowed(
2936629126 block,
29367 Type.fromInterned(dest_info.child),
29368 Type.fromInterned(inst_info.child),
29127 .fromInterned(dest_info.child),
29128 .fromInterned(inst_info.child),
2936929129 !dest_info.flags.is_const,
2937029130 target,
2937129131 dest_ty_src,
......@@ -29378,7 +29138,7 @@ fn coerceExtra(
2937829138
2937929139 if (dest_info.sentinel == .none or inst_info.sentinel == .none or
2938029140 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)))
2938229142 break :p;
2938329143
2938429144 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -30658,8 +30418,8 @@ fn coerceInMemoryAllowedPtrs(
3065830418 } };
3065930419 }
3066030420
30661 const dest_child = Type.fromInterned(dest_info.child);
30662 const src_child = Type.fromInterned(src_info.child);
30421 const dest_child: Type = .fromInterned(dest_info.child);
30422 const src_child: Type = .fromInterned(src_info.child);
3066330423 const child = try sema.coerceInMemoryAllowed(
3066430424 block,
3066530425 dest_child,
......@@ -30731,7 +30491,7 @@ fn coerceInMemoryAllowedPtrs(
3073130491 .none => Value.@"unreachable",
3073230492 else => Value.fromInterned(dest_info.sentinel),
3073330493 },
30734 .ty = Type.fromInterned(dest_info.child),
30494 .ty = .fromInterned(dest_info.child),
3073530495 } };
3073630496 }
3073730497
......@@ -30794,8 +30554,8 @@ fn coerceVarArgParam(
3079430554 const inst_bits = uncasted_ty.floatBits(target);
3079530555 if (inst_bits >= double_bits) break :float inst;
3079630556 switch (double_bits) {
30797 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),
30798 64 => break :float try sema.coerce(block, Type.f64, inst, inst_src),
30557 32 => break :float try sema.coerce(block, .f32, inst, inst_src),
30558 64 => break :float try sema.coerce(block, .f64, inst, inst_src),
3079930559 else => unreachable,
3080030560 }
3080130561 },
......@@ -30807,22 +30567,22 @@ fn coerceVarArgParam(
3080730567 .signed => .int,
3080830568 .unsigned => .uint,
3080930569 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
30810 .signed => Type.c_int,
30811 .unsigned => Type.c_uint,
30570 .signed => .c_int,
30571 .unsigned => .c_uint,
3081230572 }, inst, inst_src);
3081330573 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
3081430574 .signed => .long,
3081530575 .unsigned => .ulong,
3081630576 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
30817 .signed => Type.c_long,
30818 .unsigned => Type.c_ulong,
30577 .signed => .c_long,
30578 .unsigned => .c_ulong,
3081930579 }, inst, inst_src);
3082030580 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
3082130581 .signed => .longlong,
3082230582 .unsigned => .ulonglong,
3082330583 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
30824 .signed => Type.c_longlong,
30825 .unsigned => Type.c_ulonglong,
30584 .signed => .c_longlong,
30585 .unsigned => .c_ulonglong,
3082630586 }, inst, inst_src);
3082730587 break :int inst;
3082830588 } else inst,
......@@ -30889,7 +30649,7 @@ fn storePtr2(
3088930649 while (i < field_count) : (i += 1) {
3089030650 const elem_src = operand_src; // TODO better source location
3089130651 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);
3089330653 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true);
3089430654 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
3089530655 }
......@@ -31216,7 +30976,7 @@ fn coerceArrayPtrToSlice(
3121630976 const slice_val = try pt.intern(.{ .slice = .{
3121730977 .ty = dest_ty.toIntern(),
3121830978 .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(),
3122030980 } });
3122130981 return Air.internedToRef(slice_val);
3122230982 }
......@@ -31358,7 +31118,7 @@ fn coerceEnumToUnion(
3135831118 };
3135931119
3136031120 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]);
3136231122 try field_ty.resolveFields(pt);
3136331123 if (field_ty.zigTypeTag(zcu) == .noreturn) {
3136431124 const msg = msg: {
......@@ -31448,7 +31208,7 @@ fn coerceEnumToUnion(
3144831208
3144931209 for (0..union_obj.field_types.len) |field_index| {
3145031210 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]);
3145231212 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;
3145331213 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{
3145431214 field_name.fmt(ip),
......@@ -31536,7 +31296,7 @@ fn coerceArrayLike(
3153631296 var runtime_src: ?LazySrcLoc = null;
3153731297
3153831298 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());
3154031300 const src = inst_src; // TODO better source location
3154131301 const elem_src = inst_src; // TODO better source location
3154231302 const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true);
......@@ -31668,7 +31428,7 @@ fn coerceTupleToArrayPtrs(
3166831428 const zcu = pt.zcu;
3166931429 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
3167031430 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);
3167231432 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
3167331433 if (ptr_info.flags.alignment != .none) {
3167431434 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
......@@ -31721,14 +31481,14 @@ fn coerceTupleToTuple(
3172131481 const field_index: u32 = @intCast(field_index_usize);
3172231482
3172331483 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);
3172531485 field_refs[field_index] = coerced;
3172631486 if (default_val != .none) {
3172731487 const init_val = (try sema.resolveValue(coerced)) orelse {
3172831488 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
3172931489 };
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)) {
3173231492 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
3173331493 }
3173431494 }
......@@ -31885,7 +31645,7 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index:
3188531645
3188631646fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3188731647 const pt = sema.pt;
31888 const ptr_anyopaque_ty = try pt.singleConstPtrType(Type.anyopaque);
31648 const ptr_anyopaque_ty = try pt.singleConstPtrType(.anyopaque);
3188931649 return Value.fromInterned(try pt.intern(.{ .opt = .{
3189031650 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
3189131651 .val = if (opt_val) |val| (try pt.getCoerced(
......@@ -32140,12 +31900,12 @@ fn analyzeSliceLen(
3214031900 const zcu = pt.zcu;
3214131901 if (try sema.resolveValue(slice_inst)) |slice_val| {
3214231902 if (slice_val.isUndef(zcu)) {
32143 return pt.undefRef(Type.usize);
31903 return .undef_usize;
3214431904 }
32145 return pt.intRef(Type.usize, try slice_val.sliceLen(pt));
31905 return pt.intRef(.usize, try slice_val.sliceLen(pt));
3214631906 }
3214731907 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);
3214931909}
3215031910
3215131911fn analyzeIsNull(
......@@ -32156,7 +31916,7 @@ fn analyzeIsNull(
3215631916) CompileError!Air.Inst.Ref {
3215731917 const pt = sema.pt;
3215831918 const zcu = pt.zcu;
32159 const result_ty = Type.bool;
31919 const result_ty: Type = .bool;
3216031920 if (try sema.resolveValue(operand)) |opt_val| {
3216131921 if (opt_val.isUndef(zcu)) {
3216231922 return pt.undefRef(result_ty);
......@@ -32224,7 +31984,7 @@ fn analyzeIsNonErrComptimeOnly(
3222431984 else => {},
3222531985 }
3222631986 } else if (operand == .undef) {
32227 return pt.undefRef(Type.bool);
31987 return .undef_bool;
3222831988 } else if (@intFromEnum(operand) < InternPool.static_len) {
3222931989 // None of the ref tags can be errors.
3223031990 return .bool_true;
......@@ -32308,14 +32068,7 @@ fn analyzeIsNonErrComptimeOnly(
3230832068 }
3230932069
3231032070 if (maybe_operand_val) |err_union| {
32311 if (err_union.isUndef(zcu)) {
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 }
32071 return if (err_union.isUndef(zcu)) .undef_bool else if (err_union.getErrorName(zcu) == .none) .bool_true else .bool_false;
3231932072 }
3232032073 return .none;
3232132074}
......@@ -32412,8 +32165,8 @@ fn analyzeSlice(
3241232165 );
3241332166
3241432167 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)) {
32416 if (try sema.compareScalar(start_value, .neq, Value.zero_comptime_int, Type.comptime_int)) {
32168 if (try sema.compareScalar(start_value, .neq, end_value, .comptime_int)) {
32169 if (try sema.compareScalar(start_value, .neq, Value.zero_comptime_int, .comptime_int)) {
3241732170 const msg = msg: {
3241832171 const msg = try sema.errMsg(start_src, bounds_error_message, .{});
3241932172 errdefer msg.destroy(sema.gpa);
......@@ -32429,7 +32182,7 @@ fn analyzeSlice(
3242932182 break :msg msg;
3243032183 };
3243132184 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)) {
3243332186 const msg = msg: {
3243432187 const msg = try sema.errMsg(end_src, bounds_error_message, .{});
3243532188 errdefer msg.destroy(sema.gpa);
......@@ -32447,7 +32200,7 @@ fn analyzeSlice(
3244732200 return sema.failWithOwnedErrorMsg(block, msg);
3244832201 }
3244932202 } 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)) {
3245132204 return sema.fail(
3245232205 block,
3245332206 end_src,
......@@ -32512,7 +32265,7 @@ fn analyzeSlice(
3251232265 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);
3251332266 } 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);
3251632269 const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
3251732270 const new_ptr_ty = sema.typeOf(new_ptr);
3251832271
......@@ -32523,20 +32276,20 @@ fn analyzeSlice(
3252332276 var end_is_len = uncasted_end_opt == .none;
3252432277 const end = e: {
3252532278 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
3252832281 if (!end_is_len) {
3252932282 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);
3253132284 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);
32533 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32285 break :end try sema.coerce(block, .usize, uncasted_end, end_src);
32286 } else try sema.coerce(block, .usize, uncasted_end_opt, end_src);
3253432287 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
3253532288 const len_s_val = try pt.intValue(
32536 Type.usize,
32289 .usize,
3253732290 array_ty.arrayLenIncludingSentinel(zcu),
3253832291 );
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))) {
3254032293 const sentinel_label: []const u8 = if (array_ty.sentinel(zcu) != null)
3254132294 " +1 (sentinel)"
3254232295 else
......@@ -32557,7 +32310,7 @@ fn analyzeSlice(
3255732310 // end_is_len is only true if we are NOT using the sentinel
3255832311 // length. For sentinel-length, we don't want the type to
3255932312 // contain the sentinel.
32560 if (end_val.eql(len_val, Type.usize, zcu)) {
32313 if (end_val.eql(len_val, .usize, zcu)) {
3256132314 end_is_len = true;
3256232315 }
3256332316 }
......@@ -32568,10 +32321,10 @@ fn analyzeSlice(
3256832321 } else if (slice_ty.isSlice(zcu)) {
3256932322 if (!end_is_len) {
3257032323 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);
3257232325 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);
32574 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32326 break :end try sema.coerce(block, .usize, uncasted_end, end_src);
32327 } else try sema.coerce(block, .usize, uncasted_end_opt, end_src);
3257532328 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
3257632329 if (try sema.resolveValue(ptr_or_slice)) |slice_val| {
3257732330 if (slice_val.isUndef(zcu)) {
......@@ -32580,8 +32333,8 @@ fn analyzeSlice(
3258032333 const has_sentinel = slice_ty.sentinel(zcu) != null;
3258132334 const slice_len = try slice_val.sliceLen(pt);
3258232335 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
32583 const slice_len_val_with_sentinel = try pt.intValue(Type.usize, len_plus_sent);
32584 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
32336 const slice_len_val_with_sentinel = try pt.intValue(.usize, len_plus_sent);
32337 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, .usize))) {
3258532338 const sentinel_label: []const u8 = if (has_sentinel)
3258632339 " +1 (sentinel)"
3258732340 else
......@@ -32602,8 +32355,8 @@ fn analyzeSlice(
3260232355 // If the slice has a sentinel, we consider end_is_len
3260332356 // is only true if it equals the length WITHOUT the
3260432357 // sentinel, so we don't add a sentinel type.
32605 const slice_len_val = try pt.intValue(Type.usize, slice_len);
32606 if (end_val.eql(slice_len_val, Type.usize, zcu)) {
32358 const slice_len_val = try pt.intValue(.usize, slice_len);
32359 if (end_val.eql(slice_len_val, .usize, zcu)) {
3260732360 end_is_len = true;
3260832361 }
3260932362 }
......@@ -32614,10 +32367,10 @@ fn analyzeSlice(
3261432367 }
3261532368 if (!end_is_len) {
3261632369 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);
3261832371 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);
32620 } else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32372 break :e try sema.coerce(block, .usize, uncasted_end, end_src);
32373 } else break :e try sema.coerce(block, .usize, uncasted_end_opt, end_src);
3262132374 }
3262232375 return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
3262332376 };
......@@ -32645,7 +32398,7 @@ fn analyzeSlice(
3264532398 // requirement: start <= end
3264632399 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
3264732400 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))) {
3264932402 return sema.fail(
3265032403 block,
3265132404 start_src,
......@@ -32715,7 +32468,7 @@ fn analyzeSlice(
3271532468 try sema.addSafetyCheckCall(block, src, ok, .@"panic.startGreaterThanEnd", &.{ start, end });
3271632469 }
3271732470 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)
3271932472 else
3272032473 try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false);
3272132474 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
......@@ -32753,9 +32506,9 @@ fn analyzeSlice(
3275332506
3275432507 bounds_check: {
3275532508 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))
3275732510 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);
3275932512 break :l if (slice_ty.sentinel(zcu) == null)
3276032513 slice_len_inst
3276132514 else
......@@ -32811,15 +32564,15 @@ fn analyzeSlice(
3281132564
3281232565 // requirement: end <= len
3281332566 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))
3281532568 else if (slice_ty.isSlice(zcu)) blk: {
3281632569 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
3281732570 // we don't need to add one for sentinels because the
3281832571 // 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));
3282032573 }
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);
3282332576 if (slice_ty.sentinel(zcu) == null) break :blk slice_len_inst;
3282432577
3282532578 // we have to add one because slice lengths don't include the sentinel
......@@ -32935,8 +32688,8 @@ fn cmpNumeric(
3293532688 }
3293632689
3293732690 // 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);
32939 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(Type.bool);
32691 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
32692 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
3294032693
3294132694 const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: {
3294232695 if (maybe_rhs_val) |rhs_val| {
......@@ -33646,7 +33399,7 @@ fn resolvePeerTypes(
3364633399 candidate_srcs: PeerTypeCandidateSrc,
3364733400) !Type {
3364833401 switch (instructions.len) {
33649 0 => return Type.noreturn,
33402 0 => return .noreturn,
3365033403 1 => return sema.typeOf(instructions[0]),
3365133404 else => {},
3365233405 }
......@@ -33780,12 +33533,12 @@ fn resolvePeerTypesInner(
3378033533 .nullable => {
3378133534 for (peer_tys, 0..) |opt_ty, i| {
3378233535 const ty = opt_ty orelse continue;
33783 if (!ty.eql(Type.null, zcu)) return .{ .conflict = .{
33536 if (!ty.eql(.null, zcu)) return .{ .conflict = .{
3378433537 .peer_idx_a = strat_reason,
3378533538 .peer_idx_b = i,
3378633539 } };
3378733540 }
33788 return .{ .success = Type.null };
33541 return .{ .success = .null };
3378933542 },
3379033543
3379133544 .optional => {
......@@ -34006,7 +33759,7 @@ fn resolvePeerTypesInner(
3400633759 };
3400733760
3400833761 // 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 {
3401033763 return .{ .conflict = .{
3401133764 .peer_idx_a = first_idx,
3401233765 .peer_idx_b = i,
......@@ -34153,8 +33906,8 @@ fn resolvePeerTypesInner(
3415333906 };
3415433907
3415533908 // 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));
34157 const cur_pointee_array = sema.typeIsArrayLike(Type.fromInterned(ptr_info.child));
33909 const peer_pointee_array = sema.typeIsArrayLike(.fromInterned(peer_info.child));
33910 const cur_pointee_array = sema.typeIsArrayLike(.fromInterned(ptr_info.child));
3415833911
3415933912 // This switch is just responsible for deciding the size and pointee (not including
3416033913 // single-pointer array sentinel).
......@@ -34162,7 +33915,7 @@ fn resolvePeerTypesInner(
3416233915 switch (peer_info.flags.size) {
3416333916 .one => switch (ptr_info.flags.size) {
3416433917 .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| {
3416633919 ptr_info.child = pointee.toIntern();
3416733920 break :good;
3416833921 }
......@@ -34204,7 +33957,7 @@ fn resolvePeerTypesInner(
3420433957 .many => {
3420533958 // Only works for *[n]T + [*]T -> [*]T
3420633959 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| {
3420833961 ptr_info.child = pointee.toIntern();
3420933962 break :good;
3421033963 }
......@@ -34217,7 +33970,7 @@ fn resolvePeerTypesInner(
3421733970 .slice => {
3421833971 // Only works for *[n]T + []T -> []T
3421933972 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| {
3422133974 ptr_info.child = pointee.toIntern();
3422233975 break :good;
3422333976 }
......@@ -34233,7 +33986,7 @@ fn resolvePeerTypesInner(
3423333986 .one => {
3423433987 // Only works for [*]T + *[n]T -> [*]T
3423533988 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| {
3423733990 ptr_info.flags.size = .many;
3423833991 ptr_info.child = pointee.toIntern();
3423933992 break :good;
......@@ -34247,7 +34000,7 @@ fn resolvePeerTypesInner(
3424734000 return generic_err;
3424834001 },
3424934002 .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| {
3425134004 ptr_info.child = pointee.toIntern();
3425234005 break :good;
3425334006 }
......@@ -34262,7 +34015,7 @@ fn resolvePeerTypesInner(
3426234015 } };
3426334016 }
3426434017 // 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| {
3426634019 ptr_info.flags.size = .many;
3426734020 ptr_info.child = pointee.toIntern();
3426834021 break :good;
......@@ -34275,7 +34028,7 @@ fn resolvePeerTypesInner(
3427534028 .one => {
3427634029 // Only works for []T + *[n]T -> []T
3427734030 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| {
3427934032 ptr_info.flags.size = .slice;
3428034033 ptr_info.child = pointee.toIntern();
3428134034 break :good;
......@@ -34293,7 +34046,7 @@ fn resolvePeerTypesInner(
3429334046 return generic_err;
3429434047 },
3429534048 .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| {
3429734050 ptr_info.child = pointee.toIntern();
3429834051 break :good;
3429934052 }
......@@ -34479,7 +34232,7 @@ fn resolvePeerTypesInner(
3447934232 } },
3448034233 }
3448134234 }
34482 return .{ .success = Type.comptime_int };
34235 return .{ .success = .comptime_int };
3448334236 },
3448434237
3448534238 .comptime_float => {
......@@ -34493,7 +34246,7 @@ fn resolvePeerTypesInner(
3449334246 } },
3449434247 }
3449534248 }
34496 return .{ .success = Type.comptime_float };
34249 return .{ .success = .comptime_float };
3449734250 },
3449834251
3449934252 .fixed_int => {
......@@ -34601,11 +34354,11 @@ fn resolvePeerTypesInner(
3460134354 // Recreate the type so we eliminate any c_longdouble
3460234355 const bits = @max(cur_ty.floatBits(target), ty.floatBits(target));
3460334356 opt_cur_ty = switch (bits) {
34604 16 => Type.f16,
34605 32 => Type.f32,
34606 64 => Type.f64,
34607 80 => Type.f80,
34608 128 => Type.f128,
34357 16 => .f16,
34358 32 => .f32,
34359 64 => .f64,
34360 80 => .f80,
34361 128 => .f128,
3460934362 else => unreachable,
3461034363 };
3461134364 } else {
......@@ -34716,7 +34469,7 @@ fn resolvePeerTypesInner(
3471634469 break;
3471734470 };
3471834471 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) {
3472034473 // 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
3472134474 error.NotCoercible => {
3472234475 comptime_val = null;
......@@ -34729,7 +34482,7 @@ fn resolvePeerTypesInner(
3472934482 comptime_val = coerced_val;
3473034483 continue;
3473134484 };
34732 if (!coerced_val.eql(existing, Type.fromInterned(field_ty.*), zcu)) {
34485 if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) {
3473334486 comptime_val = null;
3473434487 break;
3473534488 }
......@@ -34743,7 +34496,7 @@ fn resolvePeerTypesInner(
3474334496 .values = field_vals,
3474434497 });
3474534498
34746 return .{ .success = Type.fromInterned(final_ty) };
34499 return .{ .success = .fromInterned(final_ty) };
3474734500 },
3474834501
3474934502 .exact => {
......@@ -34813,7 +34566,7 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
3481334566 const field_count = ty.structFieldCount(zcu);
3481434567 if (field_count == 0) return .{
3481534568 .len = 0,
34816 .elem_ty = Type.noreturn,
34569 .elem_ty = .noreturn,
3481734570 };
3481834571 if (!ty.isTuple(zcu)) return null;
3481934572 const elem_ty = ty.fieldType(0, zcu);
......@@ -34902,7 +34655,7 @@ pub fn resolveStructAlignment(
3490234655 var alignment: Alignment = .@"1";
3490334656
3490434657 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]);
3490634659 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt))
3490734660 continue;
3490834661 const field_align = try field_ty.structFieldAlignmentSema(
......@@ -34953,7 +34706,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3495334706 var big_align: Alignment = .@"1";
3495434707
3495534708 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]);
3495734710 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) {
3495834711 struct_type.offsets.get(ip)[i] = 0;
3495934712 field_size.* = 0;
......@@ -35001,7 +34754,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3500134754 const runtime_order = struct_type.runtime_order.get(ip);
3500234755
3500334756 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]);
3500534758 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) {
3500634759 ro.* = .omitted;
3500734760 } else {
......@@ -35095,7 +34848,7 @@ fn backingIntType(
3509534848 const fields_bit_sum = blk: {
3509634849 var accumulator: u64 = 0;
3509734850 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]);
3509934852 accumulator += try field_ty.bitSizeSema(pt);
3510034853 }
3510134854 break :blk accumulator;
......@@ -35234,7 +34987,7 @@ pub fn resolveUnionAlignment(
3523434987
3523534988 var max_align: Alignment = .@"1";
3523634989 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]);
3523834991 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;
3523934992
3524034993 const explicit_align = union_type.fieldAlign(ip, field_index);
......@@ -35282,7 +35035,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3528235035 var max_size: u64 = 0;
3528335036 var max_align: Alignment = .@"1";
3528435037 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
3528735040 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 {
3530735060 const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and
3530835061 try Type.fromInterned(union_type.enum_tag_ty).hasRuntimeBitsSema(pt);
3530935062 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);
3531135064 const tag_align = try enum_tag_type.abiAlignmentSema(pt);
3531235065 const tag_size = try enum_tag_type.abiSizeSema(pt);
3531335066
......@@ -35392,7 +35145,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3539235145 // See also similar code for unions.
3539335146
3539435147 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]);
3539635149 try field_ty.resolveFully(pt);
3539735150 }
3539835151}
......@@ -35421,7 +35174,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
3542135174
3542235175 union_obj.setStatus(ip, .fully_resolved_wip);
3542335176 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]);
3542535178 try field_ty.resolveFully(pt);
3542635179 }
3542735180 union_obj.setStatus(ip, .fully_resolved);
......@@ -35553,7 +35306,7 @@ fn resolveInferredErrorSet(
3555335306 // set. However, in the case of comptime/inline function calls with
3555435307 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
3555535308 // 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)).?;
3555735310 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
3555835311 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
3555935312 // so here we can simply skip this case.
......@@ -36008,7 +35761,7 @@ fn structFieldInits(
3600835761 // In init bodies, the zir index of the struct itself is used
3600935762 // 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]);
3601235765 const type_ref = Air.internedToRef(field_ty.toIntern());
3601335766 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index});
3601435767 sema.inst_map.putAssumeCapacity(zir_index, type_ref);
......@@ -36135,7 +35888,7 @@ fn unionFields(
3613535888 }
3613635889
3613735890 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);
3613935892 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
3614035893 const msg = msg: {
3614135894 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
......@@ -36288,9 +36041,9 @@ fn unionFields(
3628836041 }
3628936042
3629036043 const field_ty: Type = if (!has_type)
36291 Type.void
36044 .void
3629236045 else if (field_type_ref == .none)
36293 Type.noreturn
36046 .noreturn
3629436047 else
3629536048 try sema.resolveType(&block_scope, type_src, field_type_ref);
3629636049
......@@ -36388,11 +36141,11 @@ fn unionFields(
3638836141
3638936142 for (tag_info.names.get(ip), 0..) |field_name, field_index| {
3639036143 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", .{
3639236145 field_name.fmt(ip),
3639336146 });
3639436147 }
36395 try sema.addDeclaredHereNote(msg, Type.fromInterned(tag_ty));
36148 try sema.addDeclaredHereNote(msg, .fromInterned(tag_ty));
3639636149 break :msg msg;
3639736150 };
3639836151 return sema.failWithOwnedErrorMsg(&block_scope, msg);
......@@ -36530,10 +36283,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3653036283 .comptime_int_type,
3653136284 .comptime_float_type,
3653236285 .enum_literal_type,
36286 .ptr_usize_type,
36287 .ptr_const_comptime_int_type,
3653336288 .manyptr_u8_type,
3653436289 .manyptr_const_u8_type,
3653536290 .manyptr_const_u8_sentinel_0_type,
36536 .single_const_pointer_to_comptime_int_type,
3653736291 .slice_const_u8_type,
3653836292 .slice_const_u8_sentinel_0_type,
3653936293 .vector_8_i8_type,
......@@ -36595,11 +36349,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3659536349 .empty_tuple_type => Value.empty_tuple,
3659636350 // values, not types
3659736351 .undef,
36352 .undef_bool,
36353 .undef_usize,
36354 .undef_u1,
3659836355 .zero,
3659936356 .zero_usize,
36357 .zero_u1,
3660036358 .zero_u8,
3660136359 .one,
3660236360 .one_usize,
36361 .one_u1,
3660336362 .one_u8,
3660436363 .four_u8,
3660536364 .negative_one,
......@@ -36705,7 +36464,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3670536464 .storage = .{ .elems = &.{} },
3670636465 } }));
3670736466
36708 if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {
36467 if (try sema.typeHasOnePossibleValue(.fromInterned(seq_type.child))) |opv| {
3670936468 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3671036469 .ty = ty.toIntern(),
3671136470 .storage = .{ .repeated_elem = opv.toIntern() },
......@@ -36740,7 +36499,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3674036499 field_val.* = struct_type.field_inits.get(ip)[i];
3674136500 continue;
3674236501 }
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]);
3674436503 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
3674536504 field_val.* = field_opv.toIntern();
3674636505 } else return null;
......@@ -36773,13 +36532,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3677336532 try ty.resolveLayout(pt);
3677436533
3677536534 const union_obj = ip.loadUnionType(ty.toIntern());
36776 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse
36535 const tag_val = (try sema.typeHasOnePossibleValue(.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse
3677736536 return null;
3677836537 if (union_obj.field_types.len == 0) {
3677936538 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
3678036539 return Value.fromInterned(only);
3678136540 }
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]);
3678336542 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
3678436543 return null;
3678536544 const only = try pt.internUnion(.{
......@@ -36796,7 +36555,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3679636555 .nonexhaustive => {
3679736556 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| {
3680036559 const only = try pt.intern(.{ .enum_tag = .{
3680136560 .ty = ty.toIntern(),
3680236561 .int = int_opv.toIntern(),
......@@ -36814,7 +36573,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3681436573 1 => try pt.intern(.{ .enum_tag = .{
3681536574 .ty = ty.toIntern(),
3681636575 .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()
3681836577 else
3681936578 try ip.getCoercedInts(
3682036579 zcu.gpa,
......@@ -37041,7 +36800,7 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3704136800 if (ptr_type.flags.is_allowzero) return null;
3704236801
3704336802 // 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);
3704536804 if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) {
3704636805 return null;
3704736806 }
......@@ -37175,7 +36934,7 @@ fn intFromFloatScalar(
3717536934 var big_int = try float128IntPartToBigInt(sema.arena, float);
3717636935 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
3718036939 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
3718136940 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 {
3727837037 assert(enum_type.tag_mode != .nonexhaustive);
3727937038 // The `tagValueIndex` function call below relies on the type being the integer tag type.
3728037039 // `getCoerced` assumes the value will fit the new type.
37281 if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false;
37282 const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty));
37040 if (!(try sema.intFitsInType(int, .fromInterned(enum_type.tag_ty), null))) return false;
37041 const int_coerced = try pt.getCoerced(int, .fromInterned(enum_type.tag_ty));
3728337042
3728437043 return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null;
3728537044}
......@@ -37359,7 +37118,7 @@ fn compareVector(
3735937118 const lhs_elem = try lhs.elemValue(pt, i);
3736037119 const rhs_elem = try rhs.elemValue(pt, i);
3736137120 if (lhs_elem.isUndef(zcu) or rhs_elem.isUndef(zcu)) {
37362 scalar.* = try pt.intern(.{ .undef = .bool_type });
37121 scalar.* = .undef_bool;
3736337122 } else {
3736437123 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(zcu));
3736537124 scalar.* = Value.makeBool(res_bool).toIntern();
......@@ -37826,7 +37585,7 @@ pub fn resolveDeclaredEnum(
3782637585 .owner = .wrap(.{ .type = wip_ty.index }),
3782737586 .func_index = .none,
3782837587 .func_is_naked = false,
37829 .fn_ret_ty = Type.void,
37588 .fn_ret_ty = .void,
3783037589 .fn_ret_ty_ies = null,
3783137590 .comptime_err_ret_trace = &comptime_err_ret_trace,
3783237591 };
......@@ -37999,7 +37758,7 @@ fn resolveDeclaredEnumInner(
3799937758 break :overflow false;
3800037759 } else overflow: {
3800137760 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);
3800337762 if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true;
3800437763 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
3800537764 break :overflow false;
......@@ -38222,8 +37981,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
3822237981 .@"panic.castToNull",
3822337982 .@"panic.incorrectAlignment",
3822437983 .@"panic.invalidErrorCode",
38225 .@"panic.castTruncatedData",
38226 .@"panic.negativeToUnsigned",
37984 .@"panic.integerOutOfBounds",
3822737985 .@"panic.integerOverflow",
3822837986 .@"panic.shlOverflow",
3822937987 .@"panic.shrOverflow",
src/Sema/arith.zig+6-6
......@@ -168,7 +168,7 @@ fn addWithOverflowScalar(
168168 else => unreachable,
169169 }
170170 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{
171 .overflow_bit = try pt.undefValue(.u1),
171 .overflow_bit = .undef_u1,
172172 .wrapped_result = try pt.undefValue(ty),
173173 };
174174 return intAddWithOverflow(sema, lhs, rhs, ty);
......@@ -229,7 +229,7 @@ fn subWithOverflowScalar(
229229 else => unreachable,
230230 }
231231 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{
232 .overflow_bit = try pt.undefValue(.u1),
232 .overflow_bit = .undef_u1,
233233 .wrapped_result = try pt.undefValue(ty),
234234 };
235235 return intSubWithOverflow(sema, lhs, rhs, ty);
......@@ -290,7 +290,7 @@ fn mulWithOverflowScalar(
290290 else => unreachable,
291291 }
292292 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return .{
293 .overflow_bit = try pt.undefValue(.u1),
293 .overflow_bit = .undef_u1,
294294 .wrapped_result = try pt.undefValue(ty),
295295 };
296296 return intMulWithOverflow(sema, lhs, rhs, ty);
......@@ -1043,7 +1043,7 @@ fn comptimeIntAdd(sema: *Sema, lhs: Value, rhs: Value) !Value {
10431043fn intAddWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {
10441044 switch (ty.toIntern()) {
10451045 .comptime_int_type => return .{
1046 .overflow_bit = try sema.pt.intValue(.u1, 0),
1046 .overflow_bit = .zero_u1,
10471047 .wrapped_result = try comptimeIntAdd(sema, lhs, rhs),
10481048 },
10491049 else => return intAddWithOverflowInner(sema, lhs, rhs, ty),
......@@ -1125,7 +1125,7 @@ fn comptimeIntSub(sema: *Sema, lhs: Value, rhs: Value) !Value {
11251125fn intSubWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {
11261126 switch (ty.toIntern()) {
11271127 .comptime_int_type => return .{
1128 .overflow_bit = try sema.pt.intValue(.u1, 0),
1128 .overflow_bit = .zero_u1,
11291129 .wrapped_result = try comptimeIntSub(sema, lhs, rhs),
11301130 },
11311131 else => return intSubWithOverflowInner(sema, lhs, rhs, ty),
......@@ -1211,7 +1211,7 @@ fn comptimeIntMul(sema: *Sema, lhs: Value, rhs: Value) !Value {
12111211fn intMulWithOverflow(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value.OverflowArithmeticResult {
12121212 switch (ty.toIntern()) {
12131213 .comptime_int_type => return .{
1214 .overflow_bit = try sema.pt.intValue(.u1, 0),
1214 .overflow_bit = .zero_u1,
12151215 .wrapped_result = try comptimeIntMul(sema, lhs, rhs),
12161216 },
12171217 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 {
26412641 if (enum_type.values.len == 0) {
26422642 const only = try pt.intern(.{ .enum_tag = .{
26432643 .ty = ty.toIntern(),
2644 .int = try pt.intern(.{ .int = .{
2645 .ty = enum_type.tag_ty,
2646 .storage = .{ .u64 = 0 },
2647 } }),
2644 .int = (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern(),
26482645 } });
26492646 return Value.fromInterned(only);
26502647 } else {
......@@ -3676,10 +3673,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
36763673 .null_type,
36773674 .undefined_type,
36783675 .enum_literal_type,
3676 .ptr_usize_type,
3677 .ptr_const_comptime_int_type,
36793678 .manyptr_u8_type,
36803679 .manyptr_const_u8_type,
36813680 .manyptr_const_u8_sentinel_0_type,
3682 .single_const_pointer_to_comptime_int_type,
36833681 .slice_const_u8_type,
36843682 .slice_const_u8_sentinel_0_type,
36853683 .optional_noreturn_type,
......@@ -3691,9 +3689,11 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
36913689 .undef => unreachable,
36923690 .zero => unreachable,
36933691 .zero_usize => unreachable,
3692 .zero_u1 => unreachable,
36943693 .zero_u8 => unreachable,
36953694 .one => unreachable,
36963695 .one_usize => unreachable,
3696 .one_u1 => unreachable,
36973697 .one_u8 => unreachable,
36983698 .four_u8 => unreachable,
36993699 .negative_one => unreachable,
......@@ -4100,10 +4100,11 @@ pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type };
41004100pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type };
41014101pub 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 };
41034105pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type };
41044106pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };
41054107pub 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 };
41074108pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
41084109pub 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 {
28952895
28962896pub 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 };
28982903pub const zero_usize: Value = .{ .ip_index = .zero_usize };
2904pub const zero_u1: Value = .{ .ip_index = .zero_u1 };
28992905pub const zero_u8: Value = .{ .ip_index = .zero_u8 };
2900pub const zero_comptime_int: Value = .{ .ip_index = .zero };
29012906pub 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 };
29022911pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one };
2903pub const undef: Value = .{ .ip_index = .undef };
29042912pub const @"void": Value = .{ .ip_index = .void_value };
2913pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };
29052914pub const @"null": Value = .{ .ip_index = .null_value };
2906pub const @"false": Value = .{ .ip_index = .bool_false };
29072915pub const @"true": Value = .{ .ip_index = .bool_true };
2908pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };
2909
2910pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type };
2916pub const @"false": Value = .{ .ip_index = .bool_false };
29112917pub const empty_tuple: Value = .{ .ip_index = .empty_tuple };
29122918
29132919pub fn makeBool(x: bool) Value {
src/Zcu.zig+4-26
......@@ -441,8 +441,7 @@ pub const BuiltinDecl = enum {
441441 @"panic.castToNull",
442442 @"panic.incorrectAlignment",
443443 @"panic.invalidErrorCode",
444 @"panic.castTruncatedData",
445 @"panic.negativeToUnsigned",
444 @"panic.integerOutOfBounds",
446445 @"panic.integerOverflow",
447446 @"panic.shlOverflow",
448447 @"panic.shrOverflow",
......@@ -518,8 +517,7 @@ pub const BuiltinDecl = enum {
518517 .@"panic.castToNull",
519518 .@"panic.incorrectAlignment",
520519 .@"panic.invalidErrorCode",
521 .@"panic.castTruncatedData",
522 .@"panic.negativeToUnsigned",
520 .@"panic.integerOutOfBounds",
523521 .@"panic.integerOverflow",
524522 .@"panic.shlOverflow",
525523 .@"panic.shrOverflow",
......@@ -585,8 +583,7 @@ pub const SimplePanicId = enum {
585583 cast_to_null,
586584 incorrect_alignment,
587585 invalid_error_code,
588 cast_truncated_data,
589 negative_to_unsigned,
586 integer_out_of_bounds,
590587 integer_overflow,
591588 shl_overflow,
592589 shr_overflow,
......@@ -609,8 +606,7 @@ pub const SimplePanicId = enum {
609606 .cast_to_null => .@"panic.castToNull",
610607 .incorrect_alignment => .@"panic.incorrectAlignment",
611608 .invalid_error_code => .@"panic.invalidErrorCode",
612 .cast_truncated_data => .@"panic.castTruncatedData",
613 .negative_to_unsigned => .@"panic.negativeToUnsigned",
609 .integer_out_of_bounds => .@"panic.integerOutOfBounds",
614610 .integer_overflow => .@"panic.integerOverflow",
615611 .shl_overflow => .@"panic.shlOverflow",
616612 .shr_overflow => .@"panic.shrOverflow",
......@@ -3829,26 +3825,8 @@ pub const Feature = enum {
38293825 is_named_enum_value,
38303826 error_set_has_value,
38313827 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,
38413828 /// If the backend supports running from another thread.
38423829 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,
38523830};
38533831
38543832pub 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
17411741 return;
17421742 }
17431743
1744 const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
1745 try air.legalize(backend, zcu);
1744 legalize: {
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);
17481749 defer liveness.deinit(gpa);
17491750
17501751 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
17561757 if (std.debug.runtime_safety) {
17571758 var verify: Air.Liveness.Verify = .{
17581759 .gpa = gpa,
1760 .zcu = zcu,
17591761 .air = air.*,
17601762 .liveness = liveness,
17611763 .intern_pool = ip,
......@@ -3022,7 +3024,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
30223024 // is unused so it just has to be a no-op.
30233025 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
30243026 .tag = .alloc,
3025 .data = .{ .ty = Type.single_const_pointer_to_comptime_int },
3027 .data = .{ .ty = .ptr_const_comptime_int },
30263028 });
30273029 }
30283030
......@@ -3843,6 +3845,21 @@ pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {
38433845 } }));
38443846}
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
38463863pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type {
38473864 return pt.intType(.unsigned, Type.smallestUnsignedBits(max));
38483865}
src/arch/aarch64/CodeGen.zig+33-12
......@@ -40,6 +40,10 @@ const gp = abi.RegisterClass.gp;
4040
4141const InnerError = CodeGenError || error{OutOfRegisters};
4242
43pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
44 return null;
45}
46
4347gpa: Allocator,
4448pt: Zcu.PerThread,
4549air: Air,
......@@ -774,7 +778,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
774778 .error_name => try self.airErrorName(inst),
775779 .splat => try self.airSplat(inst),
776780 .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),
778783 .reduce => try self.airReduce(inst),
779784 .aggregate_init => try self.airAggregateInit(inst),
780785 .union_init => try self.airUnionInit(inst),
......@@ -2261,12 +2266,13 @@ fn shiftExact(
22612266 rhs_ty: Type,
22622267 maybe_inst: ?Air.Inst.Index,
22632268) InnerError!MCValue {
2264 _ = rhs_ty;
2265
22662269 const pt = self.pt;
22672270 const zcu = pt.zcu;
22682271 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", .{}),
22702276 .int => {
22712277 const int_info = lhs_ty.intInfo(zcu);
22722278 if (int_info.bits <= 64) {
......@@ -2317,7 +2323,10 @@ fn shiftNormal(
23172323 const pt = self.pt;
23182324 const zcu = pt.zcu;
23192325 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", .{}),
23212330 .int => {
23222331 const int_info = lhs_ty.intInfo(zcu);
23232332 if (int_info.bits <= 64) {
......@@ -2874,7 +2883,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void {
28742883 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu)));
28752884
28762885 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", .{}),
28782890 .int => {
28792891 const int_info = lhs_ty.intInfo(zcu);
28802892 if (int_info.bits <= 64) {
......@@ -2993,8 +3005,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void {
29933005}
29943006
29953007fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void {
3008 const zcu = self.pt.zcu;
29963009 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});
29983016 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
29993017}
30003018
......@@ -6032,11 +6050,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) InnerError!void {
60326050 return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
60336051}
60346052
6035fn airShuffle(self: *Self, inst: Air.Inst.Index) InnerError!void {
6036 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6037 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
6038 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for {}", .{self.target.cpu.arch});
6039 return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
6053fn airShuffleOne(self: *Self, inst: Air.Inst.Index) InnerError!void {
6054 _ = inst;
6055 return self.fail("TODO implement airShuffleOne for {}", .{self.target.cpu.arch});
6056}
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});
60406061}
60416062
60426063fn 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;
4141
4242const InnerError = CodeGenError || error{OutOfRegisters};
4343
44pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
45 return null;
46}
47
4448gpa: Allocator,
4549pt: Zcu.PerThread,
4650air: Air,
......@@ -763,7 +767,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
763767 .error_name => try self.airErrorName(inst),
764768 .splat => try self.airSplat(inst),
765769 .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),
767772 .reduce => try self.airReduce(inst),
768773 .aggregate_init => try self.airAggregateInit(inst),
769774 .union_init => try self.airUnionInit(inst),
......@@ -1857,7 +1862,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
18571862 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu));
18581863
18591864 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", .{}),
18611869 .int => {
18621870 const int_info = lhs_ty.intInfo(zcu);
18631871 if (int_info.bits <= 32) {
......@@ -1978,8 +1986,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
19781986}
19791987
19801988fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
1989 const zcu = self.pt.zcu;
19811990 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});
19831997 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
19841998}
19851999
......@@ -3788,7 +3802,10 @@ fn shiftExact(
37883802 const pt = self.pt;
37893803 const zcu = pt.zcu;
37903804 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", .{}),
37923809 .int => {
37933810 const int_info = lhs_ty.intInfo(zcu);
37943811 if (int_info.bits <= 32) {
......@@ -3828,7 +3845,10 @@ fn shiftNormal(
38283845 const pt = self.pt;
38293846 const zcu = pt.zcu;
38303847 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", .{}),
38323852 .int => {
38333853 const int_info = lhs_ty.intInfo(zcu);
38343854 if (int_info.bits <= 32) {
......@@ -6002,10 +6022,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
60026022 return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
60036023}
60046024
6005fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
6006 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6007 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for arm", .{});
6008 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
6025fn airShuffleOne(self: *Self, inst: Air.Inst.Index) !void {
6026 _ = inst;
6027 return self.fail("TODO implement airShuffleOne for arm", .{});
6028}
6029
6030fn airShuffleTwo(self: *Self, inst: Air.Inst.Index) !void {
6031 _ = inst;
6032 return self.fail("TODO implement airShuffleTwo for arm", .{});
60096033}
60106034
60116035fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
src/arch/powerpc/CodeGen.zig+4
......@@ -10,6 +10,10 @@ const Zcu = @import("../../Zcu.zig");
1010const assert = std.debug.assert;
1111const log = std.log.scoped(.codegen);
1212
13pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
14 return null;
15}
16
1317pub fn generate(
1418 bin_file: *link.File,
1519 pt: Zcu.PerThread,
src/arch/riscv64/CodeGen.zig+34-7
......@@ -51,6 +51,15 @@ const Instruction = encoding.Instruction;
5151
5252const 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
5463pt: Zcu.PerThread,
5564air: Air,
5665liveness: Air.Liveness,
......@@ -1577,7 +1586,8 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
15771586 .error_name => try func.airErrorName(inst),
15781587 .splat => try func.airSplat(inst),
15791588 .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),
15811591 .reduce => try func.airReduce(inst),
15821592 .aggregate_init => try func.airAggregateInit(inst),
15831593 .union_init => try func.airUnionInit(inst),
......@@ -2764,6 +2774,7 @@ fn genBinOp(
27642774 .shl,
27652775 .shl_exact,
27662776 => {
2777 if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) return func.fail("TODO: vector shift with scalar rhs", .{});
27672778 if (bit_size > 64) return func.fail("TODO: genBinOp shift > 64 bits, {}", .{bit_size});
27682779 try func.truncateRegister(rhs_ty, rhs_reg);
27692780
......@@ -3248,8 +3259,14 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
32483259}
32493260
32503261fn airShlWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
3262 const zcu = func.pt.zcu;
32513263 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", .{});
32533270 return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
32543271}
32553272
......@@ -3266,8 +3283,14 @@ fn airMulSat(func: *Func, inst: Air.Inst.Index) !void {
32663283}
32673284
32683285fn airShlSat(func: *Func, inst: Air.Inst.Index) !void {
3286 const zcu = func.pt.zcu;
32693287 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", .{});
32713294 return func.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
32723295}
32733296
......@@ -8008,10 +8031,14 @@ fn airSelect(func: *Func, inst: Air.Inst.Index) !void {
80088031 return func.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
80098032}
80108033
8011fn airShuffle(func: *Func, inst: Air.Inst.Index) !void {
8012 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8013 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement airShuffle for riscv64", .{});
8014 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
8034fn airShuffleOne(func: *Func, inst: Air.Inst.Index) !void {
8035 _ = inst;
8036 return func.fail("TODO implement airShuffleOne for riscv64", .{});
8037}
8038
8039fn airShuffleTwo(func: *Func, inst: Air.Inst.Index) !void {
8040 _ = inst;
8041 return func.fail("TODO implement airShuffleTwo for riscv64", .{});
80158042}
80168043
80178044fn airReduce(func: *Func, inst: Air.Inst.Index) !void {
src/arch/sparc64/CodeGen.zig+25-5
......@@ -41,6 +41,10 @@ const Self = @This();
4141
4242const InnerError = CodeGenError || error{OutOfRegisters};
4343
44pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
45 return null;
46}
47
4448const RegisterView = enum(u1) {
4549 caller,
4650 callee,
......@@ -617,7 +621,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
617621 .error_name => try self.airErrorName(inst),
618622 .splat => try self.airSplat(inst),
619623 .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)"),
621626 .reduce => @panic("TODO try self.airReduce(inst)"),
622627 .aggregate_init => try self.airAggregateInit(inst),
623628 .union_init => try self.airUnionInit(inst),
......@@ -2270,8 +2275,14 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
22702275}
22712276
22722277fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
2278 const zcu = self.pt.zcu;
22732279 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});
22752286 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
22762287}
22772288
......@@ -2287,7 +2298,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
22872298 const rhs_ty = self.typeOf(extra.rhs);
22882299
22892300 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", .{}),
22912305 .int => {
22922306 const int_info = lhs_ty.intInfo(zcu);
22932307 if (int_info.bits <= 64) {
......@@ -3002,7 +3016,10 @@ fn binOp(
30023016
30033017 // Truncate if necessary
30043018 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", .{}),
30063023 .int => {
30073024 const int_info = lhs_ty.intInfo(zcu);
30083025 if (int_info.bits <= 64) {
......@@ -3024,7 +3041,10 @@ fn binOp(
30243041 .shr_exact,
30253042 => {
30263043 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", .{}),
30283048 .int => {
30293049 const int_info = lhs_ty.intInfo(zcu);
30303050 if (int_info.bits <= 64) {
src/arch/wasm/CodeGen.zig+116-50
......@@ -31,6 +31,15 @@ const libcFloatSuffix = target_util.libcFloatSuffix;
3131const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;
3232const 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
3443/// Reference to the function declaration the code
3544/// section belongs to
3645owner_nav: InternPool.Nav.Index,
......@@ -1995,7 +2004,8 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19952004 .ret_load => cg.airRetLoad(inst),
19962005 .splat => cg.airSplat(inst),
19972006 .select => cg.airSelect(inst),
1998 .shuffle => cg.airShuffle(inst),
2007 .shuffle_one => cg.airShuffleOne(inst),
2008 .shuffle_two => cg.airShuffleTwo(inst),
19992009 .reduce => cg.airReduce(inst),
20002010 .aggregate_init => cg.airAggregateInit(inst),
20012011 .union_init => cg.airUnionInit(inst),
......@@ -2638,6 +2648,10 @@ fn airBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
26382648 // For big integers we can ignore this as we will call into compiler-rt which handles this.
26392649 const result = switch (op) {
26402650 .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
26412655 const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(zcu))) orelse {
26422656 return cg.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
26432657 };
......@@ -3055,8 +3069,12 @@ fn airWrapBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
30553069 const lhs_ty = cg.typeOf(bin_op.lhs);
30563070 const rhs_ty = cg.typeOf(bin_op.rhs);
30573071
3058 if (lhs_ty.zigTypeTag(zcu) == .vector or rhs_ty.zigTypeTag(zcu) == .vector) {
3059 return cg.fail("TODO: Implement wrapping arithmetic for vectors", .{});
3072 if (lhs_ty.isVector(zcu)) {
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 }
30603078 }
30613079
30623080 // For certain operations, such as shifting, the types are different.
......@@ -5160,66 +5178,105 @@ fn airSelect(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51605178 return cg.fail("TODO: Implement wasm airSelect", .{});
51615179}
51625180
5163fn airShuffle(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5181fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51645182 const pt = cg.pt;
51655183 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);
5171 const b = try cg.resolveInst(extra.b);
5172 const mask = Value.fromInterned(extra.mask);
5173 const mask_len = extra.mask_len;
5185 const unwrapped = cg.air.unwrapShuffleOne(zcu, inst);
5186 const result_ty = unwrapped.result_ty;
5187 const mask = unwrapped.mask;
5188 const operand = try cg.resolveInst(unwrapped.operand);
51745189
5175 const child_ty = inst_ty.childType(zcu);
5176 const elem_size = child_ty.abiSize(zcu);
5190 const elem_ty = result_ty.childType(zcu);
5191 const elem_size = elem_ty.abiSize(zcu);
51775192
5178 // TODO: One of them could be by ref; handle in loop
5179 if (isByRef(cg.typeOf(extra.a), zcu, cg.target) or isByRef(inst_ty, zcu, cg.target)) {
5180 const result = try cg.allocStack(inst_ty);
5193 // TODO: this function could have an `i8x16_shuffle` fast path like `airShuffleTwo` if we were
5194 // to lower the comptime-known operands to a non-by-ref vector value.
51815195
5182 for (0..mask_len) |index| {
5183 const value = (try mask.elemValue(pt, index)).toSignedInt(zcu);
5196 // TODO: this is incorrect if either operand or the result is *not* by-ref, which is possible.
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)
5188 try cg.load(a, child_ty, @as(u32, @intCast(@as(i64, @intCast(elem_size)) * value)))
5189 else
5190 try cg.load(b, child_ty, @as(u32, @intCast(@as(i64, @intCast(elem_size)) * ~value)));
5213fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5214 const pt = cg.pt;
5215 const zcu = pt.zcu;
51915216
5192 try cg.store(.stack, loaded, child_ty, result.stack_offset.value + @as(u32, @intCast(elem_size)) * @as(u32, @intCast(index)));
5193 }
5217 const unwrapped = cg.air.unwrapShuffleTwo(zcu, inst);
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 });
5196 } else {
5197 var operands = [_]u32{
5198 @intFromEnum(std.wasm.SimdOpcode.i8x16_shuffle),
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));
5223 const a_ty = cg.typeOf(unwrapped.operand_a);
5224 const b_ty = cg.typeOf(unwrapped.operand_b);
5225 const elem_ty = result_ty.childType(zcu);
5226 const elem_size = elem_ty.abiSize(zcu);
52085227
5209 for (0..@as(usize, @intCast(elem_size))) |byte_offset| {
5210 lanes[index * @as(usize, @intCast(elem_size)) + byte_offset] = base_index + @as(u8, @intCast(byte_offset));
5228 // WASM has `i8x16_shuffle`, which we can apply if the element type bit size is a multiple of 8
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);
52115247 }
52125248 }
5213
5214 try cg.emitWValue(a);
5215 try cg.emitWValue(b);
5216
5249 try cg.emitWValue(operand_a);
5250 try cg.emitWValue(operand_b);
52175251 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 });
52195259 try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
5220
5221 return cg.finishAir(inst, .stack, &.{ extra.a, extra.b });
5260 return cg.finishAir(inst, .stack, &.{ unwrapped.operand_a, unwrapped.operand_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));
52225278 }
5279 return cg.finishAir(inst, dest_alloc, &.{ unwrapped.operand_a, unwrapped.operand_b });
52235280}
52245281
52255282fn airReduce(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6067,13 +6124,17 @@ fn airShlWithOverflow(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
60676124 const ty = cg.typeOf(extra.lhs);
60686125 const rhs_ty = cg.typeOf(extra.rhs);
60696126
6070 if (ty.zigTypeTag(zcu) == .vector) {
6071 return cg.fail("TODO: Implement overflow arithmetic for vectors", .{});
6127 if (ty.isVector(zcu)) {
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 }
60726133 }
60736134
60746135 const int_info = ty.intInfo(zcu);
60756136 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});
60776138 };
60786139
60796140 // 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 {
69947055
69957056 const pt = cg.pt;
69967057 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
69977063 const ty = cg.typeOfIndex(inst);
69987064 const int_info = ty.intInfo(zcu);
69997065 const is_signed = int_info.signedness == .signed;
src/arch/x86_64/CodeGen.zig+461-137
......@@ -32,10 +32,79 @@ const FrameIndex = bits.FrameIndex;
3232
3333const InnerError = codegen.CodeGenError || error{OutOfRegisters};
3434
35pub const legalize_features: Air.Legalize.Features = .{
36 .remove_shift_vector_rhs_splat = false,
37 .reduce_one_elem_to_bitcast = true,
38};
35pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features {
36 @setEvalBranchQuota(1_200);
37 return switch (target.ofmt == .coff) {
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
40109/// Set this to `false` to uncover Sema OPV bugs.
41110/// https://github.com/ziglang/zig/issues/22419
......@@ -218,7 +287,7 @@ pub const MCValue = union(enum) {
218287 /// Payload is a frame address.
219288 lea_frame: bits.FrameAddr,
220289 /// 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 },
222291 /// This indicates that we have already allocated a frame index for this instruction,
223292 /// but it has not been spilled there yet in the current control flow.
224293 /// Payload is a frame index.
......@@ -240,7 +309,7 @@ pub const MCValue = union(enum) {
240309 .lea_direct,
241310 .lea_got,
242311 .lea_frame,
243 .elementwise_regs_then_frame,
312 .elementwise_args,
244313 .reserved_frame,
245314 .air_ref,
246315 => false,
......@@ -355,7 +424,7 @@ pub const MCValue = union(enum) {
355424 .lea_direct,
356425 .lea_got,
357426 .lea_frame,
358 .elementwise_regs_then_frame,
427 .elementwise_args,
359428 .reserved_frame,
360429 .air_ref,
361430 => unreachable, // not in memory
......@@ -389,7 +458,7 @@ pub const MCValue = union(enum) {
389458 .load_got,
390459 .load_frame,
391460 .load_symbol,
392 .elementwise_regs_then_frame,
461 .elementwise_args,
393462 .reserved_frame,
394463 .air_ref,
395464 => unreachable, // not dereferenceable
......@@ -409,7 +478,7 @@ pub const MCValue = union(enum) {
409478 .unreach,
410479 .dead,
411480 .undef,
412 .elementwise_regs_then_frame,
481 .elementwise_args,
413482 .reserved_frame,
414483 .air_ref,
415484 => unreachable, // not valid
......@@ -463,7 +532,7 @@ pub const MCValue = union(enum) {
463532 .load_got,
464533 .lea_got,
465534 .lea_frame,
466 .elementwise_regs_then_frame,
535 .elementwise_args,
467536 .reserved_frame,
468537 .lea_symbol,
469538 => unreachable,
......@@ -547,7 +616,7 @@ pub const MCValue = union(enum) {
547616 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
548617 .lea_got => |pl| try writer.print("got:{d}", .{pl}),
549618 .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}]", .{
551620 pl.regs, pl.frame_index, pl.frame_off,
552621 }),
553622 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
......@@ -580,7 +649,7 @@ const InstTracking = struct {
580649 .lea_symbol,
581650 => result,
582651 .dead,
583 .elementwise_regs_then_frame,
652 .elementwise_args,
584653 .reserved_frame,
585654 .air_ref,
586655 => unreachable,
......@@ -689,7 +758,7 @@ const InstTracking = struct {
689758 .register_overflow,
690759 .register_mask,
691760 .indirect,
692 .elementwise_regs_then_frame,
761 .elementwise_args,
693762 .air_ref,
694763 => unreachable,
695764 }
......@@ -2239,11 +2308,17 @@ fn gen(self: *CodeGen) InnerError!void {
22392308 try self.genBody(self.air.getMainBody());
22402309
22412310 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
2242 const epilogue_relocs_last_index = self.epilogue_relocs.items.len - 1;
2243 for (if (self.epilogue_relocs.items[epilogue_relocs_last_index] == self.mir_instructions.len - 1) epilogue_relocs: {
2244 _ = self.mir_instructions.pop();
2245 break :epilogue_relocs self.epilogue_relocs.items[0..epilogue_relocs_last_index];
2246 } else self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc);
2311 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);
2312 while (self.epilogue_relocs.getLastOrNull() == last_inst) {
2313 self.epilogue_relocs.items.len -= 1;
2314 self.mir_instructions.set(last_inst, .{
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
22482323 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
22492324 const backpatch_stack_dealloc = try self.asmPlaceholder();
......@@ -2430,7 +2505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24302505 switch (air_tags[@intFromEnum(inst)]) {
24312506 // zig fmt: off
24322507 .select => try cg.airSelect(inst),
2433 .shuffle => try cg.airShuffle(inst),
2508 .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),
24342509 // zig fmt: on
24352510
24362511 .arg => if (cg.debug_output != .none) {
......@@ -5714,7 +5789,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57145789 },
57155790 .extra_temps = .{
57165791 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
5717 .{ .type = .i64, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
5792 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
57185793 .unused,
57195794 .unused,
57205795 .unused,
......@@ -63352,14 +63427,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6335263427 defer assert(cg.loops.remove(inst));
6335363428 try cg.genBodyBlock(@ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len]));
6335463429 },
63355 .repeat => if (use_old) try cg.airRepeat(inst) else {
63430 .repeat => {
6335663431 const repeat = air_datas[@intFromEnum(inst)].repeat;
6335763432 const loop = cg.loops.get(repeat.loop_inst).?;
6335863433 try cg.restoreState(loop.state, &.{}, .{
6335963434 .emit_instructions = true,
6336063435 .update_tracking = false,
6336163436 .resurrect = false,
63362 .close_scope = true,
63437 .close_scope = false,
6336363438 });
6336463439 _ = try cg.asmJmpReloc(loop.target);
6336563440 },
......@@ -77234,11 +77309,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7723477309 },
7723577310 }
7723677311 },
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 },
7723877329 }) catch |err| switch (err) {
7723977330 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
7724077331 @tagName(air_tag),
77241 cg.typeOf(bin_op.lhs).fmt(pt),
77332 ty.fmt(pt),
7724277333 ops[0].tracking(cg),
7724377334 ops[1].tracking(cg),
7724477335 }),
......@@ -92468,7 +92559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9246892559 .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ },
9246992560 .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ },
9247092561 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
92471 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ },
92562 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ },
9247292563 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ },
9247392564 .{ ._, ._r, .sa, .tmp0q, .ui(63), ._, ._ },
9247492565 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ },
......@@ -92500,7 +92591,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9250092591 .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ },
9250192592 .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ },
9250292593 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
92503 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ },
92594 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ },
9250492595 .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ },
9250592596 .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ },
9250692597 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ },
......@@ -92534,7 +92625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9253492625 .{ ._, ._, .lea, .tmp1p, .mem(.dst0), ._, ._ },
9253592626 .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ },
9253692627 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
92537 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_size, -8), ._, ._ },
92628 .{ ._, ._, .mov, .tmp0q, .memad(.src0q, .add_dst0_size, -8), ._, ._ },
9253892629 .{ ._, ._l, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ },
9253992630 .{ ._, ._r, .sa, .tmp0q, .uia(64, .dst0, .sub_bit_size_rem_64), ._, ._ },
9254092631 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ },
......@@ -92595,7 +92686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9259592686 .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ },
9259692687 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
9259792688 .{ ._, ._, .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, ._ },
9259992690 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp2q, ._, ._ },
9260092691 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ },
9260192692 } },
......@@ -92627,7 +92718,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9262792718 .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ },
9262892719 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
9262992720 .{ ._, ._, .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, ._ },
9263192722 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
9263292723 } },
9263392724 }, .{
......@@ -92658,7 +92749,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9265892749 .{ ._, ._, .mov, .tmp2d, .sia(-2, .dst0, .add_size_div_8), ._, ._ },
9265992750 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
9266092751 .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ },
92661 .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_size, -16), ._, ._ },
92752 .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_dst0_size, -16), ._, ._ },
9266292753 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -16), .tmp0q, ._, ._ },
9266392754 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ },
9266492755 } },
......@@ -92690,7 +92781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9269092781 .{ ._, ._, .mov, .tmp2d, .sia(-1, .dst0, .add_size_div_8), ._, ._ },
9269192782 .{ ._, .@"rep _sq", .mov, ._, ._, ._, ._ },
9269292783 .{ ._, ._, .mov, .tmp0q, .ua(.dst0, .add_umax), ._, ._ },
92693 .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_size, -8), ._, ._ },
92784 .{ ._, ._, .@"and", .tmp0q, .memad(.src0q, .add_dst0_size, -8), ._, ._ },
9269492785 .{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp0q, ._, ._ },
9269592786 } },
9269692787 }, .{
......@@ -162356,6 +162447,136 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162356162447 .each = .{ .once = &.{
162357162448 .{ ._, ._, .mov, .leasi(.src0w, .@"2", .src1), .src2w, ._, ._ },
162358162449 } },
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 } },
162359162580 }, .{
162360162581 .src_constraints = .{ .any, .any, .{ .int = .dword } },
162361162582 .patterns = &.{
......@@ -162374,30 +162595,120 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162374162595 .each = .{ .once = &.{
162375162596 .{ ._, ._, .mov, .leasi(.src0d, .@"4", .src1), .src2d, ._, ._ },
162376162597 } },
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 } },
162377162634 }, .{
162378162635 .required_features = .{ .@"64bit", null, null, null },
162379 .dst_constraints = .{ .{ .int = .qword }, .any },
162636 .src_constraints = .{ .any, .any, .{ .int = .qword } },
162380162637 .patterns = &.{
162381 .{ .src = .{ .to_mem, .simm32, .simm32 } },
162382 .{ .src = .{ .to_mem, .simm32, .to_gpr } },
162638 .{ .src = .{ .to_gpr, .simm32, .simm32 } },
162639 .{ .src = .{ .to_gpr, .simm32, .to_gpr } },
162383162640 },
162384162641 .each = .{ .once = &.{
162385162642 .{ ._, ._, .mov, .leaa(.src0q, .add_src0_elem_size_mul_src1), .src2q, ._, ._ },
162386162643 } },
162387162644 }, .{
162388162645 .required_features = .{ .@"64bit", null, null, null },
162389 .dst_constraints = .{ .{ .int = .qword }, .any },
162646 .src_constraints = .{ .any, .any, .{ .int = .qword } },
162390162647 .patterns = &.{
162391 .{ .src = .{ .to_mem, .to_gpr, .simm32 } },
162392 .{ .src = .{ .to_mem, .to_gpr, .to_gpr } },
162648 .{ .src = .{ .to_gpr, .to_gpr, .simm32 } },
162649 .{ .src = .{ .to_gpr, .to_gpr, .to_gpr } },
162393162650 },
162394162651 .each = .{ .once = &.{
162395162652 .{ ._, ._, .mov, .leasi(.src0q, .@"8", .src1), .src2q, ._, ._ },
162396162653 } },
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 } },
162397162708 } }) catch |err| switch (err) {
162398162709 error.SelectFailed => {
162399162710 const elem_size = cg.typeOf(bin_op.rhs).abiSize(zcu);
162400 while (try ops[0].toBase(false, cg) or
162711 while (try ops[0].toRegClass(true, .general_purpose, cg) or
162401162712 try ops[1].toRegClass(true, .general_purpose, cg))
162402162713 {}
162403162714 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 {
162410162721 rhs_reg,
162411162722 .u(elem_size),
162412162723 );
162413 try cg.asmRegisterMemory(
162414 .{ ._, .lea },
162415 base_reg,
162416 try ops[0].tracking(cg).short.mem(cg, .{ .index = rhs_reg }),
162417 );
162724 try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{
162725 .base = .{ .reg = base_reg },
162726 .mod = .{ .rm = .{ .index = rhs_reg } },
162727 });
162418162728 } else if (elem_size > 8) {
162419162729 try cg.spillEflagsIfOccupied();
162420162730 try cg.asmRegisterImmediate(
......@@ -162422,20 +162732,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162422162732 rhs_reg,
162423162733 .u(std.math.log2_int(u64, elem_size)),
162424162734 );
162425 try cg.asmRegisterMemory(
162426 .{ ._, .lea },
162427 base_reg,
162428 try ops[0].tracking(cg).short.mem(cg, .{ .index = rhs_reg }),
162429 );
162430 } else try cg.asmRegisterMemory(
162431 .{ ._, .lea },
162432 base_reg,
162433 try ops[0].tracking(cg).short.mem(cg, .{
162735 try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{
162736 .base = .{ .reg = base_reg },
162737 .mod = .{ .rm = .{ .index = rhs_reg } },
162738 });
162739 } else try cg.asmRegisterMemory(.{ ._, .lea }, base_reg, .{
162740 .base = .{ .reg = base_reg },
162741 .mod = .{ .rm = .{
162434162742 .index = rhs_reg,
162435162743 .scale = .fromFactor(@intCast(elem_size)),
162436 }),
162437 );
162438 try ops[0].store(&ops[1], .{}, cg);
162744 } },
162745 });
162746 try ops[0].store(&ops[2], .{}, cg);
162439162747 },
162440162748 else => |e| return e,
162441162749 };
......@@ -165315,9 +165623,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
165315165623 .ty = mask_ty.toIntern(),
165316165624 .storage = .{ .elems = &([1]InternPool.Index{
165317165625 (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(),
165318 } ++ [1]InternPool.Index{
165319 (try pt.intValue(.u8, 0)).toIntern(),
165320 } ** 15) },
165626 } ++ [1]InternPool.Index{.zero_u8} ** 15) },
165321165627 } })));
165322165628 const mask_addr_reg = try self.copyToTmpRegister(.usize, mask_mcv.address());
165323165629 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
168138168444 .register_quadruple,
168139168445 .register_overflow,
168140168446 .register_mask,
168141 .elementwise_regs_then_frame,
168447 .elementwise_args,
168142168448 .reserved_frame,
168143168449 => unreachable, // not a valid pointer
168144168450 .immediate,
......@@ -168356,7 +168662,7 @@ fn store(
168356168662 .register_quadruple,
168357168663 .register_overflow,
168358168664 .register_mask,
168359 .elementwise_regs_then_frame,
168665 .elementwise_args,
168360168666 .reserved_frame,
168361168667 => unreachable, // not a valid pointer
168362168668 .immediate,
......@@ -168842,7 +169148,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv:
168842169148 .lea_direct,
168843169149 .lea_got,
168844169150 .lea_frame,
168845 .elementwise_regs_then_frame,
169151 .elementwise_args,
168846169152 .reserved_frame,
168847169153 .air_ref,
168848169154 => unreachable, // unmodifiable destination
......@@ -170513,7 +170819,7 @@ fn genBinOp(
170513170819 .load_got,
170514170820 .lea_got,
170515170821 .lea_frame,
170516 .elementwise_regs_then_frame,
170822 .elementwise_args,
170517170823 .reserved_frame,
170518170824 .air_ref,
170519170825 => unreachable,
......@@ -171696,7 +172002,7 @@ fn genBinOpMir(
171696172002 .lea_got,
171697172003 .lea_frame,
171698172004 .lea_symbol,
171699 .elementwise_regs_then_frame,
172005 .elementwise_args,
171700172006 .reserved_frame,
171701172007 .air_ref,
171702172008 => unreachable, // unmodifiable destination
......@@ -171732,7 +172038,7 @@ fn genBinOpMir(
171732172038 .undef,
171733172039 .register_overflow,
171734172040 .register_mask,
171735 .elementwise_regs_then_frame,
172041 .elementwise_args,
171736172042 .reserved_frame,
171737172043 => unreachable,
171738172044 .register,
......@@ -171892,7 +172198,7 @@ fn genBinOpMir(
171892172198 .undef,
171893172199 .register_overflow,
171894172200 .register_mask,
171895 .elementwise_regs_then_frame,
172201 .elementwise_args,
171896172202 .reserved_frame,
171897172203 .air_ref,
171898172204 => unreachable,
......@@ -171988,7 +172294,7 @@ fn genBinOpMir(
171988172294 .undef,
171989172295 .register_overflow,
171990172296 .register_mask,
171991 .elementwise_regs_then_frame,
172297 .elementwise_args,
171992172298 .reserved_frame,
171993172299 .air_ref,
171994172300 => unreachable,
......@@ -172119,7 +172425,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
172119172425 .lea_direct,
172120172426 .lea_got,
172121172427 .lea_frame,
172122 .elementwise_regs_then_frame,
172428 .elementwise_args,
172123172429 .reserved_frame,
172124172430 .air_ref,
172125172431 => unreachable, // unmodifiable destination
......@@ -172151,7 +172457,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
172151172457 .register_quadruple,
172152172458 .register_overflow,
172153172459 .register_mask,
172154 .elementwise_regs_then_frame,
172460 .elementwise_args,
172155172461 .reserved_frame,
172156172462 .air_ref,
172157172463 => unreachable,
......@@ -172271,7 +172577,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
172271172577 try self.genCopy(arg_ty, dst_mcv, src_mcv, .{});
172272172578 break :result dst_mcv;
172273172579 },
172274 .elementwise_regs_then_frame => |regs_frame_addr| {
172580 .elementwise_args => |regs_frame_addr| {
172275172581 try self.spillEflagsIfOccupied();
172276172582
172277172583 const fn_info = zcu.typeToFunc(self.fn_type).?;
......@@ -172375,7 +172681,7 @@ fn genLocalDebugInfo(
172375172681 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {
172376172682 switch (mcv) {
172377172683 .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,
172379172685 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),
172380172686 .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),
172381172687 .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),
......@@ -172398,7 +172704,7 @@ fn genLocalDebugInfo(
172398172704 },
172399172705 .dbg_var_ptr => switch (mcv) {
172400172706 else => unreachable,
172401 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
172707 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
172402172708 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{
172403172709 .base = .{ .frame = frame_addr.index },
172404172710 .mod = .{ .rm = .{
......@@ -172567,7 +172873,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
172567172873 try self.genCopy(arg_ty, dst_arg, src_arg, opts);
172568172874 try self.freeValue(src_arg);
172569172875 },
172570 .elementwise_regs_then_frame => |regs_frame_addr| {
172876 .elementwise_args => |regs_frame_addr| {
172571172877 const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
172572172878 const index_lock = self.register_manager.lockRegAssumeUnused(index_reg);
172573172879 defer self.register_manager.unlockReg(index_lock);
......@@ -172676,7 +172982,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
172676172982 .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{
172677172983 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
172678172984 }, .{}),
172679 .elementwise_regs_then_frame => |regs_frame_addr| {
172985 .elementwise_args => |regs_frame_addr| {
172680172986 const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{
172681172987 .base = .{ .reg = try self.copyToTmpRegister(
172682172988 .usize,
......@@ -173064,7 +173370,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
173064173370 .lea_got,
173065173371 .lea_frame,
173066173372 .lea_symbol,
173067 .elementwise_regs_then_frame,
173373 .elementwise_args,
173068173374 .reserved_frame,
173069173375 .air_ref,
173070173376 => unreachable,
......@@ -173119,7 +173425,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
173119173425 .lea_direct,
173120173426 .lea_got,
173121173427 .lea_frame,
173122 .elementwise_regs_then_frame,
173428 .elementwise_args,
173123173429 .reserved_frame,
173124173430 .air_ref,
173125173431 => unreachable,
......@@ -173524,7 +173830,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)
173524173830 .lea_direct,
173525173831 .lea_got,
173526173832 .lea_symbol,
173527 .elementwise_regs_then_frame,
173833 .elementwise_args,
173528173834 .reserved_frame,
173529173835 .air_ref,
173530173836 => unreachable,
......@@ -173868,17 +174174,23 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index
173868174174 var block_data = self.blocks.fetchRemove(inst).?;
173869174175 defer block_data.value.deinit(self.gpa);
173870174176 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);
173871174188 try self.restoreState(block_data.value.state, liveness.deaths, .{
173872174189 .emit_instructions = false,
173873174190 .update_tracking = true,
173874174191 .resurrect = true,
173875174192 .close_scope = true,
173876174193 });
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);
173882174194 }
173883174195
173884174196 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 {
174453174765 try self.freeValue(block_tracking.short);
174454174766}
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
174468174768fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
174469174769 @setEvalBranchQuota(1_100);
174470174770 const pt = self.pt;
......@@ -175587,7 +175887,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
175587175887 .lea_got,
175588175888 .lea_frame,
175589175889 .lea_symbol,
175590 .elementwise_regs_then_frame,
175890 .elementwise_args,
175591175891 .reserved_frame,
175592175892 .air_ref,
175593175893 => unreachable, // unmodifiable destination
......@@ -175598,7 +175898,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
175598175898 .dead,
175599175899 .undef,
175600175900 .register_overflow,
175601 .elementwise_regs_then_frame,
175901 .elementwise_args,
175602175902 .reserved_frame,
175603175903 => unreachable,
175604175904 .immediate,
......@@ -175776,7 +176076,7 @@ fn genSetReg(
175776176076 .none,
175777176077 .unreach,
175778176078 .dead,
175779 .elementwise_regs_then_frame,
176079 .elementwise_args,
175780176080 .reserved_frame,
175781176081 => unreachable,
175782176082 .undef => if (opts.safety) switch (dst_reg.class()) {
......@@ -176313,7 +176613,7 @@ fn genSetMem(
176313176613 .none,
176314176614 .unreach,
176315176615 .dead,
176316 .elementwise_regs_then_frame,
176616 .elementwise_args,
176317176617 .reserved_frame,
176318176618 => unreachable,
176319176619 .undef => if (opts.safety) try self.genInlineMemset(
......@@ -178566,10 +178866,10 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
178566178866 const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() });
178567178867 var mask_elems_buf: [32]InternPool.Index = undefined;
178568178868 const mask_elems = mask_elems_buf[0..vec_len];
178569 for (mask_elems, 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{
178570 .ty = mask_elem_ty.toIntern(),
178571 .storage = .{ .u64 = @as(u64, 1) << @intCast(bit) },
178572 } });
178869 for (mask_elems, 0..) |*elem, bit| elem.* = (try pt.intValue(
178870 mask_elem_ty,
178871 @as(u8, 1) << @truncate(bit),
178872 )).toIntern();
178573178873 const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{
178574178874 .ty = mask_ty.toIntern(),
178575178875 .storage = .{ .elems = mask_elems },
......@@ -179437,16 +179737,13 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {
179437179737 var lhs_mask_elems: [16]InternPool.Index = undefined;
179438179738 for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| {
179439179739 const elem_index = byte_index / elem_abi_size;
179440 lhs_mask_elem.* = try pt.intern(.{ .int = .{
179441 .ty = .u8_type,
179442 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
179443 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
179444 if (mask_elem < 0) break :elem 0b1_00_00000;
179445 const mask_elem_index: u31 = @intCast(mask_elem);
179446 const byte_off: u32 = @intCast(byte_index % elem_abi_size);
179447 break :elem @intCast(mask_elem_index * elem_abi_size + byte_off);
179448 } },
179449 } });
179740 lhs_mask_elem.* = (try pt.intValue(.u8, if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
179741 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
179742 if (mask_elem < 0) break :elem 0b1_00_00000;
179743 const mask_elem_index: u31 = @intCast(mask_elem);
179744 const byte_off: u32 = @intCast(byte_index % elem_abi_size);
179745 break :elem mask_elem_index * elem_abi_size + byte_off;
179746 })).toIntern();
179450179747 }
179451179748 const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
179452179749 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 {
179471179768 var rhs_mask_elems: [16]InternPool.Index = undefined;
179472179769 for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| {
179473179770 const elem_index = byte_index / elem_abi_size;
179474 rhs_mask_elem.* = try pt.intern(.{ .int = .{
179475 .ty = .u8_type,
179476 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
179477 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
179478 if (mask_elem >= 0) break :elem 0b1_00_00000;
179479 const mask_elem_index: u31 = @intCast(~mask_elem);
179480 const byte_off: u32 = @intCast(byte_index % elem_abi_size);
179481 break :elem @intCast(mask_elem_index * elem_abi_size + byte_off);
179482 } },
179483 } });
179771 rhs_mask_elem.* = (try pt.intValue(.u8, if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
179772 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
179773 if (mask_elem >= 0) break :elem 0b1_00_00000;
179774 const mask_elem_index: u31 = @intCast(~mask_elem);
179775 const byte_off: u32 = @intCast(byte_index % elem_abi_size);
179776 break :elem mask_elem_index * elem_abi_size + byte_off;
179777 })).toIntern();
179484179778 }
179485179779 const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
179486179780 const rhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{
......@@ -180611,7 +180905,7 @@ fn resolveCallingConventionValues(
180611180905
180612180906 result.stack_byte_count =
180613180907 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 = .{
180615180909 .regs = remaining_param_int_regs,
180616180910 .frame_off = @intCast(result.stack_byte_count),
180617180911 .frame_index = stack_frame_base,
......@@ -181236,7 +181530,7 @@ const Temp = struct {
181236181530 .load_got,
181237181531 .lea_got,
181238181532 .lea_frame,
181239 .elementwise_regs_then_frame,
181533 .elementwise_args,
181240181534 .reserved_frame,
181241181535 .air_ref,
181242181536 => false,
......@@ -181671,7 +181965,7 @@ const Temp = struct {
181671181965 .register_quadruple,
181672181966 .register_overflow,
181673181967 .register_mask,
181674 .elementwise_regs_then_frame,
181968 .elementwise_args,
181675181969 .reserved_frame,
181676181970 .air_ref,
181677181971 => unreachable, // not a valid pointer
......@@ -186395,19 +186689,46 @@ const Temp = struct {
186395186689 if (cg.reused_operands.isSet(op_index)) continue;
186396186690 try cg.processDeath(op_ref.toIndexAllowNone() orelse continue);
186397186691 }
186398 if (cg.liveness.isUnused(inst)) try temp.die(cg) else switch (temp.unwrap(cg)) {
186399 .ref, .err_ret_trace => {
186400 const result = try cg.allocRegOrMem(inst, true);
186401 try cg.genCopy(cg.typeOfIndex(inst), result, temp.tracking(cg).short, .{});
186402 tracking_log.debug("{} => {} (birth)", .{ inst, result });
186403 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result));
186404 },
186405 .temp => |temp_index| {
186406 const temp_tracking = temp_index.tracking(cg);
186407 tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short });
186408 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short));
186409 assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking));
186410 },
186692 if (cg.liveness.isUnused(inst)) try temp.die(cg) else {
186693 switch (temp.unwrap(cg)) {
186694 .ref, .err_ret_trace => {
186695 const temp_mcv = temp.tracking(cg).short;
186696 const result = result: switch (temp_mcv) {
186697 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
186698 .undef, .immediate, .lea_frame => temp_mcv,
186699 .eflags,
186700 .register,
186701 .register_pair,
186702 .register_triple,
186703 .register_quadruple,
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 }
186411186732 }
186412186733 for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| {
186413186734 if (op_temp.index != temp.index) continue;
......@@ -187950,6 +188271,7 @@ const Select = struct {
187950188271 ptr_bit_size,
187951188272 size,
187952188273 src0_size,
188274 dst0_size,
187953188275 delta_size,
187954188276 delta_elem_size,
187955188277 unaligned_size,
......@@ -187993,6 +188315,7 @@ const Select = struct {
187993188315 const sub_src0_size: Adjust = .{ .sign = .neg, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
187994188316 const add_src0_size: Adjust = .{ .sign = .pos, .lhs = .src0_size, .op = .mul, .rhs = .@"1" };
187995188317 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" };
187996188319 const add_delta_size_div_8: Adjust = .{ .sign = .pos, .lhs = .delta_size, .op = .div, .rhs = .@"8" };
187997188320 const add_delta_elem_size: Adjust = .{ .sign = .pos, .lhs = .delta_elem_size, .op = .mul, .rhs = .@"1" };
187998188321 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 {
188788189111 .ptr_bit_size => s.cg.target.ptrBitWidth(),
188789189112 .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)),
188790189113 .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)),
188791189115 .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) -
188792189116 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).abiSize(s.cg.pt.zcu)))),
188793189117 .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{
2727 CodegenFail,
2828};
2929
30fn devFeatureForBackend(comptime backend: std.builtin.CompilerBackend) dev.Feature {
31 comptime assert(mem.startsWith(u8, @tagName(backend), "stage2_"));
32 return @field(dev.Feature, @tagName(backend)["stage2_".len..] ++ "_backend");
30fn devFeatureForBackend(backend: std.builtin.CompilerBackend) dev.Feature {
31 return switch (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 };
3346}
3447
35pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type {
48fn importBackend(comptime backend: std.builtin.CompilerBackend) type {
3649 return switch (backend) {
50 .other, .stage1 => unreachable,
3751 .stage2_aarch64 => @import("arch/aarch64/CodeGen.zig"),
3852 .stage2_arm => @import("arch/arm/CodeGen.zig"),
3953 .stage2_c => @import("codegen/c.zig"),
......@@ -42,11 +56,35 @@ pub fn importBackend(comptime backend: std.builtin.CompilerBackend) ?type {
4256 .stage2_riscv64 => @import("arch/riscv64/CodeGen.zig"),
4357 .stage2_sparc64 => @import("arch/sparc64/CodeGen.zig"),
4458 .stage2_spirv64 => @import("codegen/spirv.zig"),
45 .stage2_x86_64 => @import("arch/x86_64/CodeGen.zig"),
46 else => null,
59 .stage2_wasm => @import("arch/wasm/CodeGen.zig"),
60 .stage2_x86, .stage2_x86_64 => @import("arch/x86_64/CodeGen.zig"),
61 _ => unreachable,
4762 };
4863}
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
5088pub fn generateFunction(
5189 lf: *link.File,
5290 pt: Zcu.PerThread,
......@@ -60,7 +98,7 @@ pub fn generateFunction(
6098 const zcu = pt.zcu;
6199 const func = zcu.funcInfo(func_index);
62100 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)) {
64102 else => unreachable,
65103 inline .stage2_aarch64,
66104 .stage2_arm,
......@@ -70,7 +108,7 @@ pub fn generateFunction(
70108 .stage2_x86_64,
71109 => |backend| {
72110 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);
74112 },
75113 }
76114}
......@@ -88,14 +126,14 @@ pub fn generateLazyFunction(
88126 zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
89127 else
90128 zcu.getTarget();
91 switch (target_util.zigBackend(target, false)) {
129 switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) {
92130 else => unreachable,
93131 inline .stage2_powerpc,
94132 .stage2_riscv64,
95133 .stage2_x86_64,
96134 => |backend| {
97135 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);
99137 },
100138 }
101139}
src/codegen/c.zig+80-26
......@@ -4,6 +4,7 @@ const assert = std.debug.assert;
44const mem = std.mem;
55const log = std.log.scoped(.c);
66
7const dev = @import("../dev.zig");
78const link = @import("../link.zig");
89const Zcu = @import("../Zcu.zig");
910const Module = @import("../Package/Module.zig");
......@@ -20,6 +21,15 @@ const Alignment = InternPool.Alignment;
2021const BigIntLimb = std.math.big.Limb;
2122const 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
2333pub const CType = @import("c/Type.zig");
2434
2535pub const CValue = union(enum) {
......@@ -206,7 +216,6 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
206216 .{ "atomic_ushort", {} },
207217 .{ "atomic_wchar_t", {} },
208218 .{ "auto", {} },
209 .{ "bool", {} },
210219 .{ "break", {} },
211220 .{ "case", {} },
212221 .{ "char", {} },
......@@ -266,6 +275,11 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
266275 .{ "va_end", {} },
267276 .{ "va_copy", {} },
268277
278 // stdbool.h
279 .{ "bool", {} },
280 .{ "false", {} },
281 .{ "true", {} },
282
269283 // stddef.h
270284 .{ "offsetof", {} },
271285
......@@ -1591,7 +1605,7 @@ pub const DeclGen = struct {
15911605 try writer.writeAll("((");
15921606 try dg.renderCType(writer, ctype);
15931607 return writer.print("){x})", .{
1594 try dg.fmtIntLiteral(try pt.undefValue(.usize), .Other),
1608 try dg.fmtIntLiteral(.undef_usize, .Other),
15951609 });
15961610 },
15971611 .slice => {
......@@ -1605,7 +1619,7 @@ pub const DeclGen = struct {
16051619 const ptr_ty = ty.slicePtrFieldType(zcu);
16061620 try dg.renderType(writer, ptr_ty);
16071621 return writer.print("){x}, {0x}}}", .{
1608 try dg.fmtIntLiteral(try dg.pt.undefValue(.usize), .Other),
1622 try dg.fmtIntLiteral(.undef_usize, .Other),
16091623 });
16101624 },
16111625 },
......@@ -3360,7 +3374,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
33603374 .error_name => try airErrorName(f, inst),
33613375 .splat => try airSplat(f, inst),
33623376 .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),
33643379 .reduce => try airReduce(f, inst),
33653380 .aggregate_init => try airAggregateInit(f, inst),
33663381 .union_init => try airUnionInit(f, inst),
......@@ -4179,7 +4194,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
41794194 try v.elem(f, w);
41804195 try w.writeAll(", ");
41814196 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);
41834198 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
41844199 try w.writeAll(");\n");
41854200 try v.end(f, inst, w);
......@@ -6376,7 +6391,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
63766391 if (operand_child_ctype.info(ctype_pool) == .array) {
63776392 try writer.writeByte('&');
63786393 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)});
63806395 } else try f.writeCValue(writer, operand, .Other);
63816396 }
63826397 try a.end(f, writer);
......@@ -6536,7 +6551,7 @@ fn airBinBuiltinCall(
65366551 try v.elem(f, writer);
65376552 try writer.writeAll(", ");
65386553 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);
65406555 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);
65416556 try writer.writeAll(");\n");
65426557 try v.end(f, inst, writer);
......@@ -6907,7 +6922,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
69076922 try writer.writeAll("for (");
69086923 try f.writeCValue(writer, index, .Other);
69096924 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);
69116926 try writer.writeAll("; ");
69126927 try f.writeCValue(writer, index, .Other);
69136928 try writer.writeAll(" != ");
......@@ -7149,34 +7164,73 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
71497164 return local;
71507165}
71517166
7152fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
7167fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
71537168 const pt = f.object.dg.pt;
71547169 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);
7159 const lhs = try f.resolveInst(extra.a);
7160 const rhs = try f.resolveInst(extra.b);
7161
7162 const inst_ty = f.typeOfIndex(inst);
7171 const unwrapped = f.air.unwrapShuffleOne(zcu, inst);
7172 const mask = unwrapped.mask;
7173 const operand = try f.resolveInst(unwrapped.operand);
7174 const inst_ty = unwrapped.result_ty;
71637175
71647176 const writer = f.object.writer();
71657177 const local = try f.allocLocal(inst, inst_ty);
7166 try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands
7167 for (0..extra.mask_len) |index| {
7178 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
7179 for (mask, 0..) |mask_elem, out_idx| {
71687180 try f.writeCValue(writer, local, .Other);
71697181 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);
71717183 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);
7174 const src_val = try pt.intValue(.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63)));
7196 return local;
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);
71777215 try writer.writeByte('[');
7178 try f.object.dg.renderValue(writer, src_val, .Other);
7179 try writer.writeAll("];\n");
7216 try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other);
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");
71807234 }
71817235
71827236 return local;
......@@ -8311,11 +8365,11 @@ const Vectorize = struct {
83118365
83128366 try writer.writeAll("for (");
83138367 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)});
83158369 try f.writeCValue(writer, local, .Other);
83168370 try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))});
83178371 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)});
83198373 f.object.indent_writer.pushIndent();
83208374
83218375 break :index .{ .index = local };
src/codegen/c/Type.zig+15-6
......@@ -1408,6 +1408,15 @@ pub const Pool = struct {
14081408 .bits = pt.zcu.errorSetBits(),
14091409 }, 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 }),
14111420 .manyptr_u8_type,
14121421 => return pool.getPointer(allocator, .{
14131422 .elem_ctype = .u8,
......@@ -1418,11 +1427,6 @@ pub const Pool = struct {
14181427 .elem_ctype = .u8,
14191428 .@"const" = true,
14201429 }),
1421 .single_const_pointer_to_comptime_int_type,
1422 => return pool.getPointer(allocator, .{
1423 .elem_ctype = .void,
1424 .@"const" = true,
1425 }),
14261430 .slice_const_u8_type,
14271431 .slice_const_u8_sentinel_0_type,
14281432 => {
......@@ -2157,11 +2161,16 @@ pub const Pool = struct {
21572161 },
21582162
21592163 .undef,
2164 .undef_bool,
2165 .undef_usize,
2166 .undef_u1,
21602167 .zero,
21612168 .zero_usize,
2169 .zero_u1,
21622170 .zero_u8,
21632171 .one,
21642172 .one_usize,
2173 .one_u1,
21652174 .one_u8,
21662175 .four_u8,
21672176 .negative_one,
......@@ -2172,7 +2181,7 @@ pub const Pool = struct {
21722181 .bool_false,
21732182 .empty_tuple,
21742183 .none,
2175 => unreachable,
2184 => unreachable, // values, not types
21762185
21772186 _ => |ip_index| switch (ip.indexToKey(ip_index)) {
21782187 .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;
3636
3737const Error = error{ OutOfMemory, CodegenFail };
3838
39pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
40 return null;
41}
42
3943fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 {
4044 inline for (mappings) |mapping| {
4145 if (arch.featureSetHas(features, mapping[0])) return mapping[1];
......@@ -3081,10 +3085,11 @@ pub const Object = struct {
30813085 .undefined_type,
30823086 .enum_literal_type,
30833087 => unreachable,
3088 .ptr_usize_type,
3089 .ptr_const_comptime_int_type,
30843090 .manyptr_u8_type,
30853091 .manyptr_const_u8_type,
30863092 .manyptr_const_u8_sentinel_0_type,
3087 .single_const_pointer_to_comptime_int_type,
30883093 => .ptr,
30893094 .slice_const_u8_type,
30903095 .slice_const_u8_sentinel_0_type,
......@@ -3098,11 +3103,16 @@ pub const Object = struct {
30983103 => unreachable,
30993104 // values, not types
31003105 .undef,
3106 .undef_bool,
3107 .undef_usize,
3108 .undef_u1,
31013109 .zero,
31023110 .zero_usize,
3111 .zero_u1,
31033112 .zero_u8,
31043113 .one,
31053114 .one_usize,
3115 .one_u1,
31063116 .one_u8,
31073117 .four_u8,
31083118 .negative_one,
......@@ -4959,7 +4969,8 @@ pub const FuncGen = struct {
49594969 .error_name => try self.airErrorName(inst),
49604970 .splat => try self.airSplat(inst),
49614971 .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),
49634974 .aggregate_init => try self.airAggregateInit(inst),
49644975 .union_init => try self.airUnionInit(inst),
49654976 .prefetch => try self.airPrefetch(inst),
......@@ -8917,6 +8928,8 @@ pub const FuncGen = struct {
89178928 const rhs = try self.resolveInst(extra.rhs);
89188929
89198930 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", .{});
89208933 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
89218934
89228935 const dest_ty = self.typeOfIndex(inst);
......@@ -8986,6 +8999,8 @@ pub const FuncGen = struct {
89868999 const rhs = try self.resolveInst(bin_op.rhs);
89879000
89889001 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", .{});
89899004 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
89909005
89919006 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");
......@@ -8997,14 +9012,17 @@ pub const FuncGen = struct {
89979012
89989013 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
89999014 const o = self.ng.object;
9015 const zcu = o.pt.zcu;
90009016 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
90019017
90029018 const lhs = try self.resolveInst(bin_op.lhs);
90039019 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), "");
90089026 return self.wip.bin(.shl, lhs, casted_rhs, "");
90099027 }
90109028
......@@ -9023,6 +9041,8 @@ pub const FuncGen = struct {
90239041 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);
90249042
90259043 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", .{});
90269046 const rhs_info = rhs_ty.intInfo(zcu);
90279047 assert(rhs_info.signedness == .unsigned);
90289048 const llvm_rhs_ty = try o.lowerType(rhs_ty);
......@@ -9095,6 +9115,8 @@ pub const FuncGen = struct {
90959115 const rhs = try self.resolveInst(bin_op.rhs);
90969116
90979117 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", .{});
90989120 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
90999121
91009122 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");
......@@ -9167,11 +9189,7 @@ pub const FuncGen = struct {
91679189 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
91689190 assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector));
91699191
9170 const min_panic_id: Zcu.SimplePanicId, const max_panic_id: Zcu.SimplePanicId = id: {
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 };
9192 const panic_id: Zcu.SimplePanicId = if (dest_is_enum) .invalid_enum_value else .integer_out_of_bounds;
91759193
91769194 if (have_min_check) {
91779195 const min_const_scalar = try minIntConst(&o.builder, dest_scalar, operand_scalar_llvm_ty, zcu);
......@@ -9185,7 +9203,7 @@ pub const FuncGen = struct {
91859203 const ok_block = try fg.wip.block(1, "IntMinOk");
91869204 _ = try fg.wip.brCond(ok, ok_block, fail_block, .none);
91879205 fg.wip.cursor = .{ .block = fail_block };
9188 try fg.buildSimplePanic(min_panic_id);
9206 try fg.buildSimplePanic(panic_id);
91899207 fg.wip.cursor = .{ .block = ok_block };
91909208 }
91919209
......@@ -9201,7 +9219,7 @@ pub const FuncGen = struct {
92019219 const ok_block = try fg.wip.block(1, "IntMaxOk");
92029220 _ = try fg.wip.brCond(ok, ok_block, fail_block, .none);
92039221 fg.wip.cursor = .{ .block = fail_block };
9204 try fg.buildSimplePanic(max_panic_id);
9222 try fg.buildSimplePanic(panic_id);
92059223 fg.wip.cursor = .{ .block = ok_block };
92069224 }
92079225 }
......@@ -9249,8 +9267,6 @@ pub const FuncGen = struct {
92499267 const operand_ty = self.typeOf(ty_op.operand);
92509268 const dest_ty = self.typeOfIndex(inst);
92519269 const target = zcu.getTarget();
9252 const dest_bits = dest_ty.floatBits(target);
9253 const src_bits = operand_ty.floatBits(target);
92549270
92559271 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
92569272 return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty), "");
......@@ -9258,6 +9274,8 @@ pub const FuncGen = struct {
92589274 const operand_llvm_ty = try o.lowerType(operand_ty);
92599275 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);
92619279 const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{
92629280 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
92639281 });
......@@ -9342,11 +9360,12 @@ pub const FuncGen = struct {
93429360 return self.wip.conv(.unsigned, operand, llvm_dest_ty, "");
93439361 }
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)) {
93469366 return self.wip.cast(.inttoptr, operand, llvm_dest_ty, "");
93479367 }
9348
9349 if (operand_ty.isPtrAtRuntime(zcu) and inst_ty.zigTypeTag(zcu) == .int) {
9368 if (operand_scalar_ty.isPtrAtRuntime(zcu) and inst_scalar_ty.zigTypeTag(zcu) == .int) {
93509369 return self.wip.cast(.ptrtoint, operand, llvm_dest_ty, "");
93519370 }
93529371
......@@ -9644,7 +9663,7 @@ pub const FuncGen = struct {
96449663 const zcu = o.pt.zcu;
96459664 const ip = &zcu.intern_pool;
96469665 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)) {
96489667 .none => continue,
96499668 .write, .noret, .complex => return false,
96509669 .tomb => return true,
......@@ -10399,42 +10418,192 @@ pub const FuncGen = struct {
1039910418 return self.wip.select(.normal, pred, a, b, "");
1040010419 }
1040110420
10402 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10403 const o = self.ng.object;
10421 fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10422 const o = fg.ng.object;
1040410423 const pt = o.pt;
1040510424 const zcu = pt.zcu;
10406 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
10407 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
10408 const a = try self.resolveInst(extra.a);
10409 const b = try self.resolveInst(extra.b);
10410 const mask = Value.fromInterned(extra.mask);
10411 const mask_len = extra.mask_len;
10412 const a_len = self.typeOf(extra.a).vectorLen(zcu);
10413
10414 // LLVM uses integers larger than the length of the first array to
10415 // index into the second array. This was deemed unnecessarily fragile
10416 // when changing code, so Zig uses negative numbers to index the
10417 // second vector. These start at -1 and go down, and are easiest to use
10418 // with the ~ operator. Here we convert between the two formats.
10419 const values = try self.gpa.alloc(Builder.Constant, mask_len);
10420 defer self.gpa.free(values);
10421
10422 for (values, 0..) |*val, i| {
10423 const elem = try mask.elemValue(pt, i);
10424 if (elem.isUndef(zcu)) {
10425 val.* = try o.builder.undefConst(.i32);
10426 } else {
10427 const int = elem.toSignedInt(zcu);
10428 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);
10429 val.* = try o.builder.intConst(.i32, unsigned);
10425 const gpa = zcu.gpa;
10426
10427 const unwrapped = fg.air.unwrapShuffleOne(zcu, inst);
10428
10429 const operand = try fg.resolveInst(unwrapped.operand);
10430 const mask = unwrapped.mask;
10431 const operand_ty = fg.typeOf(unwrapped.operand);
10432 const llvm_operand_ty = try o.lowerType(operand_ty);
10433 const llvm_result_ty = try o.lowerType(unwrapped.result_ty);
10434 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu));
10435 const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty);
10436 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);
10437 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);
10438
10439 // LLVM requires that the two input vectors have the same length, so lowering isn't trivial.
10440 // And, in the words of jacobly0: "llvm sucks at shuffles so we do have to hold its hand at
10441 // least a bit". So, there are two cases here.
10442 //
10443 // If the operand length equals the mask length, we do just the one `shufflevector`, where
10444 // the second operand is a constant vector with comptime-known elements at the right indices
10445 // and poison values elsewhere (in the indices which won't be selected).
10446 //
10447 // Otherwise, we lower to *two* `shufflevector` instructions. The first shuffles the runtime
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 };
1043010482 }
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 };
1043110496 }
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(
10434 try o.builder.vectorType(.normal, mask_len, .i32),
10435 values,
10505 if (!any_defined_comptime_value) {
10506 // `comptime_and_poison` is just poison; a second shuffle would be a nop.
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 "",
1043610606 );
10437 return self.wip.shuffleVector(a, b, llvm_mask_value, "");
1043810607 }
1043910608
1044010609 /// 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");
2828
2929const 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
3140pub const zig_call_abi_ver = 3;
3241pub const big_int_bits = 32;
3342
......@@ -3243,7 +3252,8 @@ const NavGen = struct {
32433252
32443253 .splat => try self.airSplat(inst),
32453254 .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
32483258 .ptr_add => try self.airPtrAdd(inst),
32493259 .ptr_sub => try self.airPtrSub(inst),
......@@ -3380,6 +3390,10 @@ const NavGen = struct {
33803390 const zcu = self.pt.zcu;
33813391 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
33833397 const base = try self.temporary(bin_op.lhs);
33843398 const shift = try self.temporary(bin_op.rhs);
33853399
......@@ -3866,6 +3880,10 @@ const NavGen = struct {
38663880 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
38673881 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
38693887 const base = try self.temporary(extra.lhs);
38703888 const shift = try self.temporary(extra.rhs);
38713889
......@@ -4030,40 +4048,57 @@ const NavGen = struct {
40304048 return result_id;
40314049 }
40324050
4033 fn airShuffle(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4034 const pt = self.pt;
4051 fn airShuffleOne(ng: *NavGen, inst: Air.Inst.Index) !?IdRef {
4052 const pt = ng.pt;
40354053 const zcu = pt.zcu;
4036 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
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);
4054 const gpa = zcu.gpa;
40414055
4042 // Note: number of components in the result, a, and b may differ.
4043 const result_ty = self.typeOfIndex(inst);
4044 const scalar_ty = result_ty.scalarType(zcu);
4045 const scalar_ty_id = try self.resolveType(scalar_ty, .direct);
4056 const unwrapped = ng.air.unwrapShuffleOne(zcu, inst);
4057 const mask = unwrapped.mask;
4058 const result_ty = unwrapped.result_ty;
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));
4048 defer self.gpa.free(constituents);
4062 const constituents = try gpa.alloc(IdRef, mask.len);
4063 defer gpa.free(constituents);
40494064
4050 for (constituents, 0..) |*id, i| {
4051 const elem = try mask.elemValue(pt, i);
4052 if (elem.isUndef(zcu)) {
4053 id.* = try self.spv.constUndef(scalar_ty_id);
4054 continue;
4055 }
4065 for (constituents, mask) |*id, mask_elem| {
4066 id.* = switch (mask_elem.unwrap()) {
4067 .elem => |idx| try ng.extractVectorComponent(elem_ty, operand, idx),
4068 .value => |val| try ng.constant(elem_ty, .fromInterned(val), .direct),
4069 };
4070 }
40564071
4057 const index = elem.toSignedInt(zcu);
4058 if (index >= 0) {
4059 id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index));
4060 } else {
4061 id.* = try self.extractVectorComponent(scalar_ty, b, @intCast(~index));
4062 }
4072 const result_ty_id = try ng.resolveType(result_ty, .direct);
4073 return try ng.constructComposite(result_ty_id, constituents);
4074 }
4075
4076 fn airShuffleTwo(ng: *NavGen, inst: Air.Inst.Index) !?IdRef {
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 };
40634098 }
40644099
4065 const result_ty_id = try self.resolveType(result_ty, .direct);
4066 return try self.constructComposite(result_ty_id, constituents);
4100 const result_ty_id = try ng.resolveType(result_ty, .direct);
4101 return try ng.constructComposite(result_ty_id, constituents);
40674102 }
40684103
40694104 fn indicesToIds(self: *NavGen, indices: []const u32) ![]IdRef {
src/dev.zig+6
......@@ -1,5 +1,8 @@
11pub const Env = enum {
22 /// zig1 features
3 /// - `-ofmt=c` only
4 /// - `-OReleaseFast` or `-OReleaseSmall` only
5 /// - no `@setRuntimeSafety(true)`
36 bootstrap,
47
58 /// zig2 features
......@@ -67,6 +70,7 @@ pub const Env = enum {
6770 .incremental,
6871 .ast_gen,
6972 .sema,
73 .legalize,
7074 .llvm_backend,
7175 .c_backend,
7276 .wasm_backend,
......@@ -144,6 +148,7 @@ pub const Env = enum {
144148 .build_command,
145149 .stdio_listen,
146150 .incremental,
151 .legalize,
147152 .x86_64_backend,
148153 .elf_linker,
149154 => true,
......@@ -222,6 +227,7 @@ pub const Feature = enum {
222227 incremental,
223228 ast_gen,
224229 sema,
230 legalize,
225231
226232 llvm_backend,
227233 c_backend,
src/mutable_value.zig+2-2
......@@ -260,7 +260,7 @@ pub const MutableValue = union(enum) {
260260 const ptr = try arena.create(MutableValue);
261261 const len = try arena.create(MutableValue);
262262 ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) };
263 len.* = .{ .interned = try pt.intern(.{ .undef = .usize_type }) };
263 len.* = .{ .interned = .undef_usize };
264264 mv.* = .{ .slice = .{
265265 .ty = ty_ip,
266266 .ptr = ptr,
......@@ -464,7 +464,7 @@ pub const MutableValue = union(enum) {
464464 return switch (field_idx) {
465465 Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() },
466466 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,
468468 .slice => |s| s.len,
469469 else => unreachable,
470470 } },
src/print_air.zig+33-7
......@@ -315,7 +315,8 @@ const Writer = struct {
315315 .wasm_memory_grow => try w.writeWasmMemoryGrow(s, inst),
316316 .mul_add => try w.writeMulAdd(s, inst),
317317 .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),
319320 .reduce, .reduce_optimized => try w.writeReduce(s, inst),
320321 .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst),
321322 .vector_store_elem => try w.writeVectorStoreElem(s, inst),
......@@ -499,14 +500,39 @@ const Writer = struct {
499500 try w.writeOperand(s, inst, 2, pl_op.operand);
500501 }
501502
502 fn writeShuffle(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 extra = w.air.extraData(Air.Shuffle, ty_pl.payload).data;
503 fn writeShuffleOne(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
504 const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst);
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);
507524 try s.writeAll(", ");
508 try w.writeOperand(s, inst, 1, extra.b);
509 try s.print(", mask {d}, len {d}", .{ extra.mask, extra.mask_len });
525 try w.writeOperand(s, inst, 1, unwrapped.operand_b);
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(']');
510536 }
511537
512538 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
842842 .stage2_c, .stage2_llvm, .stage2_x86_64 => true,
843843 else => false,
844844 },
845 .safety_checked_instructions => switch (backend) {
846 .stage2_llvm => true,
847 else => false,
848 },
849845 .separate_thread => switch (backend) {
850846 .stage2_llvm => false,
851847 else => true,
852848 },
853 .all_vector_instructions => switch (backend) {
854 .stage2_x86_64 => true,
855 else => false,
856 },
857849 };
858850}
stage1/zig.h+21-11
......@@ -481,6 +481,7 @@
481481
482482zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
483483zig_extern void *memset (void *, int, size_t);
484zig_extern void *memmove (void *, void const *, size_t);
484485
485486/* ================ 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
11141115\
11151116 static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
11161117 uint##w##_t res; \
1117 if (rhs >= bits) return lhs != UINT##w##_C(0) ? zig_maxInt_u(w, bits) : lhs; \
1118 return zig_shlo_u##w(&res, lhs, (uint8_t)rhs, bits) ? zig_maxInt_u(w, bits) : res; \
1118 if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \
1119 return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \
11191120 } \
11201121\
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) { \
11221123 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 return lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1124 if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
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); \
11251127 } \
11261128\
11271129 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
18501852
18511853static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
18521854 zig_u128 res;
1853 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) >= INT32_C(0))
1854 return zig_cmp_u128(lhs, zig_make_u128(0, 0)) != INT32_C(0) ? zig_maxInt_u(128, bits) : lhs;
1855 return zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits) ? zig_maxInt_u(128, bits) : res;
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;
1856 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
1857 case 0: return zig_make_u128(0, 0);
1858 case 1: return zig_maxInt_u(128, bits);
1859 default: zig_unreachable();
1860 }
18561861}
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) {
18591864 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;
1861 return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
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;
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 }
18621872}
18631873
18641874static 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" {
9696 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
9797 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
9898 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
101100 try comptime testAbsSignedBigInt();
102101 try testAbsSignedBigInt();
......@@ -211,7 +210,6 @@ fn testAbsFloats(comptime T: type) !void {
211210test "@abs int vectors" {
212211 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
213212 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;
215213 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
216214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
217215 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" {
837837 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
838838 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
839839 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;
841840 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
842841
843842 @export(&var_to_export, .{ .name = "opaque_extern_var" });
test/behavior/bitcast.zig-1
......@@ -384,7 +384,6 @@ test "comptime bitcast with fields following f80" {
384384 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
385385 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
386386 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
389388 const FloatT = extern struct { f: f80, x: u128 align(16) };
390389 const x: FloatT = .{ .f = 0.5, .x = 123 };
test/behavior/bitreverse.zig-4
......@@ -12,7 +12,6 @@ test "@bitReverse" {
1212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1414 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;
1615 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1716
1817 try comptime testBitReverse();
......@@ -123,7 +122,6 @@ fn vector8() !void {
123122
124123test "bitReverse vectors u8" {
125124 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
126 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
127125 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
128126 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
129127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -144,7 +142,6 @@ fn vector16() !void {
144142
145143test "bitReverse vectors u16" {
146144 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
148145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
149146 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
150147 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -165,7 +162,6 @@ fn vector24() !void {
165162
166163test "bitReverse vectors u24" {
167164 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
168 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
169165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
170166 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
171167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/byteswap.zig-4
......@@ -39,7 +39,6 @@ test "@byteSwap integers" {
3939 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
4040 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
4141 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
4443 const ByteSwapIntTest = struct {
4544 fn run() !void {
......@@ -95,7 +94,6 @@ fn vector8() !void {
9594
9695test "@byteSwap vectors u8" {
9796 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
98 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
9997 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10098 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10199 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -116,7 +114,6 @@ fn vector16() !void {
116114
117115test "@byteSwap vectors u16" {
118116 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
119 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
120117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
121118 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
122119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -137,7 +134,6 @@ fn vector24() !void {
137134
138135test "@byteSwap vectors u24" {
139136 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
140 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
141137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
142138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
143139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/cast.zig-4
......@@ -617,7 +617,6 @@ test "@intCast on vector" {
617617 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
618618 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
619619 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
620 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
621620 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
622621 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
623622 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
......@@ -2520,7 +2519,6 @@ test "@ptrFromInt on vector" {
25202519 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25212520 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25222521 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;
25242522 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
25252523
25262524 const S = struct {
......@@ -2592,7 +2590,6 @@ test "@intFromFloat on vector" {
25922590 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25932591 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25942592 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
25972594 const S = struct {
25982595 fn doTheTest() !void {
......@@ -2693,7 +2690,6 @@ test "@intCast vector of signed integer" {
26932690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
26942691 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
26952692 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2696 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
26972693 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
26982694 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
26992695 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;
55test "anyopaque extern symbol" {
66 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
77 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;
98 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
109
1110 const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" });
test/behavior/floatop.zig+36-15
......@@ -14,9 +14,11 @@ fn epsForType(comptime T: type) T {
1414}
1515
1616test "add f16" {
17 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1817 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
2022 try testAdd(f16);
2123 try comptime testAdd(f16);
2224}
......@@ -123,10 +125,12 @@ fn testMul(comptime T: type) !void {
123125
124126test "cmp f16" {
125127 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;
127128 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
128129 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
130134 try testCmp(f16);
131135 try comptime testCmp(f16);
132136}
......@@ -135,7 +139,6 @@ test "cmp f32" {
135139 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
136140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
137141 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
140143 try testCmp(f32);
141144 try comptime testCmp(f32);
......@@ -144,7 +147,6 @@ test "cmp f32" {
144147test "cmp f64" {
145148 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
146149 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;
148150 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
149151
150152 try testCmp(f64);
......@@ -340,9 +342,11 @@ test "different sized float comparisons" {
340342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
341343 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
342344 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;
344345 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
346350 try testDifferentSizedFloatComparisons();
347351 try comptime testDifferentSizedFloatComparisons();
348352}
......@@ -388,10 +392,12 @@ test "@sqrt f16" {
388392 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
389393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
390394 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;
392395 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
393396 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
395401 try testSqrt(f16);
396402 try comptime testSqrt(f16);
397403}
......@@ -400,7 +406,6 @@ test "@sqrt f32/f64" {
400406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
401407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
402408 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;
404409 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
405410
406411 try testSqrt(f32);
......@@ -1132,9 +1137,11 @@ test "@abs f16" {
11321137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11331138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11341139 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;
11361140 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
11381145 try testFabs(f16);
11391146 try comptime testFabs(f16);
11401147}
......@@ -1266,9 +1273,11 @@ test "@floor f32/f64" {
12661273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12671274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12681275 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;
12701276 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
12721281 try testFloor(f32);
12731282 try comptime testFloor(f32);
12741283 try testFloor(f64);
......@@ -1332,7 +1341,9 @@ test "@floor with vectors" {
13321341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13331342 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13341343 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
13371348 try testFloorWithVectors();
13381349 try comptime testFloorWithVectors();
......@@ -1363,9 +1374,11 @@ test "@ceil f32/f64" {
13631374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13641375 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13651376 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;
13671377 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
13691382 try testCeil(f32);
13701383 try comptime testCeil(f32);
13711384 try testCeil(f64);
......@@ -1429,7 +1442,9 @@ test "@ceil with vectors" {
14291442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14301443 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
14311444 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
14341449 try testCeilWithVectors();
14351450 try comptime testCeilWithVectors();
......@@ -1460,9 +1475,11 @@ test "@trunc f32/f64" {
14601475 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14611476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14621477 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;
14641478 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
14661483 try testTrunc(f32);
14671484 try comptime testTrunc(f32);
14681485 try testTrunc(f64);
......@@ -1526,7 +1543,9 @@ test "@trunc with vectors" {
15261543 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15271544 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
15281545 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
15311550 try testTruncWithVectors();
15321551 try comptime testTruncWithVectors();
......@@ -1546,9 +1565,11 @@ test "neg f16" {
15461565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15471566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15481567 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;
15501568 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
15521573 if (builtin.os.tag == .freebsd) {
15531574 // TODO file issue to track this failure
15541575 return error.SkipZigTest;
test/behavior/fn.zig-1
......@@ -429,7 +429,6 @@ test "implicit cast function to function ptr" {
429429 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
430430 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
431431 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
434433 const S1 = struct {
435434 export fn someFunctionThatReturnsAValue() c_int {
test/behavior/math.zig+7-13
......@@ -85,7 +85,6 @@ test "@clz big ints" {
8585 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8686 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8787 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;
8988 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9089
9190 try testClzBigInts();
......@@ -103,7 +102,6 @@ fn testOneClz(comptime T: type, x: T) u32 {
103102
104103test "@clz vectors" {
105104 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;
107105 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
108106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
109107 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -173,7 +171,6 @@ fn testOneCtz(comptime T: type, x: T) u32 {
173171}
174172
175173test "@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;
177174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
178175 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
179176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -193,7 +190,6 @@ fn testCtz128() !void {
193190
194191test "@ctz vectors" {
195192 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
197193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
198194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
199195 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -475,10 +471,12 @@ test "division" {
475471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
476472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
477473 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;
479474 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
480475 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
482480 try testIntDivision();
483481 try comptime testIntDivision();
484482
......@@ -1623,10 +1621,10 @@ test "vector integer addition" {
16231621 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
16241622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16251623 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1626 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
16271624 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16281625 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16291626 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
16311629 const S = struct {
16321630 fn doTheTest() !void {
......@@ -1694,9 +1692,6 @@ test "vector comparison" {
16941692 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16951693 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
17001695 const S = struct {
17011696 fn doTheTest() !void {
17021697 var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 };
......@@ -1785,7 +1780,6 @@ test "mod lazy values" {
17851780
17861781test "@clz works on both vector and scalar inputs" {
17871782 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;
17891783 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17901784 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17911785 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1807,7 +1801,6 @@ test "runtime comparison to NaN is comptime-known" {
18071801 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18081802 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18091803 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;
18111804 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18121805 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" {
18381831 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18391832 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18401833 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;
18421834 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18431835 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" {
19361928 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
19371929 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19381930 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
19411935 const ct_zero: @Vector(1, f32) = .{0};
19421936 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
test/behavior/maximum_minimum.zig-6
......@@ -34,7 +34,6 @@ test "@max on vectors" {
3434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3535 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3636 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
3938 const S = struct {
4039 fn doTheTest() !void {
......@@ -90,7 +89,6 @@ test "@min for vectors" {
9089 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9190 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9291 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
9593 const S = struct {
9694 fn doTheTest() !void {
......@@ -206,7 +204,6 @@ test "@min/@max notices vector bounds" {
206204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
208206 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
211208 var x: @Vector(2, u16) = .{ 140, 40 };
212209 const y: @Vector(2, u64) = .{ 5, 100 };
......@@ -260,7 +257,6 @@ test "@min/@max notices bounds from vector types" {
260257 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
262259 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
265261 var x: @Vector(2, u16) = .{ 30, 67 };
266262 var y: @Vector(2, u32) = .{ 20, 500 };
......@@ -303,7 +299,6 @@ test "@min/@max notices bounds from vector types when element of comptime-known
303299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
304300 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
305301 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
308303 var x: @Vector(2, u32) = .{ 1_000_000, 12345 };
309304 _ = &x;
......@@ -375,7 +370,6 @@ test "@min/@max with runtime vectors of signed and unsigned integers of same siz
375370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
376371 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
377372 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
380374 const S = struct {
381375 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" {
66 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
88 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;
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1110 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
1315 try comptime testMulAdd();
1416 try testMulAdd();
1517}
......@@ -137,10 +139,12 @@ test "vector f32" {
137139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
139141 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;
141142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
142143 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
144148 try comptime vector32();
145149 try vector32();
146150}
......@@ -163,10 +167,12 @@ test "vector f64" {
163167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
164168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
165169 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;
167170 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
168171 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
170176 try comptime vector64();
171177 try vector64();
172178}
test/behavior/packed-struct.zig+11
......@@ -1307,6 +1307,17 @@ test "packed struct equality" {
13071307 comptime try S.doTest(x, y);
13081308}
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
13101321test "packed struct with signed field" {
13111322 var s: packed struct {
13121323 a: i2,
test/behavior/popcount.zig-1
......@@ -77,7 +77,6 @@ fn testPopCountIntegers() !void {
7777
7878test "@popCount vectors" {
7979 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8180 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8281 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8382 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/select.zig-3
......@@ -41,8 +41,6 @@ test "@select arrays" {
4141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4242 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4343 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
4745 try comptime selectArrays();
4846 try selectArrays();
......@@ -70,7 +68,6 @@ fn selectArrays() !void {
7068test "@select compare result" {
7169 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7270 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;
7471 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
7572
7673 const S = struct {
test/behavior/shuffle.zig-5
......@@ -10,8 +10,6 @@ test "@shuffle int" {
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1212 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
1614 const S = struct {
1715 fn doTheTest() !void {
......@@ -53,7 +51,6 @@ test "@shuffle int" {
5351
5452test "@shuffle int strange sizes" {
5553 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
5754 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5855 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5956 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -136,7 +133,6 @@ fn testShuffle(
136133
137134test "@shuffle bool 1" {
138135 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
140136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
141137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
142138 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -160,7 +156,6 @@ test "@shuffle bool 1" {
160156
161157test "@shuffle bool 2" {
162158 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
164159 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
165160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
166161 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" {
282282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
283283 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
284284 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
286287 try testCastUnionToTag();
287288 try comptime testCastUnionToTag();
test/behavior/vector.zig+9-20
......@@ -31,7 +31,6 @@ test "vector wrap operators" {
3131 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3232 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3333 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
3635 const S = struct {
3736 fn doTheTest() !void {
......@@ -76,12 +75,12 @@ test "vector bin compares with mem.eql" {
7675
7776test "vector int operators" {
7877 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8078 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8179 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8381 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8482 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
8685 const S = struct {
8786 fn doTheTest() !void {
......@@ -249,9 +248,11 @@ test "array to vector with element type coercion" {
249248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
250249 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
251250 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;
253251 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
255256 const S = struct {
256257 fn doTheTest() !void {
257258 var foo: f16 = 3.14;
......@@ -286,11 +287,11 @@ test "peer type resolution with coercible element types" {
286287
287288test "tuple to vector" {
288289 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
289 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
290290 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
291291 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
292292 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
293293 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
295296 const S = struct {
296297 fn doTheTest() !void {
......@@ -652,7 +653,6 @@ test "vector division operators" {
652653test "vector bitwise not operator" {
653654 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
654655 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;
656656 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
657657 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
658658 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -684,12 +684,12 @@ test "vector bitwise not operator" {
684684
685685test "vector shift operators" {
686686 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
687 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
688687 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
689688 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
690689 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
691690 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
692691 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
694694 const S = struct {
695695 fn doTheTestShift(x: anytype, y: anytype) !void {
......@@ -908,8 +908,6 @@ test "mask parameter of @shuffle is comptime scope" {
908908 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
909909 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
910910 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
914912 const __v4hi = @Vector(4, i16);
915913 var v4_a = __v4hi{ 1, 2, 3, 4 };
......@@ -934,7 +932,6 @@ test "saturating add" {
934932 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
935933 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
936934 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
939936 const S = struct {
940937 fn doTheTest() !void {
......@@ -969,7 +966,6 @@ test "saturating subtraction" {
969966 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
970967 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
971968 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
974970 const S = struct {
975971 fn doTheTest() !void {
......@@ -989,7 +985,6 @@ test "saturating subtraction" {
989985
990986test "saturating multiplication" {
991987 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
992 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
993988 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
994989 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
995990 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1018,12 +1013,12 @@ test "saturating multiplication" {
10181013
10191014test "saturating shift-left" {
10201015 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10221016 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10231017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10241018 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10251019 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10261020 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
10281023 const S = struct {
10291024 fn doTheTest() !void {
......@@ -1043,12 +1038,12 @@ test "saturating shift-left" {
10431038
10441039test "multiplication-assignment operator with an array operand" {
10451040 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1046 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10471041 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10481042 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10491043 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10501044 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10511045 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
10531048 const S = struct {
10541049 fn doTheTest() !void {
......@@ -1065,7 +1060,6 @@ test "multiplication-assignment operator with an array operand" {
10651060
10661061test "@addWithOverflow" {
10671062 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1068 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10691063 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10701064 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10711065 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1116,7 +1110,6 @@ test "@addWithOverflow" {
11161110
11171111test "@subWithOverflow" {
11181112 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1119 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11201113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11211114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11221115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1151,7 +1144,6 @@ test "@subWithOverflow" {
11511144
11521145test "@mulWithOverflow" {
11531146 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1154 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11551147 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11561148 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11571149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1175,7 +1167,6 @@ test "@mulWithOverflow" {
11751167
11761168test "@shlWithOverflow" {
11771169 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1178 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11791170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11801171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11811172 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1314,7 +1305,7 @@ test "zero multiplicand" {
13141305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13151306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13161307 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1317 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1308 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
13181309
13191310 const zeros = @Vector(2, u32){ 0.0, 0.0 };
13201311 var ones = @Vector(2, u32){ 1.0, 1.0 };
......@@ -1362,7 +1353,6 @@ test "array operands to shuffle are coerced to vectors" {
13621353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13631354 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13641355 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1365 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
13661356 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13671357
13681358 const mask = [5]i32{ -1, 0, 1, 2, 3 };
......@@ -1469,7 +1459,6 @@ test "compare vectors with different element types" {
14691459 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14701460 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14711461 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1472 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14731462 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14741463 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14751464
test/behavior/x86_64/binary.zig+40-16
......@@ -1,5 +1,7 @@
11const AddOneBit = math.AddOneBit;
2const AsSignedness = math.AsSignedness;
23const cast = math.cast;
4const ChangeScalar = math.ChangeScalar;
35const checkExpected = math.checkExpected;
46const Compare = math.Compare;
57const DoubleBits = math.DoubleBits;
......@@ -13,6 +15,7 @@ const math = @import("math.zig");
1315const nan = math.nan;
1416const Scalar = math.Scalar;
1517const sign = math.sign;
18const splat = math.splat;
1619const Sse = math.Sse;
1720const tmin = math.tmin;
1821
......@@ -5141,6 +5144,7 @@ inline fn mulSat(comptime Type: type, lhs: Type, rhs: Type) Type {
51415144test mulSat {
51425145 const test_mul_sat = binary(mulSat, .{});
51435146 try test_mul_sat.testInts();
5147 try test_mul_sat.testIntVectors();
51445148}
51455149
51465150inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) {
......@@ -5240,38 +5244,42 @@ test min {
52405244 try test_min.testFloatVectors();
52415245}
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) } {
52445248 return @addWithOverflow(lhs, rhs);
52455249}
52465250test addWithOverflow {
52475251 const test_add_with_overflow = binary(addWithOverflow, .{});
52485252 try test_add_with_overflow.testInts();
5253 try test_add_with_overflow.testIntVectors();
52495254}
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) } {
52525257 return @subWithOverflow(lhs, rhs);
52535258}
52545259test subWithOverflow {
52555260 const test_sub_with_overflow = binary(subWithOverflow, .{});
52565261 try test_sub_with_overflow.testInts();
5262 try test_sub_with_overflow.testIntVectors();
52575263}
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) } {
52605266 return @mulWithOverflow(lhs, rhs);
52615267}
52625268test mulWithOverflow {
52635269 const test_mul_with_overflow = binary(mulWithOverflow, .{});
52645270 try test_mul_with_overflow.testInts();
5271 try test_mul_with_overflow.testIntVectors();
52655272}
52665273
5267inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {
5268 const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs);
5274inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } {
5275 const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs);
52695276 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);
52715278}
52725279test shlWithOverflow {
52735280 const test_shl_with_overflow = binary(shlWithOverflow, .{});
52745281 try test_shl_with_overflow.testInts();
5282 try test_shl_with_overflow.testIntVectors();
52755283}
52765284
52775285inline 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) {
52805288test equal {
52815289 const test_equal = binary(equal, .{});
52825290 try test_equal.testInts();
5291 try test_equal.testIntVectors();
52835292 try test_equal.testFloats();
5293 try test_equal.testFloatVectors();
52845294}
52855295
52865296inline 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
52895299test notEqual {
52905300 const test_not_equal = binary(notEqual, .{});
52915301 try test_not_equal.testInts();
5302 try test_not_equal.testIntVectors();
52925303 try test_not_equal.testFloats();
5304 try test_not_equal.testFloatVectors();
52935305}
52945306
52955307inline 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)
52985310test lessThan {
52995311 const test_less_than = binary(lessThan, .{});
53005312 try test_less_than.testInts();
5313 try test_less_than.testIntVectors();
53015314 try test_less_than.testFloats();
5315 try test_less_than.testFloatVectors();
53025316}
53035317
53045318inline 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
53075321test lessThanOrEqual {
53085322 const test_less_than_or_equal = binary(lessThanOrEqual, .{});
53095323 try test_less_than_or_equal.testInts();
5324 try test_less_than_or_equal.testIntVectors();
53105325 try test_less_than_or_equal.testFloats();
5326 try test_less_than_or_equal.testFloatVectors();
53115327}
53125328
53135329inline 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
53165332test greaterThan {
53175333 const test_greater_than = binary(greaterThan, .{});
53185334 try test_greater_than.testInts();
5335 try test_greater_than.testIntVectors();
53195336 try test_greater_than.testFloats();
5337 try test_greater_than.testFloatVectors();
53205338}
53215339
53225340inline 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(
53255343test greaterThanOrEqual {
53265344 const test_greater_than_or_equal = binary(greaterThanOrEqual, .{});
53275345 try test_greater_than_or_equal.testInts();
5346 try test_greater_than_or_equal.testIntVectors();
53285347 try test_greater_than_or_equal.testFloats();
5348 try test_greater_than_or_equal.testFloatVectors();
53295349}
53305350
53315351inline fn bitAnd(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs & rhs) {
......@@ -5347,54 +5367,57 @@ test bitOr {
53475367}
53485368
53495369inline 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);
53515371 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;
53535373}
53545374test shr {
53555375 const test_shr = binary(shr, .{});
53565376 try test_shr.testInts();
5377 try test_shr.testIntVectors();
53575378}
53585379
53595380inline 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);
53615382 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;
53635384 return @shrExact(lhs >> final_rhs << final_rhs, final_rhs);
53645385}
53655386test shrExact {
53665387 const test_shr_exact = binary(shrExact, .{});
53675388 try test_shr_exact.testInts();
5389 try test_shr_exact.testIntVectors();
53685390}
53695391
53705392inline 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);
53725394 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;
53745396}
53755397test shl {
53765398 const test_shl = binary(shl, .{});
53775399 try test_shl.testInts();
5400 try test_shl.testIntVectors();
53785401}
53795402
53805403inline fn shlExactUnsafe(comptime Type: type, lhs: Type, rhs: Type) Type {
53815404 @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);
53835406 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;
53855408 return @shlExact(lhs << final_rhs >> final_rhs, final_rhs);
53865409}
53875410test shlExactUnsafe {
53885411 const test_shl_exact_unsafe = binary(shlExactUnsafe, .{});
53895412 try test_shl_exact_unsafe.testInts();
5413 try test_shl_exact_unsafe.testIntVectors();
53905414}
53915415
53925416inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type {
53935417 // workaround https://github.com/ziglang/zig/issues/23034
53945418 if (@inComptime()) {
53955419 // workaround https://github.com/ziglang/zig/issues/23139
5396 //return lhs <<| @min(@abs(rhs), imax(u64));
5397 return lhs <<| @min(@abs(rhs), @as(u64, imax(u64)));
5420 return lhs <<| @min(@abs(rhs), splat(ChangeScalar(Type, u64), imax(u64)));
53985421 }
53995422 // workaround https://github.com/ziglang/zig/issues/23033
54005423 @setRuntimeSafety(false);
......@@ -5403,6 +5426,7 @@ inline fn shlSat(comptime Type: type, lhs: Type, rhs: Type) Type {
54035426test shlSat {
54045427 const test_shl_sat = binary(shlSat, .{});
54055428 try test_shl_sat.testInts();
5429 try test_shl_sat.testIntVectors();
54065430}
54075431
54085432inline 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;
88pub const imax = math.maxInt;
99pub const imin = math.minInt;
1010pub const inf = math.inf;
11pub const Log2Int = math.Log2Int;
12pub const Log2IntCeil = math.Log2IntCeil;
1311pub const nan = math.nan;
1412pub const next = math.nextAfter;
1513pub const tmin = math.floatTrueMin;
......@@ -30,38 +28,44 @@ pub fn Scalar(comptime Type: type) type {
3028 .vector => |info| info.child,
3129 };
3230}
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}
3343pub fn AddOneBit(comptime Type: type) type {
34 const ResultScalar = switch (@typeInfo(Scalar(Type))) {
44 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
3545 .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = 1 + int.bits } }),
3646 .float => Scalar(Type),
3747 else => @compileError(@typeName(Type)),
38 };
39 return switch (@typeInfo(Type)) {
40 else => ResultScalar,
41 .vector => |vector| @Vector(vector.len, ResultScalar),
42 };
48 });
4349}
4450pub fn DoubleBits(comptime Type: type) type {
45 const ResultScalar = switch (@typeInfo(Scalar(Type))) {
51 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
4652 .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = int.bits * 2 } }),
4753 .float => Scalar(Type),
4854 else => @compileError(@typeName(Type)),
49 };
50 return switch (@typeInfo(Type)) {
51 else => ResultScalar,
52 .vector => |vector| @Vector(vector.len, ResultScalar),
53 };
55 });
5456}
5557pub fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type {
56 const ResultScalar = switch (@typeInfo(Scalar(Type))) {
58 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
5759 .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = std.mem.alignForward(u16, int.bits, multiple) } }),
5860 .float => Scalar(Type),
5961 else => @compileError(@typeName(Type)),
60 };
61 return switch (@typeInfo(Type)) {
62 else => ResultScalar,
63 .vector => |vector| @Vector(vector.len, ResultScalar),
64 };
62 });
63}
64pub fn Log2Int(comptime Type: type) type {
65 return ChangeScalar(Type, math.Log2Int(Scalar(Type)));
66}
67pub fn Log2IntCeil(comptime Type: type) type {
68 return ChangeScalar(Type, math.Log2IntCeil(Scalar(Type)));
6569}
6670// inline to avoid a runtime `@splat`
6771pub 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) {
7882 else => @compileError(@typeName(@TypeOf(cond))),
7983 };
8084}
81pub fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) {
82 else => bool,
83 .vector => |vector| @Vector(vector.len, bool),
84} {
85pub fn sign(rhs: anytype) ChangeScalar(@TypeOf(rhs), bool) {
8586 const ScalarInt = @Type(.{ .int = .{
8687 .signedness = .unsigned,
8788 .bits = @bitSizeOf(Scalar(@TypeOf(rhs))),
8889 } });
89 const VectorInt = switch (@typeInfo(@TypeOf(rhs))) {
90 else => ScalarInt,
91 .vector => |vector| @Vector(vector.len, ScalarInt),
92 };
90 const VectorInt = ChangeScalar(@TypeOf(rhs), ScalarInt);
9391 return @as(VectorInt, @bitCast(rhs)) & splat(VectorInt, @as(ScalarInt, 1) << @bitSizeOf(ScalarInt) - 1) != splat(VectorInt, 0);
9492}
9593fn 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)) {
48284828test ctz {
48294829 const test_ctz = unary(ctz, .{});
48304830 try test_ctz.testInts();
4831 try test_ctz.testIntVectors();
48314832}
48324833
48334834inline 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)) {
48364837test popCount {
48374838 const test_pop_count = unary(popCount, .{});
48384839 try test_pop_count.testInts();
4840 try test_pop_count.testIntVectors();
48394841}
48404842
48414843inline 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) {
48444846test byteSwap {
48454847 const test_byte_swap = unary(byteSwap, .{});
48464848 try test_byte_swap.testInts();
4849 try test_byte_swap.testIntVectors();
48474850}
48484851
48494852inline 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)) {
48524855test bitReverse {
48534856 const test_bit_reverse = unary(bitReverse, .{});
48544857 try test_bit_reverse.testInts();
4858 try test_bit_reverse.testIntVectors();
48554859}
48564860
48574861inline 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 {
117117// tmp.zig:37:38: note: imported here
118118// neg_inf.zon:1:1: error: expected type '?u8'
119119// 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'
121121// 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'
123123// 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'
125125// 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 {
1515// error
1616//
1717// :7:25: error: unable to resolve comptime value
18// :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_492.C' must be comptime-known
18// :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_496.C' must be comptime-known
1919// :4:16: note: struct requires comptime because of this field
2020// :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 {
1515 pub const castToNull = simple_panic.castToNull;
1616 pub const incorrectAlignment = simple_panic.incorrectAlignment;
1717 pub const invalidErrorCode = simple_panic.invalidErrorCode;
18 pub const castTruncatedData = simple_panic.castTruncatedData;
19 pub const negativeToUnsigned = simple_panic.negativeToUnsigned;
18 pub const integerOutOfBounds = simple_panic.integerOutOfBounds;
2019 pub const integerOverflow = simple_panic.integerOverflow;
2120 pub const shlOverflow = simple_panic.shlOverflow;
2221 pub const shrOverflow = simple_panic.shrOverflow;
......@@ -27,8 +26,6 @@ pub const panic = struct {
2726 pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig;
2827 pub const invalidEnumValue = simple_panic.invalidEnumValue;
2928 pub const forLenMismatch = simple_panic.forLenMismatch;
30 /// Delete after next zig1.wasm update
31 pub const memcpyLenMismatch = copyLenMismatch;
3229 pub const copyLenMismatch = simple_panic.copyLenMismatch;
3330 pub const memcpyAlias = simple_panic.memcpyAlias;
3431 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 {
1111 pub const castToNull = simple_panic.castToNull;
1212 pub const incorrectAlignment = simple_panic.incorrectAlignment;
1313 pub const invalidErrorCode = simple_panic.invalidErrorCode;
14 pub const castTruncatedData = simple_panic.castTruncatedData;
15 pub const negativeToUnsigned = simple_panic.negativeToUnsigned;
14 pub const integerOutOfBounds = simple_panic.integerOutOfBounds;
1615 pub const integerOverflow = simple_panic.integerOverflow;
1716 pub const shlOverflow = simple_panic.shlOverflow;
1817 pub const shrOverflow = simple_panic.shrOverflow;
......@@ -23,8 +22,6 @@ pub const panic = struct {
2322 pub const shiftRhsTooBig = simple_panic.shiftRhsTooBig;
2423 pub const invalidEnumValue = simple_panic.invalidEnumValue;
2524 pub const forLenMismatch = simple_panic.forLenMismatch;
26 /// Delete after next zig1.wasm update
27 pub const memcpyLenMismatch = copyLenMismatch;
2825 pub const copyLenMismatch = simple_panic.copyLenMismatch;
2926 pub const memcpyAlias = simple_panic.memcpyAlias;
3027 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 {
1616//
1717// :3:6: error: no field or member function named 'copy' in '[]const u8'
1818// :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'
2020// :12:6: note: struct declared here
test/cases/compile_errors/coerce_anon_struct.zig+1-1
......@@ -6,6 +6,6 @@ export fn foo() void {
66
77// error
88//
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'
1010// :3:16: note: struct declared here
1111// :1:11: note: struct declared here
test/cases/compile_errors/redundant_try.zig+2-2
......@@ -44,9 +44,9 @@ comptime {
4444//
4545// :5:23: error: expected error union type, found 'comptime_int'
4646// :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'
4848// :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'
5050// :20:27: note: struct declared here
5151// :25:23: error: expected error union type, found 'struct { comptime *const [5:0]u8 = "hello" }'
5252// :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 @@
1export fn entry() void {
2 const v: @Vector(4, u32) = [4]u32{ 10, 11, 12, 13 };
3 const x: @Vector(4, u32) = [4]u32{ 14, 15, 16, 17 };
4 const z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
5 _ = z;
1export fn foo() void {
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 a: @Vector(4, u32) = .{ 10, 11, 12, 13 };
4 const b: @Vector(4, u32) = .{ 14, 15, 16, 17 };
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 });
612}
713
814// error
9// backend=stage2
10// target=native
1115//
12// :4:41: error: mask index '4' has out-of-bounds selection
13// :4:29: note: selected index '7' out of bounds of '@Vector(4, u32)'
14// :4:32: note: selections from the second vector are specified with negative numbers
16// :5:35: error: mask element at index '4' selects out-of-bounds index
17// :5:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here
18// :11:35: error: mask element at index '4' selects out-of-bounds index
19// :11:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here
20// :11:26: note: use '~@as(u32, 7)' to index into second vector given here
test/cases/safety/@intCast to u0.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/cases/safety/memmove_len_mismatch.zig+1-1
......@@ -15,5 +15,5 @@ pub fn main() !void {
1515 return error.TestFailed;
1616}
1717// run
18// backend=llvm
18// backend=stage2,llvm
1919// 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");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 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");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/cases/safety/signed-unsigned vector cast.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 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
2323const std = @import("std");
2424
2525// run
26// backend=llvm
26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/slice_cast_change_len_1.zig+2-1
......@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu
2323const std = @import("std");
2424
2525// run
26// backend=llvm
26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/slice_cast_change_len_2.zig+2-1
......@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu
2323const std = @import("std");
2424
2525// run
26// backend=llvm
26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/truncating vector cast.zig +2-2
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
......@@ -17,5 +17,5 @@ pub fn main() !void {
1717}
1818
1919// run
20// backend=llvm
20// backend=stage2,llvm
2121// 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");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/cases/safety/unsigned-signed vector cast.zig +2-2
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
......@@ -17,5 +17,5 @@ pub fn main() !void {
1717}
1818
1919// run
20// backend=llvm
20// backend=stage2,llvm
2121// target=native
test/cases/safety/value does not fit in shortening cast - u0.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 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");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = 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")) {
66 std.process.exit(0);
77 }
88 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) {
1818 return a + b;
1919}
2020// run
21// backend=llvm
21// backend=stage2,llvm
2222// 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) {
1818 return a * b;
1919}
2020// run
21// backend=llvm
21// backend=stage2,llvm
2222// 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) {
1818 return -a;
1919}
2020// run
21// backend=llvm
21// backend=stage2,llvm
2222// 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) {
1818 return a - b;
1919}
2020// run
21// backend=llvm
21// backend=stage2,llvm
2222// target=native
test/incremental/change_panic_handler_explicit+3-12
......@@ -26,8 +26,7 @@ pub const panic = struct {
2626 pub const castToNull = no_panic.castToNull;
2727 pub const incorrectAlignment = no_panic.incorrectAlignment;
2828 pub const invalidErrorCode = no_panic.invalidErrorCode;
29 pub const castTruncatedData = no_panic.castTruncatedData;
30 pub const negativeToUnsigned = no_panic.negativeToUnsigned;
29 pub const integerOutOfBounds = no_panic.integerOutOfBounds;
3130 pub const shlOverflow = no_panic.shlOverflow;
3231 pub const shrOverflow = no_panic.shrOverflow;
3332 pub const divideByZero = no_panic.divideByZero;
......@@ -37,8 +36,6 @@ pub const panic = struct {
3736 pub const shiftRhsTooBig = no_panic.shiftRhsTooBig;
3837 pub const invalidEnumValue = no_panic.invalidEnumValue;
3938 pub const forLenMismatch = no_panic.forLenMismatch;
40 /// Delete after next zig1.wasm update
41 pub const memcpyLenMismatch = copyLenMismatch;
4239 pub const copyLenMismatch = no_panic.copyLenMismatch;
4340 pub const memcpyAlias = no_panic.memcpyAlias;
4441 pub const noreturnReturned = no_panic.noreturnReturned;
......@@ -75,8 +72,7 @@ pub const panic = struct {
7572 pub const castToNull = no_panic.castToNull;
7673 pub const incorrectAlignment = no_panic.incorrectAlignment;
7774 pub const invalidErrorCode = no_panic.invalidErrorCode;
78 pub const castTruncatedData = no_panic.castTruncatedData;
79 pub const negativeToUnsigned = no_panic.negativeToUnsigned;
75 pub const integerOutOfBounds = no_panic.integerOutOfBounds;
8076 pub const shlOverflow = no_panic.shlOverflow;
8177 pub const shrOverflow = no_panic.shrOverflow;
8278 pub const divideByZero = no_panic.divideByZero;
......@@ -86,8 +82,6 @@ pub const panic = struct {
8682 pub const shiftRhsTooBig = no_panic.shiftRhsTooBig;
8783 pub const invalidEnumValue = no_panic.invalidEnumValue;
8884 pub const forLenMismatch = no_panic.forLenMismatch;
89 /// Delete after next zig1.wasm update
90 pub const memcpyLenMismatch = copyLenMismatch;
9185 pub const copyLenMismatch = no_panic.copyLenMismatch;
9286 pub const memcpyAlias = no_panic.memcpyAlias;
9387 pub const noreturnReturned = no_panic.noreturnReturned;
......@@ -124,8 +118,7 @@ pub const panic = struct {
124118 pub const castToNull = no_panic.castToNull;
125119 pub const incorrectAlignment = no_panic.incorrectAlignment;
126120 pub const invalidErrorCode = no_panic.invalidErrorCode;
127 pub const castTruncatedData = no_panic.castTruncatedData;
128 pub const negativeToUnsigned = no_panic.negativeToUnsigned;
121 pub const integerOutOfBounds = no_panic.integerOutOfBounds;
129122 pub const shlOverflow = no_panic.shlOverflow;
130123 pub const shrOverflow = no_panic.shrOverflow;
131124 pub const divideByZero = no_panic.divideByZero;
......@@ -135,8 +128,6 @@ pub const panic = struct {
135128 pub const shiftRhsTooBig = no_panic.shiftRhsTooBig;
136129 pub const invalidEnumValue = no_panic.invalidEnumValue;
137130 pub const forLenMismatch = no_panic.forLenMismatch;
138 /// Delete after next zig1.wasm update
139 pub const memcpyLenMismatch = copyLenMismatch;
140131 pub const copyLenMismatch = no_panic.copyLenMismatch;
141132 pub const memcpyAlias = no_panic.memcpyAlias;
142133 pub const noreturnReturned = no_panic.noreturnReturned;
test/src/Cases.zig+17-3
......@@ -400,7 +400,7 @@ fn addFromDirInner(
400400 for (targets) |target_query| {
401401 const output = try manifest.trailingLinesSplit(ctx.arena);
402402 try ctx.translate.append(.{
403 .name = std.fs.path.stem(filename),
403 .name = try caseNameFromPath(ctx.arena, filename),
404404 .c_frontend = c_frontend,
405405 .target = b.resolveTargetQuery(target_query),
406406 .link_libc = link_libc,
......@@ -416,7 +416,7 @@ fn addFromDirInner(
416416 for (targets) |target_query| {
417417 const output = try manifest.trailingSplit(ctx.arena);
418418 try ctx.translate.append(.{
419 .name = std.fs.path.stem(filename),
419 .name = try caseNameFromPath(ctx.arena, filename),
420420 .c_frontend = c_frontend,
421421 .target = b.resolveTargetQuery(target_query),
422422 .link_libc = link_libc,
......@@ -454,7 +454,7 @@ fn addFromDirInner(
454454
455455 const next = ctx.cases.items.len;
456456 try ctx.cases.append(.{
457 .name = std.fs.path.stem(filename),
457 .name = try caseNameFromPath(ctx.arena, filename),
458458 .import_path = std.fs.path.dirname(filename),
459459 .backend = backend,
460460 .files = .init(ctx.arena),
......@@ -1138,3 +1138,17 @@ fn knownFileExtension(filename: []const u8) bool {
11381138 if (it.next() != null) return false;
11391139 return false;
11401140}
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 = {
601601 'fn_void_no_args': lambda payload: 'fn() void',
602602 'fn_naked_noreturn_no_args': lambda payload: 'fn() callconv(.naked) noreturn',
603603 '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',
605606 'manyptr_u8': lambda payload: '[*]u8',
606607 'manyptr_const_u8': lambda payload: '[*]const u8',
607608 'manyptr_const_u8_sentinel_0': lambda payload: '[*:0]const u8',