authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-07-26 07:30:56-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-07-26 07:44:12-04:00
log3194a4d22b755393296a4db4c85d7b54ea83e96d
tree35981c33d9017f610722766e6b573bd8189b1145
parent68cfa736dfd38cc151af1f9e1b0edb3041bc237c

x86_64: fix dst create alloc reg clobbering src

Closes #24390

1 files changed, 22 insertions(+), 12 deletions(-)

src/arch/x86_64/CodeGen.zig+22-12
...@@ -191920,18 +191920,15 @@ const Select = struct {...@@ -191920,18 +191920,15 @@ const Select = struct {
191920 error.InvalidInstruction => {191920 error.InvalidInstruction => {
191921 const fixes = @tagName(mir_tag[0]);191921 const fixes = @tagName(mir_tag[0]);
191922 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;191922 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;
191923 return s.cg.fail(191923 return s.cg.fail("invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", .{
191924 "invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'",191924 fixes[0..fixes_blank],
191925 .{191925 @tagName(mir_tag[1]),
191926 fixes[0..fixes_blank],191926 fixes[fixes_blank + 1 ..],
191927 @tagName(mir_tag[1]),191927 @tagName(mir_ops[0]),
191928 fixes[fixes_blank + 1 ..],191928 @tagName(mir_ops[1]),
191929 @tagName(mir_ops[0]),191929 @tagName(mir_ops[2]),
191930 @tagName(mir_ops[1]),191930 @tagName(mir_ops[3]),
191931 @tagName(mir_ops[2]),191931 });
191932 @tagName(mir_ops[3]),
191933 },
191934 );
191935 },191932 },
191936 else => |e| return e,191933 else => |e| return e,
191937 };191934 };
...@@ -194423,6 +194420,18 @@ fn select(...@@ -194423,6 +194420,18 @@ fn select(
194423 while (true) for (pattern.src[0..src_temps.len], src_temps) |src_pattern, *src_temp| {194420 while (true) for (pattern.src[0..src_temps.len], src_temps) |src_pattern, *src_temp| {
194424 if (try src_pattern.convert(src_temp, cg)) break;194421 if (try src_pattern.convert(src_temp, cg)) break;
194425 } else break;194422 } else break;
194423 var src_locks: [s_src_temps.len][2]?RegisterLock = @splat(@splat(null));
194424 for (src_locks[0..src_temps.len], src_temps) |*locks, src_temp| {
194425 const regs: [2]Register = switch (src_temp.tracking(cg).short) {
194426 else => continue,
194427 .register => |reg| .{ reg, .none },
194428 .register_pair => |regs| regs,
194429 };
194430 for (regs, locks) |reg, *lock| {
194431 if (reg == .none) continue;
194432 lock.* = cg.register_manager.lockRegIndex(RegisterManager.indexOfRegIntoTracked(reg) orelse continue);
194433 }
194434 }
194426 @memcpy(s_src_temps[0..src_temps.len], src_temps);194435 @memcpy(s_src_temps[0..src_temps.len], src_temps);
194427 std.mem.swap(Temp, &s_src_temps[pattern.commute[0]], &s_src_temps[pattern.commute[1]]);194436 std.mem.swap(Temp, &s_src_temps[pattern.commute[0]], &s_src_temps[pattern.commute[1]]);
194428194437
...@@ -194441,6 +194450,7 @@ fn select(...@@ -194441,6 +194450,7 @@ fn select(
194441 }194450 }
194442 assert(s.top == 0);194451 assert(s.top == 0);
194443194452
194453 for (src_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194444 for (tmp_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);194454 for (tmp_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194445 for (dst_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);194455 for (dst_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194446 caller_preserved: {194456 caller_preserved: {