zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 05b12e677939effa9da147008071908a2a93fe35 (tree)
parent 238615984064f52b6ff31b5750824a9c764fdb15
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date:   Tue, 14 Mar 2023 22:32:00 -0400

x86_64: handle duplicate prong deaths

Diffstat:
Msrc/arch/x86_64/CodeGen.zig | 13++++++-------
Mtest/behavior/inline_switch.zig | 1-
Mtest/behavior/union.zig | 2--
Mtest/behavior/union_with_members.zig | 1-
4 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig @@ -1037,9 +1037,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { fn processDeath(self: *Self, inst: Air.Inst.Index) void { const air_tags = self.air.instructions.items(.tag); if (air_tags[inst] == .constant) return; // Constants are immortal. + const prev_value = self.getResolvedInstValue(inst) orelse return; log.debug("%{d} => {}", .{ inst, MCValue.dead }); // When editing this function, note that the logic must synchronize with `reuseOperand`. - const prev_value = self.getResolvedInstValue(inst); const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; branch.inst_table.putAssumeCapacity(inst, .dead); switch (prev_value) { @@ -1225,7 +1225,7 @@ fn revertState(self: *Self, state: State) void { pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { const stack_mcv = try self.allocRegOrMem(inst, false); log.debug("spilling %{d} to stack mcv {any}", .{ inst, stack_mcv }); - const reg_mcv = self.getResolvedInstValue(inst); + const reg_mcv = self.getResolvedInstValue(inst).?; switch (reg_mcv) { .register => |other| { assert(reg.to64() == other.to64()); @@ -1242,7 +1242,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void pub fn spillEflagsIfOccupied(self: *Self) !void { if (self.eflags_inst) |inst_to_save| { - const mcv = self.getResolvedInstValue(inst_to_save); + const mcv = self.getResolvedInstValue(inst_to_save).?; const new_mcv = switch (mcv) { .register_overflow => try self.allocRegOrMem(inst_to_save, false), .eflags => try self.allocRegOrMem(inst_to_save, true), @@ -6315,18 +6315,17 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { return gop.value_ptr.*; }, .const_ty => unreachable, - else => return self.getResolvedInstValue(inst_index), + else => return self.getResolvedInstValue(inst_index).?, } } -fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { +fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) ?MCValue { // Treat each stack item as a "layer" on top of the previous one. var i: usize = self.branch_stack.items.len; while (true) { i -= 1; if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| { - assert(mcv != .dead); - return mcv; + return if (mcv != .dead) mcv else null; } } } diff --git a/test/behavior/inline_switch.zig b/test/behavior/inline_switch.zig @@ -46,7 +46,6 @@ const U = union(E) { a: void, b: u2, c: u3, d: u4 }; test "inline switch unions" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var x: U = .a; diff --git a/test/behavior/union.zig b/test/behavior/union.zig @@ -214,7 +214,6 @@ const Payload = union(Letter) { }; test "union with specified enum tag" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -224,7 +223,6 @@ test "union with specified enum tag" { } test "packed union generates correctly aligned type" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/union_with_members.zig b/test/behavior/union_with_members.zig @@ -18,7 +18,6 @@ const ET = union(enum) { test "enum with members" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO