authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 18:19:25+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 23:20:05+01:00
log12cdb36c5ba1fd9dfa5985d36a2f5955528c2de7
treeb28b98a8c43ad1a81eeac26e2a07d7acbb38ebf9
parent05431d7c4a8cb20a3a70553ef0d0f8ed00a05402

codegen: fix padding calculation for error unions when lowering

* do not track `rdi` register before `call` inst, but instead freeze it from further use, until `call` has been realised * pass more error union tests

3 files changed, 21 insertions(+), 33 deletions(-)

src/arch/x86_64/CodeGen.zig+3-1
......@@ -3167,11 +3167,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
31673167 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));
31683168 const stack_offset = @intCast(i32, try self.allocMem(inst, ret_abi_size, ret_abi_align));
31693169
3170 try self.register_manager.getReg(.rdi, inst);
3170 try self.register_manager.getReg(.rdi, null);
3171 self.register_manager.freezeRegs(&.{.rdi});
31713172 try self.genSetReg(Type.usize, .rdi, .{ .ptr_stack_offset = stack_offset });
31723173
31733174 info.return_value.stack_offset = stack_offset;
31743175 }
3176 defer if (info.return_value == .stack_offset) self.register_manager.unfreezeRegs(&.{.rdi});
31753177
31763178 for (args) |arg, arg_i| {
31773179 const mc_arg = info.args[arg_i];
src/codegen.zig+18-27
......@@ -553,31 +553,21 @@ pub fn generateSymbol(
553553 const target = bin_file.options.target;
554554 const abi_align = typed_value.ty.abiAlignment(target);
555555
556 {
557 const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero);
558 const begin = code.items.len;
559 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
560 .ty = error_ty,
561 .val = error_val,
562 }, code, debug_output)) {
563 .appended => {},
564 .externally_managed => |external_slice| {
565 code.appendSliceAssumeCapacity(external_slice);
566 },
567 .fail => |em| return Result{ .fail = em },
568 }
569 const unpadded_end = code.items.len - begin;
570 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);
571 const padding = try math.cast(usize, padded_end - unpadded_end);
572
573 if (padding > 0) {
574 try code.writer().writeByteNTimes(0, padding);
575 }
556 const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero);
557 const begin = code.items.len;
558 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
559 .ty = error_ty,
560 .val = error_val,
561 }, code, debug_output)) {
562 .appended => {},
563 .externally_managed => |external_slice| {
564 code.appendSliceAssumeCapacity(external_slice);
565 },
566 .fail => |em| return Result{ .fail = em },
576567 }
577568
578569 if (payload_ty.hasRuntimeBits()) {
579570 const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef);
580 const begin = code.items.len;
581571 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
582572 .ty = payload_ty,
583573 .val = payload_val,
......@@ -588,13 +578,14 @@ pub fn generateSymbol(
588578 },
589579 .fail => |em| return Result{ .fail = em },
590580 }
591 const unpadded_end = code.items.len - begin;
592 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);
593 const padding = try math.cast(usize, padded_end - unpadded_end);
581 }
594582
595 if (padding > 0) {
596 try code.writer().writeByteNTimes(0, padding);
597 }
583 const unpadded_end = code.items.len - begin;
584 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);
585 const padding = try math.cast(usize, padded_end - unpadded_end);
586
587 if (padding > 0) {
588 try code.writer().writeByteNTimes(0, padding);
598589 }
599590
600591 return Result{ .appended = {} };
test/behavior/error.zig-5
......@@ -23,7 +23,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
2323}
2424
2525test "error binary operator" {
26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2726 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2827 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2928
......@@ -58,7 +57,6 @@ pub fn baz() anyerror!i32 {
5857}
5958
6059test "error wrapping" {
61 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
6260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6361 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6462
......@@ -66,7 +64,6 @@ test "error wrapping" {
6664}
6765
6866test "unwrap simple value from error" {
69 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7067 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7269
......@@ -102,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {
10299}
103100
104101test "widen cast integer payload of error union function call" {
105 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
106102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
107103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
108104
......@@ -307,7 +303,6 @@ test "error: Infer error set from literals" {
307303 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
308304 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
309305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
311306 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
312307
313308 _ = nullLiteral("n") catch |err| handleErrors(err);