authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-07 00:45:14-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-13 04:17:47-04:00
logcaa3d6a4f4413c1cace517b073476780168f24cf
treebe23d04a3bc5e236b6b962d0c7f000ed08bfb655
parent3b22ce82643f2e547c85bf4b17477bc27133eb42

x86_64: fix constant pointers to zero-bit types

These non-dereferencable pointers still need to have the correct alignment and non-null-ness.

3 files changed, 21 insertions(+), 9 deletions(-)

src/arch/x86_64/CodeGen.zig+12-3
...@@ -1080,7 +1080,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1080,7 +1080,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
10801080
1081 .constant => unreachable, // excluded from function bodies1081 .constant => unreachable, // excluded from function bodies
1082 .const_ty => unreachable, // excluded from function bodies1082 .const_ty => unreachable, // excluded from function bodies
1083 .unreach => self.finishAirBookkeeping(),1083 .unreach => if (self.wantSafety()) try self.airTrap() else self.finishAirBookkeeping(),
10841084
1085 .optional_payload => try self.airOptionalPayload(inst),1085 .optional_payload => try self.airOptionalPayload(inst),
1086 .optional_payload_ptr => try self.airOptionalPayloadPtr(inst),1086 .optional_payload_ptr => try self.airOptionalPayloadPtr(inst),
...@@ -6273,6 +6273,15 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -6273,6 +6273,15 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
62736273
6274 const block_data = self.blocks.getPtr(inst).?;6274 const block_data = self.blocks.getPtr(inst).?;
6275 const target_branch = self.branch_stack.pop();6275 const target_branch = self.branch_stack.pop();
6276
6277 log.debug("airBlock: %{d}", .{inst});
6278 log.debug("Upper branches:", .{});
6279 for (self.branch_stack.items) |bs| {
6280 log.debug("{}", .{bs.fmtDebug()});
6281 }
6282 log.debug("Block branch: {}", .{block_data.branch.fmtDebug()});
6283 log.debug("Target branch: {}", .{target_branch.fmtDebug()});
6284
6276 try self.canonicaliseBranches(true, &block_data.branch, &target_branch, false, false);6285 try self.canonicaliseBranches(true, &block_data.branch, &target_branch, false, false);
62776286
6278 for (block_data.relocs.items) |reloc| try self.performReloc(reloc);6287 for (block_data.relocs.items) |reloc| try self.performReloc(reloc);
...@@ -6444,7 +6453,7 @@ fn canonicaliseBranches(...@@ -6444,7 +6453,7 @@ fn canonicaliseBranches(
6444 // If integer overflow occurs, the question is: why wasn't the instruction marked dead?6453 // If integer overflow occurs, the question is: why wasn't the instruction marked dead?
6445 break :blk self.getResolvedInstValue(target_key).?.*;6454 break :blk self.getResolvedInstValue(target_key).?.*;
6446 };6455 };
6447 log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv });6456 log.debug("consolidating target_entry %{d} {}=>{}", .{ target_key, target_value, canon_mcv });
6448 // TODO handle the case where the destination stack offset / register has something6457 // TODO handle the case where the destination stack offset / register has something
6449 // going on there.6458 // going on there.
6450 assert(!hazard_map.contains(target_value));6459 assert(!hazard_map.contains(target_value));
...@@ -6466,7 +6475,7 @@ fn canonicaliseBranches(...@@ -6466,7 +6475,7 @@ fn canonicaliseBranches(
6466 const parent_mcv =6475 const parent_mcv =
6467 if (canon_value != .dead) self.getResolvedInstValue(canon_key).?.* else undefined;6476 if (canon_value != .dead) self.getResolvedInstValue(canon_key).?.* else undefined;
6468 if (canon_value != .dead) {6477 if (canon_value != .dead) {
6469 log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value });6478 log.debug("consolidating canon_entry %{d} {}=>{}", .{ canon_key, parent_mcv, canon_value });
6470 // TODO handle the case where the destination stack offset / register has something6479 // TODO handle the case where the destination stack offset / register has something
6471 // going on there.6480 // going on there.
6472 assert(!hazard_map.contains(parent_mcv));6481 assert(!hazard_map.contains(parent_mcv));
src/codegen.zig+9-5
...@@ -966,7 +966,7 @@ fn genDeclRef(...@@ -966,7 +966,7 @@ fn genDeclRef(
966 const module = bin_file.options.module.?;966 const module = bin_file.options.module.?;
967 const decl = module.declPtr(decl_index);967 const decl = module.declPtr(decl_index);
968968
969 if (decl.ty.zigTypeTag() != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime()) {969 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime()) {
970 const imm: u64 = switch (ptr_bytes) {970 const imm: u64 = switch (ptr_bytes) {
971 1 => 0xaa,971 1 => 0xaa,
972 2 => 0xaaaa,972 2 => 0xaaaa,
...@@ -978,10 +978,14 @@ fn genDeclRef(...@@ -978,10 +978,14 @@ fn genDeclRef(
978 }978 }
979979
980 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?980 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
981 if (tv.ty.zigTypeTag() == .Pointer) blk: {981 if (tv.ty.castPtrToFn()) |fn_ty| {
982 if (tv.ty.castPtrToFn()) |_| break :blk;982 if (fn_ty.fnInfo().is_generic) {
983 if (!tv.ty.elemType2().hasRuntimeBits()) {983 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(target) });
984 return GenResult.mcv(.none);984 }
985 } else if (tv.ty.zigTypeTag() == .Pointer) {
986 const elem_ty = tv.ty.elemType2();
987 if (!elem_ty.hasRuntimeBits()) {
988 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(target) });
985 }989 }
986 }990 }
987991
test/behavior/pointers.zig-1
...@@ -506,7 +506,6 @@ test "ptrToInt on a generic function" {...@@ -506,7 +506,6 @@ test "ptrToInt on a generic function" {
506 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO506 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO508 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
510509
511 const S = struct {510 const S = struct {
512 fn generic(i: anytype) @TypeOf(i) {511 fn generic(i: anytype) @TypeOf(i) {