x86_64: fix crashes

This commit is contained in:
Jacob Young 2023-10-18 01:24:17 -04:00
parent b403ca0aab
commit 9358a7528f
4 changed files with 40 additions and 20 deletions

View file

@ -3798,11 +3798,13 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
} }
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op; const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: { const result: MCValue = result: {
const pl_ty = self.typeOfIndex(inst); const pl_ty = self.typeOfIndex(inst);
const opt_mcv = try self.resolveInst(ty_op.operand); if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
const opt_mcv = try self.resolveInst(ty_op.operand);
if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
switch (opt_mcv) { switch (opt_mcv) {
.register => |reg| try self.truncateRegister(pl_ty, reg), .register => |reg| try self.truncateRegister(pl_ty, reg),
@ -11521,10 +11523,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
.undef => {}, .undef => {},
.immediate => |imm| switch (abi_size) { .immediate => |imm| switch (abi_size) {
1, 2, 4 => { 1, 2, 4 => {
const immediate = if (ty.isSignedInt(mod)) const immediate = switch (if (ty.isAbiInt(mod))
Immediate.s(@truncate(@as(i64, @bitCast(imm)))) ty.intInfo(mod).signedness
else else
Immediate.u(@as(u32, @intCast(imm))); .unsigned) {
.signed => Immediate.s(@truncate(@as(i64, @bitCast(imm)))),
.unsigned => Immediate.u(@as(u32, @intCast(imm))),
};
try self.asmMemoryImmediate( try self.asmMemoryImmediate(
.{ ._, .mov }, .{ ._, .mov },
Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }), Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }),
@ -11586,7 +11591,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
.{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) },
), registerAlias(src_reg, part_size)); ), registerAlias(src_reg, part_size));
}, },
.register_overflow => |ro| { .register_overflow => |ro| switch (ty.zigTypeTag(mod)) {
.Struct => {
try self.genSetMem( try self.genSetMem(
base, base,
disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),
@ -11600,6 +11606,21 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
.{ .eflags = ro.eflags }, .{ .eflags = ro.eflags },
); );
}, },
.Optional => {
assert(!ty.optionalReprIsPayload(mod));
const child_ty = ty.optionalChild(mod);
try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg });
try self.genSetMem(
base,
disp + @as(i32, @intCast(child_ty.abiSize(mod))),
Type.bool,
.{ .eflags = ro.eflags },
);
},
else => return self.fail("TODO implement genSetMem for {s} of {}", .{
@tagName(src_mcv), ty.fmt(mod),
}),
},
.register_offset, .register_offset,
.memory, .memory,
.indirect, .indirect,

View file

@ -745,12 +745,12 @@ test "auto created variables have correct alignment" {
test "extern variable with non-pointer opaque type" { test "extern variable with non-pointer opaque type" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
@export(var_to_export, .{ .name = "opaque_extern_var" }); @export(var_to_export, .{ .name = "opaque_extern_var" });
try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42); try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42);

View file

@ -2383,7 +2383,6 @@ test "numeric coercions with undefined" {
test "15-bit int to float" { test "15-bit int to float" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
var a: u15 = 42; var a: u15 = 42;
var b: f32 = @floatFromInt(a); var b: f32 = @floatFromInt(a);

View file

@ -425,8 +425,8 @@ test "implicit cast function to function ptr" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
const S1 = struct { const S1 = struct {
export fn someFunctionThatReturnsAValue() c_int { export fn someFunctionThatReturnsAValue() c_int {