authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-05-10 23:21:53-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-06-13 02:21:38-07:00
log7ed2f2156f4e93fa6463fb81f134c0d5e7e7cc89
treef4e137d7fe20f4799467a9eaa661a56e81bdfbc8
parent381a1043eb53971b9fe5bde088211d04e63dfd58
signaturelock-open Commit is signed but in an unrecognized format.

riscv: fix register clobber in certain edge cases


4 files changed, 12 insertions(+), 16 deletions(-)

src/arch/riscv64/CodeGen.zig+12-12
...@@ -1841,7 +1841,7 @@ fn airMinMax(...@@ -1841,7 +1841,7 @@ fn airMinMax(
1841 if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{});1841 if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{});
18421842
1843 const lhs_reg, const lhs_lock = blk: {1843 const lhs_reg, const lhs_lock = blk: {
1844 if (lhs == .register) break :blk .{ lhs.register, null };1844 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
18451845
1846 const lhs_reg, const lhs_lock = try self.allocReg();1846 const lhs_reg, const lhs_lock = try self.allocReg();
1847 try self.genSetReg(lhs_ty, lhs_reg, lhs);1847 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -1850,7 +1850,7 @@ fn airMinMax(...@@ -1850,7 +1850,7 @@ fn airMinMax(
1850 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);1850 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
18511851
1852 const rhs_reg, const rhs_lock = blk: {1852 const rhs_reg, const rhs_lock = blk: {
1853 if (rhs == .register) break :blk .{ rhs.register, null };1853 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
18541854
1855 const rhs_reg, const rhs_lock = try self.allocReg();1855 const rhs_reg, const rhs_lock = try self.allocReg();
1856 try self.genSetReg(rhs_ty, rhs_reg, rhs);1856 try self.genSetReg(rhs_ty, rhs_reg, rhs);
...@@ -2088,7 +2088,7 @@ fn binOpRegister(...@@ -2088,7 +2088,7 @@ fn binOpRegister(
2088 rhs_ty: Type,2088 rhs_ty: Type,
2089) !MCValue {2089) !MCValue {
2090 const lhs_reg, const lhs_lock = blk: {2090 const lhs_reg, const lhs_lock = blk: {
2091 if (lhs == .register) break :blk .{ lhs.register, null };2091 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
20922092
2093 const lhs_reg, const lhs_lock = try self.allocReg();2093 const lhs_reg, const lhs_lock = try self.allocReg();
2094 try self.genSetReg(lhs_ty, lhs_reg, lhs);2094 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -2097,7 +2097,7 @@ fn binOpRegister(...@@ -2097,7 +2097,7 @@ fn binOpRegister(
2097 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);2097 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
20982098
2099 const rhs_reg, const rhs_lock = blk: {2099 const rhs_reg, const rhs_lock = blk: {
2100 if (rhs == .register) break :blk .{ rhs.register, null };2100 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
21012101
2102 const rhs_reg, const rhs_lock = try self.allocReg();2102 const rhs_reg, const rhs_lock = try self.allocReg();
2103 try self.genSetReg(rhs_ty, rhs_reg, rhs);2103 try self.genSetReg(rhs_ty, rhs_reg, rhs);
...@@ -2358,7 +2358,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2358,7 +2358,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2358 const offset = result_mcv.load_frame;2358 const offset = result_mcv.load_frame;
23592359
2360 const lhs_reg, const lhs_lock = blk: {2360 const lhs_reg, const lhs_lock = blk: {
2361 if (lhs == .register) break :blk .{ lhs.register, null };2361 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
23622362
2363 const lhs_reg, const lhs_lock = try self.allocReg();2363 const lhs_reg, const lhs_lock = try self.allocReg();
2364 try self.genSetReg(lhs_ty, lhs_reg, lhs);2364 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -2367,7 +2367,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2367,7 +2367,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2367 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);2367 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
23682368
2369 const rhs_reg, const rhs_lock = blk: {2369 const rhs_reg, const rhs_lock = blk: {
2370 if (rhs == .register) break :blk .{ rhs.register, null };2370 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
23712371
2372 const rhs_reg, const rhs_lock = try self.allocReg();2372 const rhs_reg, const rhs_lock = try self.allocReg();
2373 try self.genSetReg(rhs_ty, rhs_reg, rhs);2373 try self.genSetReg(rhs_ty, rhs_reg, rhs);
...@@ -2596,7 +2596,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {...@@ -2596,7 +2596,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
2596 const rhs_ty = self.typeOf(bin_op.rhs);2596 const rhs_ty = self.typeOf(bin_op.rhs);
25972597
2598 const lhs_reg, const lhs_lock = blk: {2598 const lhs_reg, const lhs_lock = blk: {
2599 if (lhs == .register) break :blk .{ lhs.register, null };2599 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
26002600
2601 const lhs_reg, const lhs_lock = try self.allocReg();2601 const lhs_reg, const lhs_lock = try self.allocReg();
2602 try self.genSetReg(lhs_ty, lhs_reg, lhs);2602 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -2605,7 +2605,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {...@@ -2605,7 +2605,7 @@ fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
2605 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);2605 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
26062606
2607 const rhs_reg, const rhs_lock = blk: {2607 const rhs_reg, const rhs_lock = blk: {
2608 if (rhs == .register) break :blk .{ rhs.register, null };2608 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
26092609
2610 const rhs_reg, const rhs_lock = try self.allocReg();2610 const rhs_reg, const rhs_lock = try self.allocReg();
2611 try self.genSetReg(rhs_ty, rhs_reg, rhs);2611 try self.genSetReg(rhs_ty, rhs_reg, rhs);
...@@ -2641,7 +2641,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2641,7 +2641,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
2641 const rhs_ty = self.typeOf(bin_op.rhs);2641 const rhs_ty = self.typeOf(bin_op.rhs);
26422642
2643 const lhs_reg, const lhs_lock = blk: {2643 const lhs_reg, const lhs_lock = blk: {
2644 if (lhs == .register) break :blk .{ lhs.register, null };2644 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
26452645
2646 const lhs_reg, const lhs_lock = try self.allocReg();2646 const lhs_reg, const lhs_lock = try self.allocReg();
2647 try self.genSetReg(lhs_ty, lhs_reg, lhs);2647 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -2650,7 +2650,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2650,7 +2650,7 @@ fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
2650 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);2650 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
26512651
2652 const rhs_reg, const rhs_lock = blk: {2652 const rhs_reg, const rhs_lock = blk: {
2653 if (rhs == .register) break :blk .{ rhs.register, null };2653 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
26542654
2655 const rhs_reg, const rhs_lock = try self.allocReg();2655 const rhs_reg, const rhs_lock = try self.allocReg();
2656 try self.genSetReg(rhs_ty, rhs_reg, rhs);2656 try self.genSetReg(rhs_ty, rhs_reg, rhs);
...@@ -4717,7 +4717,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4717,7 +4717,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
4717 const rhs_ty = Type.bool;4717 const rhs_ty = Type.bool;
47184718
4719 const lhs_reg, const lhs_lock = blk: {4719 const lhs_reg, const lhs_lock = blk: {
4720 if (lhs == .register) break :blk .{ lhs.register, null };4720 if (lhs == .register) break :blk .{ lhs.register, self.register_manager.lockReg(lhs.register) };
47214721
4722 const lhs_reg, const lhs_lock = try self.allocReg();4722 const lhs_reg, const lhs_lock = try self.allocReg();
4723 try self.genSetReg(lhs_ty, lhs_reg, lhs);4723 try self.genSetReg(lhs_ty, lhs_reg, lhs);
...@@ -4726,7 +4726,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4726,7 +4726,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
4726 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);4726 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
47274727
4728 const rhs_reg, const rhs_lock = blk: {4728 const rhs_reg, const rhs_lock = blk: {
4729 if (rhs == .register) break :blk .{ rhs.register, null };4729 if (rhs == .register) break :blk .{ rhs.register, self.register_manager.lockReg(rhs.register) };
47304730
4731 const rhs_reg, const rhs_lock = try self.allocReg();4731 const rhs_reg, const rhs_lock = try self.allocReg();
4732 try self.genSetReg(rhs_ty, rhs_reg, rhs);4732 try self.genSetReg(rhs_ty, rhs_reg, rhs);
test/behavior/cast.zig-1
...@@ -677,7 +677,6 @@ test "@floatCast cast down" {...@@ -677,7 +677,6 @@ test "@floatCast cast down" {
677test "peer type resolution: unreachable, error set, unreachable" {677test "peer type resolution: unreachable, error set, unreachable" {
678 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO678 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
679 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO679 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
680 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
681680
682 const Error = error{681 const Error = error{
683 FileDescriptorAlreadyPresentInSet,682 FileDescriptorAlreadyPresentInSet,
test/behavior/enum.zig-2
...@@ -618,7 +618,6 @@ test "enum with specified tag values" {...@@ -618,7 +618,6 @@ test "enum with specified tag values" {
618test "non-exhaustive enum" {618test "non-exhaustive enum" {
619 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;619 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
620 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO620 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
621 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
622621
623 const S = struct {622 const S = struct {
624 const E = enum(u8) { a, b, _ };623 const E = enum(u8) { a, b, _ };
...@@ -683,7 +682,6 @@ test "empty non-exhaustive enum" {...@@ -683,7 +682,6 @@ test "empty non-exhaustive enum" {
683test "single field non-exhaustive enum" {682test "single field non-exhaustive enum" {
684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;683 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO684 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
686 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
687685
688 const S = struct {686 const S = struct {
689 const E = enum(u8) { a, _ };687 const E = enum(u8) { a, _ };
test/behavior/switch.zig-1
...@@ -216,7 +216,6 @@ fn poll() void {...@@ -216,7 +216,6 @@ fn poll() void {
216216
217test "switch on global mutable var isn't constant-folded" {217test "switch on global mutable var isn't constant-folded" {
218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
219 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
220219
221 while (state < 2) {220 while (state < 2) {
222 poll();221 poll();