authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-14 19:57:42-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-15 01:04:21-04:00
logbb6b9c19e06320d8617f8858dde1ae6a7cf7fc5e
tree4c97b97424677a7edb129b9044e4855ce8946e62
parentc51930b060cf66b21c78b97e53fd71b153a5e60c

x86_64: fix lowering of non-pointer optional is null


1 files changed, 23 insertions(+), 20 deletions(-)

src/arch/x86_64/CodeGen.zig+23-20
...@@ -208,7 +208,7 @@ const Branch = struct {...@@ -208,7 +208,7 @@ const Branch = struct {
208};208};
209209
210const StackAllocation = struct {210const StackAllocation = struct {
211 inst: Air.Inst.Index,211 inst: ?Air.Inst.Index,
212 /// TODO do we need size? should be determined by inst.ty.abiSize(self.target.*)212 /// TODO do we need size? should be determined by inst.ty.abiSize(self.target.*)
213 size: u32,213 size: u32,
214};214};
...@@ -1109,7 +1109,7 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {...@@ -1109,7 +1109,7 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
1109 try table.ensureUnusedCapacity(self.gpa, additional_count);1109 try table.ensureUnusedCapacity(self.gpa, additional_count);
1110}1110}
11111111
1112fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u32 {1112fn allocMem(self: *Self, inst: ?Air.Inst.Index, abi_size: u32, abi_align: u32) !u32 {
1113 if (abi_align > self.stack_align)1113 if (abi_align > self.stack_align)
1114 self.stack_align = abi_align;1114 self.stack_align = abi_align;
1115 // TODO find a free slot instead of always appending1115 // TODO find a free slot instead of always appending
...@@ -1142,7 +1142,14 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1142,7 +1142,14 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1142}1142}
11431143
1144fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {1144fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
1145 const elem_ty = self.air.typeOfIndex(inst);1145 return self.allocRegOrMemAdvanced(self.air.typeOfIndex(inst), inst, reg_ok);
1146}
1147
1148fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
1149 return self.allocRegOrMemAdvanced(elem_ty, null, reg_ok);
1150}
1151
1152fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {
1146 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {1153 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1147 const mod = self.bin_file.options.module.?;1154 const mod = self.bin_file.options.module.?;
1148 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1155 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
...@@ -4571,18 +4578,16 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4571,18 +4578,16 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4571 };4578 };
4572 defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock);4579 defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock);
45734580
4574 const operand: MCValue = blk: {
4575 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
4576 // The MCValue that holds the pointer can be re-used as the value.
4577 break :blk operand_ptr;
4578 } else {
4579 break :blk try self.allocRegOrMem(inst, true);
4580 }
4581 };
4582 const ptr_ty = self.air.typeOf(un_op);4581 const ptr_ty = self.air.typeOf(un_op);
4582 const elem_ty = ptr_ty.childType();
4583 const operand = if (elem_ty.isPtrLikeOptional() and self.reuseOperand(inst, un_op, 0, operand_ptr))
4584 // The MCValue that holds the pointer can be re-used as the value.
4585 operand_ptr
4586 else
4587 try self.allocTempRegOrMem(elem_ty, true);
4583 try self.load(operand, operand_ptr, ptr_ty);4588 try self.load(operand, operand_ptr, ptr_ty);
45844589
4585 const result = try self.isNull(inst, ptr_ty.elemType(), operand);4590 const result = try self.isNull(inst, elem_ty, operand);
45864591
4587 return self.finishAir(inst, result, .{ un_op, .none, .none });4592 return self.finishAir(inst, result, .{ un_op, .none, .none });
4588}4593}
...@@ -4611,15 +4616,13 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4611,15 +4616,13 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4611 };4616 };
4612 defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock);4617 defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock);
46134618
4614 const operand: MCValue = blk: {
4615 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
4616 // The MCValue that holds the pointer can be re-used as the value.
4617 break :blk operand_ptr;
4618 } else {
4619 break :blk try self.allocRegOrMem(inst, true);
4620 }
4621 };
4622 const ptr_ty = self.air.typeOf(un_op);4619 const ptr_ty = self.air.typeOf(un_op);
4620 const elem_ty = ptr_ty.childType();
4621 const operand = if (elem_ty.isPtrLikeOptional() and self.reuseOperand(inst, un_op, 0, operand_ptr))
4622 // The MCValue that holds the pointer can be re-used as the value.
4623 operand_ptr
4624 else
4625 try self.allocTempRegOrMem(elem_ty, true);
4623 try self.load(operand, operand_ptr, ptr_ty);4626 try self.load(operand, operand_ptr, ptr_ty);
46244627
4625 const result = try self.isNonNull(inst, ptr_ty.elemType(), operand);4628 const result = try self.isNonNull(inst, ptr_ty.elemType(), operand);