diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-03-02 14:29:48 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-03-02 14:34:43 +0100 |
| commit | 350bf9db131dd5573da0d06d38e40746c99a8a34 (patch) | |
| tree | 386bed9ea764d82d76468dac1253be0975a62ee6 /src | |
| parent | d35cae551ed5f3e6082b2e599f9c258af9d2630e (diff) | |
| download | zig-350bf9db131dd5573da0d06d38e40746c99a8a34.tar.gz zig-350bf9db131dd5573da0d06d38e40746c99a8a34.zip | |
x64: fix intCast to properly clear out dest register
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 3ecf4a70aa..8efb1042ef 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -981,7 +981,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { operand.freezeIfRegister(&self.register_manager); defer operand.unfreezeIfRegister(&self.register_manager); - break :blk try self.copyToRegisterWithInstTracking(inst, dest_ty, operand); + const reg = try self.register_manager.allocReg(inst); + try self.genSetReg(dest_ty, reg, .{ .immediate = 0 }); + try self.genSetReg(operand_ty, reg, operand); + break :blk MCValue{ .register = reg }; }; return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); @@ -1851,22 +1854,29 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { - const payload_ty = self.air.typeOf(ty_op.operand); + if (self.liveness.isUnused(inst)) { + return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); + } + + const payload_ty = self.air.typeOf(ty_op.operand); + const result: MCValue = result: { if (!payload_ty.hasRuntimeBits()) { break :result MCValue{ .immediate = 1 }; } const optional_ty = self.air.typeOfIndex(inst); const operand = try self.resolveInst(ty_op.operand); + operand.freezeIfRegister(&self.register_manager); + defer operand.unfreezeIfRegister(&self.register_manager); + if (optional_ty.isPtrLikeOptional()) { // TODO should we check if we can reuse the operand? - break :result operand; + if (self.reuseOperand(inst, ty_op.operand, 0, operand)) { + break :result operand; + } + break :result try self.copyToRegisterWithInstTracking(inst, payload_ty, operand); } - operand.freezeIfRegister(&self.register_manager); - defer operand.unfreezeIfRegister(&self.register_manager); - const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*)); const optional_abi_align = optional_ty.abiAlignment(self.target.*); const payload_abi_size = @intCast(u32, payload_ty.abiSize(self.target.*)); |
