riscv: fix register clobber in certain edge cases

This commit is contained in:
David Rubin 2024-05-10 23:21:53 -07:00
parent 381a1043eb
commit 7ed2f2156f
No known key found for this signature in database
GPG Key ID: C326E694CED89F6D
4 changed files with 12 additions and 16 deletions

View File

@ -1841,7 +1841,7 @@ fn airMinMax(
if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{}); if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{});
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -1850,7 +1850,7 @@ fn airMinMax(
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);
@ -2088,7 +2088,7 @@ fn binOpRegister(
rhs_ty: Type, rhs_ty: Type,
) !MCValue { ) !MCValue {
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -2097,7 +2097,7 @@ fn binOpRegister(
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);
@ -2358,7 +2358,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const offset = result_mcv.load_frame; const offset = result_mcv.load_frame;
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -2367,7 +2367,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);
@ -2596,7 +2596,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
const rhs_ty = self.typeOf(bin_op.rhs); const rhs_ty = self.typeOf(bin_op.rhs);
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -2605,7 +2605,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);
@ -2641,7 +2641,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
const rhs_ty = self.typeOf(bin_op.rhs); const rhs_ty = self.typeOf(bin_op.rhs);
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -2650,7 +2650,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);
@ -4717,7 +4717,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
const rhs_ty = Type.bool; const rhs_ty = Type.bool;
const lhs_reg, const lhs_lock = blk: { const lhs_reg, const lhs_lock = blk: {
if (lhs == .register) break :blk .{ lhs.register, null }; if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
const lhs_reg, const lhs_lock = try self.allocReg(); const lhs_reg, const lhs_lock = try self.allocReg();
try self.genSetReg(lhs_ty, lhs_reg, lhs); try self.genSetReg(lhs_ty, lhs_reg, lhs);
@ -4726,7 +4726,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
const rhs_reg, const rhs_lock = blk: { const rhs_reg, const rhs_lock = blk: {
if (rhs == .register) break :blk .{ rhs.register, null }; if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
const rhs_reg, const rhs_lock = try self.allocReg(); const rhs_reg, const rhs_lock = try self.allocReg();
try self.genSetReg(rhs_ty, rhs_reg, rhs); try self.genSetReg(rhs_ty, rhs_reg, rhs);

View File

@ -677,7 +677,6 @@ test "@floatCast cast down" {
test "peer type resolution: unreachable, error set, unreachable" { test "peer type resolution: unreachable, error set, unreachable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Error = error{ const Error = error{
FileDescriptorAlreadyPresentInSet, FileDescriptorAlreadyPresentInSet,

View File

@ -618,7 +618,6 @@ test "enum with specified tag values" {
test "non-exhaustive enum" { test "non-exhaustive enum" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct { const S = struct {
const E = enum(u8) { a, b, _ }; const E = enum(u8) { a, b, _ };
@ -683,7 +682,6 @@ test "empty non-exhaustive enum" {
test "single field non-exhaustive enum" { test "single field non-exhaustive enum" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct { const S = struct {
const E = enum(u8) { a, _ }; const E = enum(u8) { a, _ };

View File

@ -216,7 +216,6 @@ fn poll() void {
test "switch on global mutable var isn't constant-folded" { test "switch on global mutable var isn't constant-folded" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
while (state < 2) { while (state < 2) {
poll(); poll();