Commit 02692ad78c

Jacob Young <jacobly0@users.noreply.github.com>
2025-01-10 09:24:44
cbe: fix miscomps of the compiler
1 parent 4e58142
src/codegen/c.zig
@@ -7419,7 +7419,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
                 .@"packed" => {
                     try f.writeCValue(writer, local, .Other);
                     try writer.writeAll(" = ");
-                    const int_info = inst_ty.intInfo(zcu);
+
+                    const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));
+                    const int_info = backing_int_ty.intInfo(zcu);
 
                     const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
 
@@ -7450,6 +7452,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
                         try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
                         try writer.writeByte('(');
 
+                        if (field_ty.isAbiInt(zcu)) {
+                            try writer.writeAll("zig_and_");
+                            try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
+                            try writer.writeByte('(');
+                        }
+
                         if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {
                             try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);
                         } else {
@@ -7467,6 +7475,17 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
                             try f.writeCValue(writer, element, .Other);
                         }
 
+                        if (field_ty.isAbiInt(zcu)) {
+                            try writer.writeAll(", ");
+                            const field_int_info = field_ty.intInfo(zcu);
+                            const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)
+                                try pt.intValue(backing_int_ty, -1)
+                            else
+                                try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);
+                            try f.object.dg.renderValue(writer, field_mask, .FunctionArgument);
+                            try writer.writeByte(')');
+                        }
+
                         try writer.print(", {}", .{
                             try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
                         });
src/Compilation.zig
@@ -251,7 +251,12 @@ reference_trace: ?u32 = null,
 libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
 
 /// This mutex guards all `Compilation` mutable state.
-mutex: std.Thread.Mutex = .{},
+/// Disabled in single-threaded mode because the thread pool spawns in the same thread.
+mutex: if (builtin.single_threaded) struct {
+    pub inline fn tryLock(_: @This()) void {}
+    pub inline fn lock(_: @This()) void {}
+    pub inline fn unlock(_: @This()) void {}
+} else std.Thread.Mutex = .{},
 
 test_filters: []const []const u8,
 test_name_prefix: ?[]const u8,
src/InternPool.zig
@@ -5538,7 +5538,7 @@ pub const Tag = enum(u8) {
             },
         },
         .type_union = .{
-            .summary = .@"{.payload.name%summary#\"#\"}",
+            .summary = .@"{.payload.name%summary#\"}",
             .payload = TypeUnion,
             .trailing = struct {
                 captures_len: ?u32,
@@ -6584,7 +6584,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
 }
 
 pub fn deinit(ip: *InternPool, gpa: Allocator) void {
-    if (!builtin.strip_debug_info) std.debug.assert(debug_state.intern_pool == null);
+    if (debug_state.enable_checks) std.debug.assert(debug_state.intern_pool == null);
 
     ip.file_deps.deinit(gpa);
     ip.src_hash_deps.deinit(gpa);
@@ -6629,7 +6629,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
 }
 
 pub fn activate(ip: *const InternPool) void {
-    if (builtin.strip_debug_info) return;
+    if (!debug_state.enable) return;
     _ = Index.Unwrapped.debug_state;
     _ = String.debug_state;
     _ = OptionalString.debug_state;
@@ -6639,18 +6639,23 @@ pub fn activate(ip: *const InternPool) void {
     _ = TrackedInst.Index.Optional.debug_state;
     _ = Nav.Index.debug_state;
     _ = Nav.Index.Optional.debug_state;
-    std.debug.assert(debug_state.intern_pool == null);
+    if (debug_state.enable_checks) std.debug.assert(debug_state.intern_pool == null);
     debug_state.intern_pool = ip;
 }
 
 pub fn deactivate(ip: *const InternPool) void {
-    if (builtin.strip_debug_info) return;
+    if (!debug_state.enable) return;
     std.debug.assert(debug_state.intern_pool == ip);
-    debug_state.intern_pool = null;
+    if (debug_state.enable_checks) debug_state.intern_pool = null;
 }
 
 /// For debugger access only.
 const debug_state = struct {
+    const enable = switch (builtin.zig_backend) {
+        else => false,
+        .stage2_x86_64 => !builtin.strip_debug_info,
+    };
+    const enable_checks = enable and !builtin.single_threaded;
     threadlocal var intern_pool: ?*const InternPool = null;
 };
 
test/behavior/export_keyword.zig
@@ -41,6 +41,8 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {
 }
 
 test "export function alias" {
+    if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
+
     _ = struct {
         fn foo_internal() callconv(.C) u32 {
             return 123;
test/behavior/packed-struct.zig
@@ -1327,3 +1327,20 @@ test "packed struct with signed field" {
     try expect(s.a == -1);
     try expect(s.b == 42);
 }
+
+test "assign packed struct initialized with RLS to packed struct literal field" {
+    if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) return error.SkipZigTest;
+    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
+
+    const Inner = packed struct { x: u17 };
+    const Outer = packed struct { inner: Inner, x: u15 };
+
+    var x: u15 = undefined;
+    x = 23385;
+    var inner: Inner = undefined;
+    inner = .{ .x = x };
+    const outer = Outer{ .x = x, .inner = inner };
+    try expect(outer.inner.x == x);
+    try expect(outer.x == x);
+}