authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-02 14:29:48+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-02 14:34:43+01:00
log350bf9db131dd5573da0d06d38e40746c99a8a34
tree386bed9ea764d82d76468dac1253be0975a62ee6
parentd35cae551ed5f3e6082b2e599f9c258af9d2630e

x64: fix intCast to properly clear out dest register


2 files changed, 18 insertions(+), 16 deletions(-)

src/arch/x86_64/CodeGen.zig+17-7
......@@ -981,7 +981,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
981981 operand.freezeIfRegister(&self.register_manager);
982982 defer operand.unfreezeIfRegister(&self.register_manager);
983983
984 break :blk try self.copyToRegisterWithInstTracking(inst, dest_ty, operand);
984 const reg = try self.register_manager.allocReg(inst);
985 try self.genSetReg(dest_ty, reg, .{ .immediate = 0 });
986 try self.genSetReg(operand_ty, reg, operand);
987 break :blk MCValue{ .register = reg };
985988 };
986989
987990 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
......@@ -1851,22 +1854,29 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
18511854
18521855fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
18531856 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1854 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1855 const payload_ty = self.air.typeOf(ty_op.operand);
1857 if (self.liveness.isUnused(inst)) {
1858 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
1859 }
1860
1861 const payload_ty = self.air.typeOf(ty_op.operand);
1862 const result: MCValue = result: {
18561863 if (!payload_ty.hasRuntimeBits()) {
18571864 break :result MCValue{ .immediate = 1 };
18581865 }
18591866
18601867 const optional_ty = self.air.typeOfIndex(inst);
18611868 const operand = try self.resolveInst(ty_op.operand);
1869 operand.freezeIfRegister(&self.register_manager);
1870 defer operand.unfreezeIfRegister(&self.register_manager);
1871
18621872 if (optional_ty.isPtrLikeOptional()) {
18631873 // TODO should we check if we can reuse the operand?
1864 break :result operand;
1874 if (self.reuseOperand(inst, ty_op.operand, 0, operand)) {
1875 break :result operand;
1876 }
1877 break :result try self.copyToRegisterWithInstTracking(inst, payload_ty, operand);
18651878 }
18661879
1867 operand.freezeIfRegister(&self.register_manager);
1868 defer operand.unfreezeIfRegister(&self.register_manager);
1869
18701880 const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));
18711881 const optional_abi_align = optional_ty.abiAlignment(self.target.*);
18721882 const payload_abi_size = @intCast(u32, payload_ty.abiSize(self.target.*));
test/behavior/cast.zig+1-9
......@@ -302,7 +302,7 @@ fn implicitIntLitToOptional() void {
302302
303303test "return u8 coercing into ?u32 return type" {
304304 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
305 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
306306
307307 const S = struct {
308308 fn doTheTest() !void {
......@@ -373,7 +373,6 @@ fn testPeerResolveArrayConstSlice(b: bool) !void {
373373test "implicitly cast from T to anyerror!?T" {
374374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
375375 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
376 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
377376
378377 try castToOptionalTypeError(1);
379378 comptime try castToOptionalTypeError(1);
......@@ -1036,7 +1035,6 @@ test "implicit cast from [*]T to ?*anyopaque" {
10361035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10371036 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10381037 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1039 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10401038
10411039 var a = [_]u8{ 3, 2, 1 };
10421040 var runtime_zero: usize = 0;
......@@ -1073,7 +1071,6 @@ test "implicit ptr to *anyopaque" {
10731071 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10741072 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10751073 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1076 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10771074
10781075 var a: u32 = 1;
10791076 var ptr: *align(@alignOf(u32)) anyopaque = &a;
......@@ -1087,7 +1084,6 @@ test "implicit ptr to *anyopaque" {
10871084test "return null from fn() anyerror!?&T" {
10881085 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10891086 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1090 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10911087
10921088 const a = returnNullFromOptionalTypeErrorRef();
10931089 const b = returnNullLitFromOptionalTypeErrorRef();
......@@ -1125,7 +1121,6 @@ test "implicitly cast from [N]T to ?[]const T" {
11251121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11261122 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11271123 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1128 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11291124
11301125 try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
11311126 comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
......@@ -1177,7 +1172,6 @@ test "implicit cast from *T to ?*anyopaque" {
11771172 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11781173 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11791174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1180 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11811175
11821176 var a: u8 = 1;
11831177 incrementVoidPtrValue(&a);
......@@ -1213,7 +1207,6 @@ test "*const [N]null u8 to ?[]const u8" {
12131207 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12141208 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12151209 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1216 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12171210
12181211 const S = struct {
12191212 fn doTheTest() !void {
......@@ -1249,7 +1242,6 @@ test "assignment to optional pointer result loc" {
12491242 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12501243 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12511244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1252 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12531245
12541246 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
12551247 try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct));