aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-03-02 14:29:48 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-03-02 14:34:43 +0100
commit350bf9db131dd5573da0d06d38e40746c99a8a34 (patch)
tree386bed9ea764d82d76468dac1253be0975a62ee6 /src
parentd35cae551ed5f3e6082b2e599f9c258af9d2630e (diff)
downloadzig-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.zig24
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.*));