Skip to content

Commit 9827ffe

Browse files
jacobly0andrewrk
authored andcommitted
x86_64: fix incorrect handling of unreusable operands
Closes #23448
1 parent 95fdbc5 commit 9827ffe

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104889,8 +104889,9 @@ const Temp = struct {
104889104889
const result_temp: Temp = .{ .index = result_temp_index.toIndex() };
104890104890
assert(cg.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking));
104891104891
assert(cg.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking));
104892-
cg.temp_type[@intFromEnum(result_temp_index)] = .slice_const_u8;
104893104892
result_temp_index.tracking(cg).* = .init(result);
104893+
cg.temp_type[@intFromEnum(result_temp_index)] = .slice_const_u8;
104894+
cg.next_temp_index = @enumFromInt(@intFromEnum(result_temp_index) + 1);
104894104895
first_temp.* = result_temp;
104895104896
second_temp.* = result_temp;
104896104897
}
@@ -109598,7 +109599,8 @@ const Temp = struct {
109598109599
) InnerError!void {
109599109600
const tomb_bits = cg.liveness.getTombBits(inst);
109600109601
for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| {
109601-
if (op_temp.index != temp.index and op_temp.tracking(cg).short != .dead) try op_temp.die(cg);
109602+
if (op_temp.index == temp.index) continue;
109603+
if (op_temp.tracking(cg).short != .dead) try op_temp.die(cg);
109602109604
if (tomb_bits & @as(Liveness.Bpi, 1) << @intCast(op_index) == 0) continue;
109603109605
if (cg.reused_operands.isSet(op_index)) continue;
109604109606
try cg.processDeath(op_ref.toIndexAllowNone() orelse continue);
@@ -109617,6 +109619,12 @@ const Temp = struct {
109617109619
assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking));
109618109620
},
109619109621
}
109622+
for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| {
109623+
if (op_temp.index != temp.index) continue;
109624+
if (tomb_bits & @as(Liveness.Bpi, 1) << @intCast(op_index) == 0) continue;
109625+
if (cg.reused_operands.isSet(op_index)) continue;
109626+
try cg.processDeath(op_ref.toIndexAllowNone() orelse continue);
109627+
}
109620109628
}
109621109629

109622109630
fn die(temp: Temp, cg: *CodeGen) InnerError!void {
@@ -109642,7 +109650,8 @@ const Temp = struct {
109642109650
}
109643109651

109644109652
fn isValid(index: Index, cg: *CodeGen) bool {
109645-
return index.tracking(cg).short != .dead;
109653+
return @intFromEnum(index) < @intFromEnum(cg.next_temp_index) and
109654+
index.tracking(cg).short != .dead;
109646109655
}
109647109656

109648109657
fn typeOf(index: Index, cg: *CodeGen) Type {

test/behavior/struct.zig

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ test "optional generic function label struct field" {
15271527
}
15281528

15291529
test "struct fields get automatically reordered" {
1530-
if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO
1530+
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
15311531

15321532
const S1 = struct {
15331533
a: u32,
@@ -2137,3 +2137,45 @@ test "anonymous struct equivalence" {
21372137
comptime assert(A != C);
21382138
comptime assert(B != C);
21392139
}
2140+
2141+
test "field access through mem ptr arg" {
2142+
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2143+
2144+
const S = struct {
2145+
fn nestedFieldAccess(
2146+
_: usize,
2147+
_: usize,
2148+
_: usize,
2149+
_: usize,
2150+
_: usize,
2151+
_: usize,
2152+
_: usize,
2153+
_: usize,
2154+
ptr_struct: *const struct { field: u32 },
2155+
) u32 {
2156+
return ptr_struct.field;
2157+
}
2158+
};
2159+
try expect(S.nestedFieldAccess(
2160+
undefined,
2161+
undefined,
2162+
undefined,
2163+
undefined,
2164+
undefined,
2165+
undefined,
2166+
undefined,
2167+
undefined,
2168+
&.{ .field = 0x6b00a2eb },
2169+
) == 0x6b00a2eb);
2170+
comptime assert(S.nestedFieldAccess(
2171+
undefined,
2172+
undefined,
2173+
undefined,
2174+
undefined,
2175+
undefined,
2176+
undefined,
2177+
undefined,
2178+
undefined,
2179+
&.{ .field = 0x0ced271f },
2180+
) == 0x0ced271f);
2181+
}

0 commit comments

Comments
 (0)