Commit 9358a7528f

Jacob Young <jacobly0@users.noreply.github.com>
2023-10-18 07:24:17
x86_64: fix crashes
1 parent b403ca0
Changed files (4)
src
arch
test
src/arch/x86_64/CodeGen.zig
@@ -3798,11 +3798,13 @@ fn airShlSat(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 result: MCValue = result: {
         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)) {
             switch (opt_mcv) {
                 .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 => {},
         .immediate => |imm| switch (abi_size) {
             1, 2, 4 => {
-                const immediate = if (ty.isSignedInt(mod))
-                    Immediate.s(@truncate(@as(i64, @bitCast(imm))))
+                const immediate = switch (if (ty.isAbiInt(mod))
+                    ty.intInfo(mod).signedness
                 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(
                     .{ ._, .mov },
                     Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }),
@@ -11586,19 +11591,35 @@ 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)) },
             ), registerAlias(src_reg, part_size));
         },
-        .register_overflow => |ro| {
-            try self.genSetMem(
-                base,
-                disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),
-                ty.structFieldType(0, mod),
-                .{ .register = ro.reg },
-            );
-            try self.genSetMem(
-                base,
-                disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))),
-                ty.structFieldType(1, mod),
-                .{ .eflags = ro.eflags },
-            );
+        .register_overflow => |ro| switch (ty.zigTypeTag(mod)) {
+            .Struct => {
+                try self.genSetMem(
+                    base,
+                    disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),
+                    ty.structFieldType(0, mod),
+                    .{ .register = ro.reg },
+                );
+                try self.genSetMem(
+                    base,
+                    disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))),
+                    ty.structFieldType(1, mod),
+                    .{ .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,
         .memory,
test/behavior/basic.zig
@@ -745,12 +745,12 @@ test "auto created variables have correct alignment" {
 
 test "extern variable with non-pointer opaque type" {
     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_arm) 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_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" });
     try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42);
test/behavior/cast.zig
@@ -2383,7 +2383,6 @@ test "numeric coercions with undefined" {
 
 test "15-bit int to float" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
 
     var a: u15 = 42;
     var b: f32 = @floatFromInt(a);
test/behavior/fn.zig
@@ -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_aarch64) 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_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
 
     const S1 = struct {
         export fn someFunctionThatReturnsAValue() c_int {