Commit f1c0f42cdd

Jacob Young <jacobly0@users.noreply.github.com>
2024-04-12 05:40:15
cbe: fix optional codegen
Also reduce ctype pool string memory usage, remove self assignments, and enable more warnings.
1 parent 05d9755
lib/std/posix/test.zig
@@ -839,7 +839,7 @@ test "sigaction" {
     const S = struct {
         var handler_called_count: u32 = 0;
 
-        fn handler(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) void {
+        fn handler(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.C) void {
             _ = ctx_ptr;
             // Check that we received the correct signal.
             switch (native_os) {
src/codegen/c/Type.zig
@@ -1,13 +1,33 @@
 index: CType.Index,
 
+pub const @"void": CType = .{ .index = .void };
+pub const @"bool": CType = .{ .index = .bool };
+pub const @"i8": CType = .{ .index = .int8_t };
+pub const @"u8": CType = .{ .index = .uint8_t };
+pub const @"i16": CType = .{ .index = .int16_t };
+pub const @"u16": CType = .{ .index = .uint16_t };
+pub const @"i32": CType = .{ .index = .int32_t };
+pub const @"u32": CType = .{ .index = .uint32_t };
+pub const @"i64": CType = .{ .index = .int64_t };
+pub const @"u64": CType = .{ .index = .uint64_t };
+pub const @"i128": CType = .{ .index = .zig_i128 };
+pub const @"u128": CType = .{ .index = .zig_u128 };
+pub const @"isize": CType = .{ .index = .intptr_t };
+pub const @"usize": CType = .{ .index = .uintptr_t };
+pub const @"f16": CType = .{ .index = .zig_f16 };
+pub const @"f32": CType = .{ .index = .zig_f32 };
+pub const @"f64": CType = .{ .index = .zig_f64 };
+pub const @"f80": CType = .{ .index = .zig_f80 };
+pub const @"f128": CType = .{ .index = .zig_f128 };
+
 pub fn fromPoolIndex(pool_index: usize) CType {
     return .{ .index = @enumFromInt(CType.Index.first_pool_index + pool_index) };
 }
 
 pub fn toPoolIndex(ctype: CType) ?u32 {
-    const pool_index, const is_basic =
+    const pool_index, const is_null =
         @subWithOverflow(@intFromEnum(ctype.index), CType.Index.first_pool_index);
-    return switch (is_basic) {
+    return switch (is_null) {
         0 => pool_index,
         1 => null,
     };
@@ -710,20 +730,6 @@ pub const Kind = enum {
     }
 };
 
-pub const String = struct {
-    index: String.Index,
-
-    const Index = enum(u32) {
-        _,
-    };
-
-    pub fn slice(string: String, pool: *const Pool) []const u8 {
-        const start = pool.string_indices.items[@intFromEnum(string.index)];
-        const end = pool.string_indices.items[@intFromEnum(string.index) + 1];
-        return pool.string_bytes.items[start..end];
-    }
-};
-
 pub const Info = union(enum) {
     basic: CType.Index,
     pointer: Pointer,
@@ -766,7 +772,7 @@ pub const Info = union(enum) {
     pub const AggregateTag = enum { @"enum", @"struct", @"union" };
 
     pub const Field = struct {
-        name: String,
+        name: Pool.String,
         ctype: CType,
         alignas: AlignAs,
 
@@ -812,12 +818,15 @@ pub const Info = union(enum) {
             rhs_pool: *const Pool,
             pool_adapter: anytype,
         ) bool {
-            return std.meta.eql(lhs_field.alignas, rhs_field.alignas) and
-                pool_adapter.eql(lhs_field.ctype, rhs_field.ctype) and std.mem.eql(
-                u8,
-                lhs_field.name.slice(lhs_pool),
-                rhs_field.name.slice(rhs_pool),
-            );
+            if (!std.meta.eql(lhs_field.alignas, rhs_field.alignas)) return false;
+            if (!pool_adapter.eql(lhs_field.ctype, rhs_field.ctype)) return false;
+            return if (lhs_field.name.toPoolSlice(lhs_pool)) |lhs_name|
+                if (rhs_field.name.toPoolSlice(rhs_pool)) |rhs_name|
+                    std.mem.eql(u8, lhs_name, rhs_name)
+                else
+                    false
+            else
+                lhs_field.name.index == rhs_field.name.index;
         }
     };
 
@@ -918,6 +927,86 @@ pub const Pool = struct {
 
     const Map = std.AutoArrayHashMapUnmanaged(void, void);
 
+    pub const String = struct {
+        index: String.Index,
+
+        const FormatData = struct { string: String, pool: *const Pool };
+        fn format(
+            data: FormatData,
+            comptime fmt_str: []const u8,
+            _: std.fmt.FormatOptions,
+            writer: anytype,
+        ) @TypeOf(writer).Error!void {
+            if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");
+            if (data.string.toSlice(data.pool)) |slice|
+                try writer.writeAll(slice)
+            else
+                try writer.print("f{d}", .{@intFromEnum(data.string.index)});
+        }
+        pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {
+            return .{ .data = .{ .string = str, .pool = pool } };
+        }
+
+        fn fromUnnamed(index: u31) String {
+            return .{ .index = @enumFromInt(index) };
+        }
+
+        fn isNamed(str: String) bool {
+            return @intFromEnum(str.index) >= String.Index.first_named_index;
+        }
+
+        pub fn toSlice(str: String, pool: *const Pool) ?[]const u8 {
+            return str.toPoolSlice(pool) orelse if (str.isNamed()) @tagName(str.index) else null;
+        }
+
+        fn toPoolSlice(str: String, pool: *const Pool) ?[]const u8 {
+            if (str.toPoolIndex()) |pool_index| {
+                const start = pool.string_indices.items[pool_index + 0];
+                const end = pool.string_indices.items[pool_index + 1];
+                return pool.string_bytes.items[start..end];
+            } else return null;
+        }
+
+        fn fromPoolIndex(pool_index: usize) String {
+            return .{ .index = @enumFromInt(String.Index.first_pool_index + pool_index) };
+        }
+
+        fn toPoolIndex(str: String) ?u32 {
+            const pool_index, const is_null =
+                @subWithOverflow(@intFromEnum(str.index), String.Index.first_pool_index);
+            return switch (is_null) {
+                0 => pool_index,
+                1 => null,
+            };
+        }
+
+        const Index = enum(u32) {
+            array = first_named_index,
+            @"error",
+            is_null,
+            len,
+            payload,
+            ptr,
+            tag,
+            _,
+
+            const first_named_index: u32 = 1 << 31;
+            const first_pool_index: u32 = first_named_index + @typeInfo(String.Index).Enum.fields.len;
+        };
+
+        const Adapter = struct {
+            pool: *const Pool,
+            pub fn hash(_: @This(), slice: []const u8) Map.Hash {
+                return @truncate(Hasher.Impl.hash(1, slice));
+            }
+            pub fn eql(string_adapter: @This(), lhs_slice: []const u8, _: void, rhs_index: usize) bool {
+                const rhs_string = String.fromPoolIndex(rhs_index);
+                const rhs_slice = rhs_string.toPoolSlice(string_adapter.pool).?;
+                return std.mem.eql(u8, lhs_slice, rhs_slice);
+            }
+        };
+    };
+
     pub const empty: Pool = .{
         .map = .{},
         .items = .{},
@@ -1200,26 +1289,26 @@ pub const Pool = struct {
         kind: Kind,
     ) !CType {
         switch (int_info.bits) {
-            0 => return .{ .index = .void },
+            0 => return CType.void,
             1...8 => switch (int_info.signedness) {
-                .unsigned => return .{ .index = .uint8_t },
-                .signed => return .{ .index = .int8_t },
+                .signed => return CType.i8,
+                .unsigned => return CType.u8,
             },
             9...16 => switch (int_info.signedness) {
-                .unsigned => return .{ .index = .uint16_t },
-                .signed => return .{ .index = .int16_t },
+                .signed => return CType.i16,
+                .unsigned => return CType.u16,
             },
             17...32 => switch (int_info.signedness) {
-                .unsigned => return .{ .index = .uint32_t },
-                .signed => return .{ .index = .int32_t },
+                .signed => return CType.i32,
+                .unsigned => return CType.u32,
             },
             33...64 => switch (int_info.signedness) {
-                .unsigned => return .{ .index = .uint64_t },
-                .signed => return .{ .index = .int64_t },
+                .signed => return CType.i64,
+                .unsigned => return CType.u64,
             },
             65...128 => switch (int_info.signedness) {
-                .unsigned => return .{ .index = .zig_u128 },
-                .signed => return .{ .index = .zig_i128 },
+                .signed => return CType.i128,
+                .unsigned => return CType.u128,
             },
             else => {
                 const target = &mod.resolved_target.result;
@@ -1235,7 +1324,7 @@ pub const Pool = struct {
                 if (!kind.isParameter()) return array_ctype;
                 var fields = [_]Info.Field{
                     .{
-                        .name = try pool.string(allocator, "array"),
+                        .name = .{ .index = .array },
                         .ctype = array_ctype,
                         .alignas = AlignAs.fromAbiAlignment(abi_align),
                     },
@@ -1267,19 +1356,19 @@ pub const Pool = struct {
             .null_type,
             .undefined_type,
             .enum_literal_type,
-            => return .{ .index = .void },
-            .u1_type, .u8_type => return .{ .index = .uint8_t },
-            .i8_type => return .{ .index = .int8_t },
-            .u16_type => return .{ .index = .uint16_t },
-            .i16_type => return .{ .index = .int16_t },
-            .u29_type, .u32_type => return .{ .index = .uint32_t },
-            .i32_type => return .{ .index = .int32_t },
-            .u64_type => return .{ .index = .uint64_t },
-            .i64_type => return .{ .index = .int64_t },
-            .u80_type, .u128_type => return .{ .index = .zig_u128 },
-            .i128_type => return .{ .index = .zig_i128 },
-            .usize_type => return .{ .index = .uintptr_t },
-            .isize_type => return .{ .index = .intptr_t },
+            => return CType.void,
+            .u1_type, .u8_type => return CType.u8,
+            .i8_type => return CType.i8,
+            .u16_type => return CType.u16,
+            .i16_type => return CType.i16,
+            .u29_type, .u32_type => return CType.u32,
+            .i32_type => return CType.i32,
+            .u64_type => return CType.u64,
+            .i64_type => return CType.i64,
+            .u80_type, .u128_type => return CType.u128,
+            .i128_type => return CType.i128,
+            .usize_type => return CType.usize,
+            .isize_type => return CType.isize,
             .c_char_type => return .{ .index = .char },
             .c_short_type => return .{ .index = .short },
             .c_ushort_type => return .{ .index = .@"unsigned short" },
@@ -1290,12 +1379,12 @@ pub const Pool = struct {
             .c_longlong_type => return .{ .index = .@"long long" },
             .c_ulonglong_type => return .{ .index = .@"unsigned long long" },
             .c_longdouble_type => return .{ .index = .@"long double" },
-            .f16_type => return .{ .index = .zig_f16 },
-            .f32_type => return .{ .index = .zig_f32 },
-            .f64_type => return .{ .index = .zig_f64 },
-            .f80_type => return .{ .index = .zig_f80 },
-            .f128_type => return .{ .index = .zig_f128 },
-            .bool_type, .optional_noreturn_type => return .{ .index = .bool },
+            .f16_type => return CType.f16,
+            .f32_type => return CType.f32,
+            .f64_type => return CType.f64,
+            .f80_type => return CType.f80,
+            .f128_type => return CType.f128,
+            .bool_type, .optional_noreturn_type => return CType.bool,
             .noreturn_type,
             .anyframe_type,
             .generic_poison_type,
@@ -1324,17 +1413,17 @@ pub const Pool = struct {
             }, mod, kind),
             .manyptr_u8_type,
             => return pool.getPointer(allocator, .{
-                .elem_ctype = .{ .index = .uint8_t },
+                .elem_ctype = CType.u8,
             }),
             .manyptr_const_u8_type,
             .manyptr_const_u8_sentinel_0_type,
             => return pool.getPointer(allocator, .{
-                .elem_ctype = .{ .index = .uint8_t },
+                .elem_ctype = CType.u8,
                 .@"const" = true,
             }),
             .single_const_pointer_to_comptime_int_type,
             => return pool.getPointer(allocator, .{
-                .elem_ctype = .{ .index = .void },
+                .elem_ctype = CType.void,
                 .@"const" = true,
             }),
             .slice_const_u8_type,
@@ -1343,16 +1432,16 @@ pub const Pool = struct {
                 const target = &mod.resolved_target.result;
                 var fields = [_]Info.Field{
                     .{
-                        .name = try pool.string(allocator, "ptr"),
+                        .name = .{ .index = .ptr },
                         .ctype = try pool.getPointer(allocator, .{
-                            .elem_ctype = .{ .index = .uint8_t },
+                            .elem_ctype = CType.u8,
                             .@"const" = true,
                         }),
                         .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target.*)),
                     },
                     .{
-                        .name = try pool.string(allocator, "len"),
-                        .ctype = .{ .index = .uintptr_t },
+                        .name = .{ .index = .len },
+                        .ctype = CType.usize,
                         .alignas = AlignAs.fromAbiAlignment(
                             Type.intAbiAlignment(target.ptrBitWidth(), target.*),
                         ),
@@ -1442,7 +1531,7 @@ pub const Pool = struct {
                         const target = &mod.resolved_target.result;
                         var fields = [_]Info.Field{
                             .{
-                                .name = try pool.string(allocator, "ptr"),
+                                .name = .{ .index = .ptr },
                                 .ctype = try pool.fromType(
                                     allocator,
                                     scratch,
@@ -1454,8 +1543,8 @@ pub const Pool = struct {
                                 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target.*)),
                             },
                             .{
-                                .name = try pool.string(allocator, "len"),
-                                .ctype = .{ .index = .uintptr_t },
+                                .name = .{ .index = .len },
+                                .ctype = CType.usize,
                                 .alignas = AlignAs.fromAbiAlignment(
                                     Type.intAbiAlignment(target.ptrBitWidth(), target.*),
                                 ),
@@ -1466,7 +1555,7 @@ pub const Pool = struct {
                 },
                 .array_type => |array_info| {
                     const len = array_info.lenIncludingSentinel();
-                    if (len == 0) return .{ .index = .void };
+                    if (len == 0) return CType.void;
                     const elem_type = Type.fromInterned(array_info.child);
                     const elem_ctype = try pool.fromType(
                         allocator,
@@ -1476,7 +1565,7 @@ pub const Pool = struct {
                         mod,
                         kind.noParameter(),
                     );
-                    if (elem_ctype.index == .void) return .{ .index = .void };
+                    if (elem_ctype.index == .void) return CType.void;
                     const array_ctype = try pool.getArray(allocator, .{
                         .elem_ctype = elem_ctype,
                         .len = len,
@@ -1484,7 +1573,7 @@ pub const Pool = struct {
                     if (!kind.isParameter()) return array_ctype;
                     var fields = [_]Info.Field{
                         .{
-                            .name = try pool.string(allocator, "array"),
+                            .name = .{ .index = .array },
                             .ctype = array_ctype,
                             .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
                         },
@@ -1492,7 +1581,7 @@ pub const Pool = struct {
                     return pool.fromFields(allocator, .@"struct", &fields, kind);
                 },
                 .vector_type => |vector_info| {
-                    if (vector_info.len == 0) return .{ .index = .void };
+                    if (vector_info.len == 0) return CType.void;
                     const elem_type = Type.fromInterned(vector_info.child);
                     const elem_ctype = try pool.fromType(
                         allocator,
@@ -1502,7 +1591,7 @@ pub const Pool = struct {
                         mod,
                         kind.noParameter(),
                     );
-                    if (elem_ctype.index == .void) return .{ .index = .void };
+                    if (elem_ctype.index == .void) return CType.void;
                     const vector_ctype = try pool.getVector(allocator, .{
                         .elem_ctype = elem_ctype,
                         .len = vector_info.len,
@@ -1510,7 +1599,7 @@ pub const Pool = struct {
                     if (!kind.isParameter()) return vector_ctype;
                     var fields = [_]Info.Field{
                         .{
-                            .name = try pool.string(allocator, "array"),
+                            .name = .{ .index = .array },
                             .ctype = vector_ctype,
                             .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
                         },
@@ -1518,7 +1607,7 @@ pub const Pool = struct {
                     return pool.fromFields(allocator, .@"struct", &fields, kind);
                 },
                 .opt_type => |payload_type| {
-                    if (ip.isNoReturn(payload_type)) return .{ .index = .void };
+                    if (ip.isNoReturn(payload_type)) return CType.void;
                     const payload_ctype = try pool.fromType(
                         allocator,
                         scratch,
@@ -1527,7 +1616,7 @@ pub const Pool = struct {
                         mod,
                         kind.noParameter(),
                     );
-                    if (payload_ctype.index == .void) return .{ .index = .bool };
+                    if (payload_ctype.index == .void) return CType.bool;
                     switch (payload_type) {
                         .anyerror_type => return payload_ctype,
                         else => switch (ip.indexToKey(payload_type)) {
@@ -1539,12 +1628,12 @@ pub const Pool = struct {
                     }
                     var fields = [_]Info.Field{
                         .{
-                            .name = try pool.string(allocator, "is_null"),
-                            .ctype = .{ .index = .bool },
+                            .name = .{ .index = .is_null },
+                            .ctype = CType.bool,
                             .alignas = AlignAs.fromAbiAlignment(.@"1"),
                         },
                         .{
-                            .name = try pool.string(allocator, "payload"),
+                            .name = .{ .index = .payload },
                             .ctype = payload_ctype,
                             .alignas = AlignAs.fromAbiAlignment(
                                 Type.fromInterned(payload_type).abiAlignment(zcu),
@@ -1574,14 +1663,14 @@ pub const Pool = struct {
                     const target = &mod.resolved_target.result;
                     var fields = [_]Info.Field{
                         .{
-                            .name = try pool.string(allocator, "error"),
+                            .name = .{ .index = .@"error" },
                             .ctype = error_set_ctype,
                             .alignas = AlignAs.fromAbiAlignment(
                                 Type.intAbiAlignment(error_set_bits, target.*),
                             ),
                         },
                         .{
-                            .name = try pool.string(allocator, "payload"),
+                            .name = .{ .index = .payload },
                             .ctype = payload_ctype,
                             .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)),
                         },
@@ -1600,7 +1689,7 @@ pub const Pool = struct {
                             if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
                                 fwd_decl
                             else
-                                .{ .index = .void };
+                                CType.void;
                             const scratch_top = scratch.items.len;
                             defer scratch.shrinkRetainingCapacity(scratch_top);
                             try scratch.ensureUnusedCapacity(
@@ -1627,7 +1716,7 @@ pub const Pool = struct {
                                     .unwrap()) |field_name|
                                     try pool.string(allocator, field_name.toSlice(ip))
                                 else
-                                    try pool.fmt(allocator, "f{d}", .{field_index});
+                                    String.fromUnnamed(@intCast(field_index));
                                 const field_alignas = AlignAs.fromAlignment(.{
                                     .@"align" = loaded_struct.fieldAlign(ip, field_index),
                                     .abi = field_type.abiAlignment(zcu),
@@ -1644,7 +1733,7 @@ pub const Pool = struct {
                                 scratch.items.len - scratch_top,
                                 @typeInfo(Field).Struct.fields.len,
                             ));
-                            if (fields_len == 0) return .{ .index = .void };
+                            if (fields_len == 0) return CType.void;
                             try pool.ensureUnusedCapacity(allocator, 1);
                             const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{
                                 .fwd_decl = fwd_decl.index,
@@ -1700,7 +1789,7 @@ pub const Pool = struct {
                         scratch.items.len - scratch_top,
                         @typeInfo(Field).Struct.fields.len,
                     ));
-                    if (fields_len == 0) return .{ .index = .void };
+                    if (fields_len == 0) return CType.void;
                     if (kind.isForward()) {
                         try pool.ensureUnusedCapacity(allocator, 1);
                         const extra_index = try pool.addHashedExtra(
@@ -1739,7 +1828,7 @@ pub const Pool = struct {
                             if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
                                 fwd_decl
                             else
-                                .{ .index = .void };
+                                CType.void;
                             const loaded_tag = loaded_union.loadTagType(ip);
                             const scratch_top = scratch.items.len;
                             defer scratch.shrinkRetainingCapacity(scratch_top);
@@ -1786,7 +1875,7 @@ pub const Pool = struct {
                                 @typeInfo(Field).Struct.fields.len,
                             ));
                             if (!has_tag) {
-                                if (fields_len == 0) return .{ .index = .void };
+                                if (fields_len == 0) return CType.void;
                                 try pool.ensureUnusedCapacity(allocator, 1);
                                 const extra_index = try pool.addHashedExtra(
                                     allocator,
@@ -1813,7 +1902,7 @@ pub const Pool = struct {
                                 );
                                 if (tag_ctype.index != .void) {
                                     struct_fields[struct_fields_len] = .{
-                                        .name = try pool.string(allocator, "tag"),
+                                        .name = .{ .index = .tag },
                                         .ctype = tag_ctype,
                                         .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),
                                     };
@@ -1846,14 +1935,14 @@ pub const Pool = struct {
                                 };
                                 if (payload_ctype.index != .void) {
                                     struct_fields[struct_fields_len] = .{
-                                        .name = try pool.string(allocator, "payload"),
+                                        .name = .{ .index = .payload },
                                         .ctype = payload_ctype,
                                         .alignas = AlignAs.fromAbiAlignment(payload_align),
                                     };
                                     struct_fields_len += 1;
                                 }
                             }
-                            if (struct_fields_len == 0) return .{ .index = .void };
+                            if (struct_fields_len == 0) return CType.void;
                             sortFields(struct_fields[0..struct_fields_len]);
                             return pool.getAggregate(allocator, .{
                                 .tag = .@"struct",
@@ -1867,7 +1956,7 @@ pub const Pool = struct {
                         }, mod, kind),
                     }
                 },
-                .opaque_type => return .{ .index = .void },
+                .opaque_type => return CType.void,
                 .enum_type => return pool.fromType(
                     allocator,
                     scratch,
@@ -1876,7 +1965,7 @@ pub const Pool = struct {
                     mod,
                     kind,
                 ),
-                .func_type => |func_info| if (func_info.is_generic) return .{ .index = .void } else {
+                .func_type => |func_info| if (func_info.is_generic) return CType.void else {
                     const scratch_top = scratch.items.len;
                     defer scratch.shrinkRetainingCapacity(scratch_top);
                     try scratch.ensureUnusedCapacity(allocator, func_info.param_types.len);
@@ -1890,7 +1979,7 @@ pub const Pool = struct {
                         zcu,
                         mod,
                         kind.asParameter(),
-                    ) else .{ .index = .void };
+                    ) else CType.void;
                     for (0..func_info.param_types.len) |param_index| {
                         const param_type = Type.fromInterned(
                             func_info.param_types.get(ip)[param_index],
@@ -2024,7 +2113,10 @@ pub const Pool = struct {
                     });
                     for (0..fields.len) |field_index| {
                         const field = fields.at(field_index, source_pool);
-                        const field_name = try pool.string(allocator, field.name.slice(source_pool));
+                        const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
+                            try pool.string(allocator, slice)
+                        else
+                            field.name;
                         pool.addExtraAssumeCapacity(Field, .{
                             .name = field_name.index,
                             .ctype = pool_adapter.copy(field.ctype).index,
@@ -2054,7 +2146,10 @@ pub const Pool = struct {
                 });
                 for (0..aggregate_info.fields.len) |field_index| {
                     const field = aggregate_info.fields.at(field_index, source_pool);
-                    const field_name = try pool.string(allocator, field.name.slice(source_pool));
+                    const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
+                        try pool.string(allocator, slice)
+                    else
+                        field.name;
                     pool.addExtraAssumeCapacity(Field, .{
                         .name = field_name.index,
                         .ctype = pool_adapter.copy(field.ctype).index,
@@ -2082,8 +2177,8 @@ pub const Pool = struct {
         return .{ ctype, gop.found_existing };
     }
 
-    pub fn string(pool: *Pool, allocator: std.mem.Allocator, str: []const u8) !String {
-        try pool.string_bytes.appendSlice(allocator, str);
+    pub fn string(pool: *Pool, allocator: std.mem.Allocator, slice: []const u8) !String {
+        try pool.string_bytes.appendSlice(allocator, slice);
         return pool.trailingString(allocator);
     }
 
@@ -2111,12 +2206,15 @@ pub const Pool = struct {
         fn updateExtra(hasher: *Hasher, comptime Extra: type, extra: Extra, pool: *const Pool) void {
             inline for (@typeInfo(Extra).Struct.fields) |field| {
                 const value = @field(extra, field.name);
-                hasher.update(switch (field.type) {
+                switch (field.type) {
                     Pool.Tag, String, CType => unreachable,
-                    CType.Index => (CType{ .index = value }).hash(pool),
-                    String.Index => (String{ .index = value }).slice(pool),
-                    else => value,
-                });
+                    CType.Index => hasher.update((CType{ .index = value }).hash(pool)),
+                    String.Index => if ((String{ .index = value }).toPoolSlice(pool)) |slice|
+                        hasher.update(slice)
+                    else
+                        hasher.update(@intFromEnum(value)),
+                    else => hasher.update(value),
+                }
             }
         }
         fn update(hasher: *Hasher, data: anytype) void {
@@ -2231,30 +2329,30 @@ pub const Pool = struct {
     }
 
     fn trailingString(pool: *Pool, allocator: std.mem.Allocator) !String {
-        const StringAdapter = struct {
-            pool: *const Pool,
-            pub fn hash(_: @This(), slice: []const u8) Map.Hash {
-                return @truncate(Hasher.Impl.hash(1, slice));
-            }
-            pub fn eql(string_adapter: @This(), lhs_slice: []const u8, _: void, rhs_index: usize) bool {
-                const rhs_string: String = .{ .index = @enumFromInt(rhs_index) };
-                const rhs_slice = rhs_string.slice(string_adapter.pool);
-                return std.mem.eql(u8, lhs_slice, rhs_slice);
-            }
-        };
+        const start = pool.string_indices.getLast();
+        const slice: []const u8 = pool.string_bytes.items[start..];
+        if (slice.len >= 2 and slice[0] == 'f' and switch (slice[1]) {
+            '0' => slice.len == 2,
+            '1'...'9' => true,
+            else => false,
+        }) if (std.fmt.parseInt(u31, slice[1..], 10)) |unnamed| {
+            pool.string_bytes.shrinkRetainingCapacity(start);
+            return String.fromUnnamed(unnamed);
+        } else |_| {};
+        if (std.meta.stringToEnum(String.Index, slice)) |index| {
+            pool.string_bytes.shrinkRetainingCapacity(start);
+            return .{ .index = index };
+        }
+
         try pool.string_map.ensureUnusedCapacity(allocator, 1);
         try pool.string_indices.ensureUnusedCapacity(allocator, 1);
 
-        const start = pool.string_indices.getLast();
-        const gop = pool.string_map.getOrPutAssumeCapacityAdapted(
-            @as([]const u8, pool.string_bytes.items[start..]),
-            StringAdapter{ .pool = pool },
-        );
+        const gop = pool.string_map.getOrPutAssumeCapacityAdapted(slice, String.Adapter{ .pool = pool });
         if (gop.found_existing)
             pool.string_bytes.shrinkRetainingCapacity(start)
         else
             pool.string_indices.appendAssumeCapacity(@intCast(pool.string_bytes.items.len));
-        return .{ .index = @enumFromInt(gop.index) };
+        return String.fromPoolIndex(gop.index);
     }
 
     const Item = struct {
src/codegen/c.zig
@@ -43,10 +43,12 @@ pub const CValue = union(enum) {
     decl_ref: InternPool.DeclIndex,
     /// An undefined value (cannot be dereferenced)
     undef: Type,
-    /// Render the slice as an identifier (using fmtIdent)
+    /// Rendered as an identifier (using fmtIdent)
     identifier: []const u8,
-    /// Render the slice as an payload.identifier (using fmtIdent)
+    /// Rendered as "payload." followed by as identifier (using fmtIdent)
     payload_identifier: []const u8,
+    /// Rendered with fmtCTypePoolString
+    ctype_pool_string: CType.Pool.String,
 };
 
 const BlockData = struct {
@@ -62,10 +64,10 @@ pub const LazyFnKey = union(enum) {
     never_inline: InternPool.DeclIndex,
 };
 pub const LazyFnValue = struct {
-    fn_name: CType.String,
+    fn_name: CType.Pool.String,
     data: Data,
 
-    pub const Data = union {
+    const Data = union {
         tag_name: Type,
         never_tail: void,
         never_inline: void,
@@ -80,7 +82,7 @@ const Local = struct {
         _: u20 = undefined,
     },
 
-    pub fn getType(local: Local) LocalType {
+    fn getType(local: Local) LocalType {
         return .{ .ctype = local.ctype, .alignas = local.flags.alignas };
     }
 };
@@ -96,12 +98,20 @@ const ValueRenderLocation = enum {
     StaticInitializer,
     Other,
 
-    pub fn isInitializer(self: ValueRenderLocation) bool {
-        return switch (self) {
+    fn isInitializer(loc: ValueRenderLocation) bool {
+        return switch (loc) {
             .Initializer, .StaticInitializer => true,
             else => false,
         };
     }
+
+    fn toCTypeKind(loc: ValueRenderLocation) CType.Kind {
+        return switch (loc) {
+            .FunctionArgument => .parameter,
+            .Initializer, .Other => .complete,
+            .StaticInitializer => .global,
+        };
+    }
 };
 
 const BuiltinInfo = enum { none, bits };
@@ -234,12 +244,11 @@ fn isReservedIdent(ident: []const u8) bool {
 
 fn formatIdent(
     ident: []const u8,
-    comptime fmt: []const u8,
-    options: std.fmt.FormatOptions,
+    comptime fmt_str: []const u8,
+    _: std.fmt.FormatOptions,
     writer: anytype,
-) !void {
-    _ = options;
-    const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
+) @TypeOf(writer).Error!void {
+    const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.
     if (solo and isReservedIdent(ident)) {
         try writer.writeAll("zig_e_");
     }
@@ -256,11 +265,32 @@ fn formatIdent(
         }
     }
 }
-
 pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
     return .{ .data = ident };
 }
 
+const CTypePoolStringFormatData = struct {
+    ctype_pool_string: CType.Pool.String,
+    ctype_pool: *const CType.Pool,
+};
+fn formatCTypePoolString(
+    data: CTypePoolStringFormatData,
+    comptime fmt_str: []const u8,
+    fmt_opts: std.fmt.FormatOptions,
+    writer: anytype,
+) @TypeOf(writer).Error!void {
+    if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
+        try formatIdent(slice, fmt_str, fmt_opts, writer)
+    else
+        try writer.print("{}", .{data.ctype_pool_string.fmt(data.ctype_pool)});
+}
+pub fn fmtCTypePoolString(
+    ctype_pool_string: CType.Pool.String,
+    ctype_pool: *const CType.Pool,
+) std.fmt.Formatter(formatCTypePoolString) {
+    return .{ .data = .{ .ctype_pool_string = ctype_pool_string, .ctype_pool = ctype_pool } };
+}
+
 // Returns true if `formatIdent` would make any edits to ident.
 // This must be kept in sync with `formatIdent`.
 pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
@@ -321,7 +351,7 @@ pub const Function = struct {
             try writer.writeAll(" = ");
             try f.object.dg.renderValue(writer, val, .StaticInitializer);
             try writer.writeAll(";\n ");
-            break :result decl_c_value;
+            break :result .{ .local = decl_c_value.new_local };
         } else .{ .constant = val };
 
         gop.value_ptr.* = result;
@@ -377,27 +407,7 @@ pub const Function = struct {
         switch (c_value) {
             .none => unreachable,
             .new_local, .local => |i| try w.print("t{d}", .{i}),
-            .local_ref => |i| {
-                const local = &f.locals.items[i];
-                if (local.flags.alignas.abiOrder().compare(.lt)) {
-                    const gpa = f.object.dg.gpa;
-                    const mod = f.object.dg.mod;
-                    const ctype_pool = &f.object.dg.ctype_pool;
-
-                    try w.writeByte('(');
-                    try f.renderCType(w, try ctype_pool.getPointer(gpa, .{
-                        .elem_ctype = try ctype_pool.fromIntInfo(gpa, .{
-                            .signedness = .unsigned,
-                            .bits = @min(
-                                local.flags.alignas.toByteUnits(),
-                                mod.resolved_target.result.maxIntAlignment(),
-                            ) * 8,
-                        }, mod, .forward),
-                    }));
-                    try w.writeByte(')');
-                }
-                try w.print("&t{d}", .{i});
-            },
+            .local_ref => |i| try w.print("&t{d}", .{i}),
             .constant => |val| try f.object.dg.renderValue(w, val, location),
             .arg => |i| try w.print("a{d}", .{i}),
             .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),
@@ -516,7 +526,7 @@ pub const Function = struct {
                 },
             };
         }
-        return gop.value_ptr.fn_name.slice(ctype_pool);
+        return gop.value_ptr.fn_name.toSlice(ctype_pool).?;
     }
 
     pub fn deinit(f: *Function) void {
@@ -538,6 +548,43 @@ pub const Function = struct {
         const zcu = f.object.dg.zcu;
         return f.air.typeOfIndex(inst, &zcu.intern_pool);
     }
+
+    fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void {
+        switch (dst) {
+            .new_local, .local => |dst_local_index| switch (src) {
+                .new_local, .local => |src_local_index| if (dst_local_index == src_local_index) return,
+                else => {},
+            },
+            else => {},
+        }
+        const writer = f.object.writer();
+        const a = try Assignment.start(f, writer, ctype);
+        try f.writeCValue(writer, dst, .Other);
+        try a.assign(f, writer);
+        try f.writeCValue(writer, src, .Initializer);
+        try a.end(f, writer);
+    }
+
+    fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
+        switch (src) {
+            // Move the freshly allocated local to be owned by this instruction,
+            // by returning it here instead of freeing it.
+            .new_local => return src,
+            else => {
+                try freeCValue(f, inst, src);
+                const dst = try f.allocLocal(inst, ty);
+                try f.copyCValue(try f.ctypeFromType(ty, .complete), dst, src);
+                return dst;
+            },
+        }
+    }
+
+    fn freeCValue(f: *Function, inst: ?Air.Inst.Index, val: CValue) !void {
+        switch (val) {
+            .new_local => |local_index| try freeLocal(f, inst, local_index, null),
+            else => {},
+        }
+    }
 };
 
 /// This data is available when outputting .c code for a `Zcu`.
@@ -627,13 +674,14 @@ pub const DeclGen = struct {
         // them).  The analysis until now should ensure that the C function
         // pointers are compatible.  If they are not, then there is a bug
         // somewhere and we should let the C compiler tell us about it.
-        const elem_ctype = (try dg.ctypeFromType(ptr_ty, .complete)).info(ctype_pool).pointer.elem_ctype;
+        const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);
+        const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
         const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);
         const need_cast = !elem_ctype.eql(decl_ctype) and
             (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);
         if (need_cast) {
             try writer.writeAll("((");
-            try dg.renderType(writer, ptr_ty);
+            try dg.renderCType(writer, ptr_ctype);
             try writer.writeByte(')');
         }
         try writer.writeByte('&');
@@ -692,13 +740,14 @@ pub const DeclGen = struct {
         // them).  The analysis until now should ensure that the C function
         // pointers are compatible.  If they are not, then there is a bug
         // somewhere and we should let the C compiler tell us about it.
-        const elem_ctype = (try dg.ctypeFromType(ty, .complete)).info(ctype_pool).pointer.elem_ctype;
+        const ctype = try dg.ctypeFromType(ty, .complete);
+        const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;
         const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);
         const need_cast = !elem_ctype.eql(decl_ctype) and
             (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);
         if (need_cast) {
             try writer.writeAll("((");
-            try dg.renderType(writer, ty);
+            try dg.renderCType(writer, ctype);
             try writer.writeByte(')');
         }
         try writer.writeByte('&');
@@ -828,6 +877,12 @@ pub const DeclGen = struct {
         }
     }
 
+    fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {
+        const zcu = dg.zcu;
+        const ip = &zcu.intern_pool;
+        try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))});
+    }
+
     fn renderValue(
         dg: *DeclGen,
         writer: anytype,
@@ -837,6 +892,7 @@ pub const DeclGen = struct {
         const zcu = dg.zcu;
         const ip = &zcu.intern_pool;
         const target = &dg.mod.resolved_target.result;
+        const ctype_pool = &dg.ctype_pool;
 
         const initializer_type: ValueRenderLocation = switch (location) {
             .StaticInitializer => .StaticInitializer,
@@ -845,6 +901,7 @@ pub const DeclGen = struct {
 
         const ty = val.typeOf(zcu);
         if (val.isUndefDeep(zcu)) return dg.renderUndefValue(writer, ty, location);
+        const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
         switch (ip.indexToKey(val.toIntern())) {
             // types, not values
             .int_type,
@@ -890,76 +947,53 @@ pub const DeclGen = struct {
                 .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(val, location)}),
                 .lazy_align, .lazy_size => {
                     try writer.writeAll("((");
-                    try dg.renderType(writer, ty);
+                    try dg.renderCType(writer, ctype);
                     try writer.print("){x})", .{try dg.fmtIntLiteral(
                         try zcu.intValue(Type.usize, val.toUnsignedInt(zcu)),
                         .Other,
                     )});
                 },
             },
-            .err => |err| try writer.print("zig_error_{}", .{
-                fmtIdent(err.name.toSlice(ip)),
-            }),
-            .error_union => |error_union| {
-                const payload_ty = ty.errorUnionPayload(zcu);
-                const error_ty = ty.errorUnionSet(zcu);
-                const err_int_ty = try zcu.errorIntType();
-                if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-                    switch (error_union.val) {
-                        .err_name => |err_name| return dg.renderValue(
-                            writer,
-                            Value.fromInterned((try zcu.intern(.{ .err = .{
-                                .ty = error_ty.toIntern(),
-                                .name = err_name,
-                            } }))),
-                            location,
-                        ),
-                        .payload => return dg.renderValue(
-                            writer,
-                            try zcu.intValue(err_int_ty, 0),
-                            location,
-                        ),
+            .err => |err| try dg.renderErrorName(writer, err.name),
+            .error_union => |error_union| switch (ctype.info(ctype_pool)) {
+                .basic => switch (error_union.val) {
+                    .err_name => |err_name| try dg.renderErrorName(writer, err_name),
+                    .payload => try writer.writeAll("0"),
+                },
+                .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+                .aggregate => |aggregate| {
+                    if (!location.isInitializer()) {
+                        try writer.writeByte('(');
+                        try dg.renderCType(writer, ctype);
+                        try writer.writeByte(')');
                     }
-                }
-
-                if (!location.isInitializer()) {
-                    try writer.writeByte('(');
-                    try dg.renderType(writer, ty);
-                    try writer.writeByte(')');
-                }
-
-                try writer.writeAll("{ .payload = ");
-                try dg.renderValue(
-                    writer,
-                    Value.fromInterned(switch (error_union.val) {
-                        .err_name => (try zcu.undefValue(payload_ty)).toIntern(),
-                        .payload => |payload| payload,
-                    }),
-                    initializer_type,
-                );
-                try writer.writeAll(", .error = ");
-                switch (error_union.val) {
-                    .err_name => |err_name| try dg.renderValue(
-                        writer,
-                        Value.fromInterned((try zcu.intern(.{ .err = .{
-                            .ty = error_ty.toIntern(),
-                            .name = err_name,
-                        } }))),
-                        location,
-                    ),
-                    .payload => try dg.renderValue(
-                        writer,
-                        try zcu.intValue(err_int_ty, 0),
-                        location,
-                    ),
-                }
-                try writer.writeAll(" }");
+                    try writer.writeByte('{');
+                    for (0..aggregate.fields.len) |field_index| {
+                        if (field_index > 0) try writer.writeByte(',');
+                        switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
+                            .@"error" => switch (error_union.val) {
+                                .err_name => |err_name| try dg.renderErrorName(writer, err_name),
+                                .payload => try writer.writeByte('0'),
+                            },
+                            .payload => switch (error_union.val) {
+                                .err_name => try dg.renderUndefValue(
+                                    writer,
+                                    ty.errorUnionPayload(zcu),
+                                    initializer_type,
+                                ),
+                                .payload => |payload| try dg.renderValue(
+                                    writer,
+                                    Value.fromInterned(payload),
+                                    initializer_type,
+                                ),
+                            },
+                            else => unreachable,
+                        }
+                    }
+                    try writer.writeByte('}');
+                },
             },
-            .enum_tag => |enum_tag| try dg.renderValue(
-                writer,
-                Value.fromInterned(enum_tag.int),
-                location,
-            ),
+            .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location),
             .float => {
                 const bits = ty.floatBits(target.*);
                 const f128_val = val.toFloat(f128, zcu);
@@ -1050,15 +1084,23 @@ pub const DeclGen = struct {
                 if (!empty) try writer.writeByte(')');
             },
             .slice => |slice| {
+                const aggregate = ctype.info(ctype_pool).aggregate;
                 if (!location.isInitializer()) {
                     try writer.writeByte('(');
-                    try dg.renderType(writer, ty);
+                    try dg.renderCType(writer, ctype);
                     try writer.writeByte(')');
                 }
                 try writer.writeByte('{');
-                try dg.renderValue(writer, Value.fromInterned(slice.ptr), initializer_type);
-                try writer.writeAll(", ");
-                try dg.renderValue(writer, Value.fromInterned(slice.len), initializer_type);
+                for (0..aggregate.fields.len) |field_index| {
+                    if (field_index > 0) try writer.writeByte(',');
+                    try dg.renderValue(writer, Value.fromInterned(
+                        switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
+                            .ptr => slice.ptr,
+                            .len => slice.len,
+                            else => unreachable,
+                        },
+                    ), initializer_type);
+                }
                 try writer.writeByte('}');
             },
             .ptr => |ptr| switch (ptr.addr) {
@@ -1066,7 +1108,7 @@ pub const DeclGen = struct {
                 .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, val, decl_val, location),
                 .int => |int| {
                     try writer.writeAll("((");
-                    try dg.renderType(writer, ty);
+                    try dg.renderCType(writer, ctype);
                     try writer.print("){x})", .{try dg.fmtIntLiteral(Value.fromInterned(int), location)});
                 },
                 .eu_payload,
@@ -1076,54 +1118,80 @@ pub const DeclGen = struct {
                 => try dg.renderParentPtr(writer, val.toIntern(), location),
                 .comptime_field, .comptime_alloc => unreachable,
             },
-            .opt => |opt| {
-                const payload_ty = ty.optionalChild(zcu);
-
-                const is_null_val = Value.makeBool(opt.val == .none);
-                if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
-                    return dg.renderValue(writer, is_null_val, location);
-
-                if (ty.optionalReprIsPayload(zcu)) return dg.renderValue(
-                    writer,
+            .opt => |opt| switch (ctype.info(ctype_pool)) {
+                .basic => if (ctype.isBool()) try writer.writeAll(switch (opt.val) {
+                    .none => "true",
+                    else => "false",
+                }) else switch (opt.val) {
+                    .none => try writer.writeAll("0"),
+                    else => |payload| switch (ip.indexToKey(payload)) {
+                        .undef => |err_ty| try dg.renderUndefValue(
+                            writer,
+                            Type.fromInterned(err_ty),
+                            location,
+                        ),
+                        .err => |err| try dg.renderErrorName(writer, err.name),
+                        else => unreachable,
+                    },
+                },
+                .pointer => switch (opt.val) {
+                    .none => try writer.writeAll("NULL"),
+                    else => |payload| try dg.renderValue(writer, Value.fromInterned(payload), location),
+                },
+                .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+                .aggregate => |aggregate| {
                     switch (opt.val) {
-                        .none => switch (payload_ty.zigTypeTag(zcu)) {
-                            .ErrorSet => try zcu.intValue(try zcu.errorIntType(), 0),
-                            .Pointer => try zcu.getCoerced(val, payload_ty),
+                        .none => {},
+                        else => |payload| switch (aggregate.fields.at(0, ctype_pool).name.index) {
+                            .is_null, .payload => {},
+                            .ptr, .len => return dg.renderValue(
+                                writer,
+                                Value.fromInterned(payload),
+                                location,
+                            ),
                             else => unreachable,
                         },
-                        else => |payload| Value.fromInterned(payload),
-                    },
-                    location,
-                );
-
-                if (!location.isInitializer()) {
-                    try writer.writeByte('(');
-                    try dg.renderType(writer, ty);
-                    try writer.writeByte(')');
-                }
-
-                try writer.writeAll("{ .payload = ");
-                switch (opt.val) {
-                    .none => try dg.renderUndefValue(writer, payload_ty, initializer_type),
-                    else => |payload| try dg.renderValue(
-                        writer,
-                        Value.fromInterned(payload),
-                        initializer_type,
-                    ),
-                }
-                try writer.writeAll(", .is_null = ");
-                try dg.renderValue(writer, is_null_val, initializer_type);
-                try writer.writeAll(" }");
+                    }
+                    if (!location.isInitializer()) {
+                        try writer.writeByte('(');
+                        try dg.renderCType(writer, ctype);
+                        try writer.writeByte(')');
+                    }
+                    try writer.writeByte('{');
+                    for (0..aggregate.fields.len) |field_index| {
+                        if (field_index > 0) try writer.writeByte(',');
+                        switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
+                            .is_null => try writer.writeAll(switch (opt.val) {
+                                .none => "true",
+                                else => "false",
+                            }),
+                            .payload => switch (opt.val) {
+                                .none => try dg.renderUndefValue(
+                                    writer,
+                                    ty.optionalChild(zcu),
+                                    initializer_type,
+                                ),
+                                else => |payload| try dg.renderValue(
+                                    writer,
+                                    Value.fromInterned(payload),
+                                    initializer_type,
+                                ),
+                            },
+                            .ptr => try writer.writeAll("NULL"),
+                            .len => try dg.renderUndefValue(writer, Type.usize, initializer_type),
+                            else => unreachable,
+                        }
+                    }
+                    try writer.writeByte('}');
+                },
             },
             .aggregate => switch (ip.indexToKey(ty.toIntern())) {
                 .array_type, .vector_type => {
                     if (location == .FunctionArgument) {
                         try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
+                        try dg.renderCType(writer, ctype);
                         try writer.writeByte(')');
                     }
-                    // Fall back to generic implementation.
-
                     const ai = ty.arrayInfo(zcu);
                     if (ai.elem_type.eql(Type.u8, zcu)) {
                         var literal = stringLiteral(writer, ty.arrayLenIncludingSentinel(zcu));
@@ -1160,7 +1228,7 @@ pub const DeclGen = struct {
                 .anon_struct_type => |tuple| {
                     if (!location.isInitializer()) {
                         try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
+                        try dg.renderCType(writer, ctype);
                         try writer.writeByte(')');
                     }
 
@@ -1196,7 +1264,7 @@ pub const DeclGen = struct {
                         .auto, .@"extern" => {
                             if (!location.isInitializer()) {
                                 try writer.writeByte('(');
-                                try dg.renderType(writer, ty);
+                                try dg.renderCType(writer, ctype);
                                 try writer.writeByte(')');
                             }
 
@@ -1238,7 +1306,7 @@ pub const DeclGen = struct {
 
                             if (eff_num_fields == 0) {
                                 try writer.writeByte('(');
-                                try dg.renderUndefValue(writer, ty, initializer_type);
+                                try dg.renderUndefValue(writer, ty, location);
                                 try writer.writeByte(')');
                             } else if (ty.bitSize(zcu) > 64) {
                                 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
@@ -1293,7 +1361,7 @@ pub const DeclGen = struct {
 
                                     if (!empty) try writer.writeAll(" | ");
                                     try writer.writeByte('(');
-                                    try dg.renderType(writer, ty);
+                                    try dg.renderCType(writer, ctype);
                                     try writer.writeByte(')');
 
                                     const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
@@ -1334,7 +1402,7 @@ pub const DeclGen = struct {
                                 try dg.renderType(writer, backing_ty);
                                 try writer.writeByte(')');
                             }
-                            try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
+                            try dg.renderValue(writer, Value.fromInterned(un.val), location);
                         },
                         .@"extern" => {
                             if (location == .StaticInitializer) {
@@ -1347,7 +1415,7 @@ pub const DeclGen = struct {
                             try writer.writeAll(")(");
                             try dg.renderType(writer, backing_ty);
                             try writer.writeAll("){");
-                            try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
+                            try dg.renderValue(writer, Value.fromInterned(un.val), location);
                             try writer.writeAll("})");
                         },
                         else => unreachable,
@@ -1355,7 +1423,7 @@ pub const DeclGen = struct {
                 } else {
                     if (!location.isInitializer()) {
                         try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
+                        try dg.renderCType(writer, ctype);
                         try writer.writeByte(')');
                     }
 
@@ -1366,43 +1434,56 @@ pub const DeclGen = struct {
                         if (field_ty.hasRuntimeBits(zcu)) {
                             if (field_ty.isPtrAtRuntime(zcu)) {
                                 try writer.writeByte('(');
-                                try dg.renderType(writer, ty);
+                                try dg.renderCType(writer, ctype);
                                 try writer.writeByte(')');
                             } else if (field_ty.zigTypeTag(zcu) == .Float) {
                                 try writer.writeByte('(');
-                                try dg.renderType(writer, ty);
+                                try dg.renderCType(writer, ctype);
                                 try writer.writeByte(')');
                             }
-                            try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
-                        } else {
-                            try writer.writeAll("0");
-                        }
+                            try dg.renderValue(writer, Value.fromInterned(un.val), location);
+                        } else try writer.writeAll("0");
                         return;
                     }
 
-                    try writer.writeByte('{');
-                    if (ty.unionTagTypeSafety(zcu)) |_| {
-                        const layout = zcu.getUnionLayout(loaded_union);
-                        if (layout.tag_size != 0) {
-                            try writer.writeAll(" .tag = ");
-                            try dg.renderValue(writer, Value.fromInterned(un.tag), initializer_type);
+                    const has_tag = loaded_union.hasTag(ip);
+                    if (has_tag) try writer.writeByte('{');
+                    const aggregate = ctype.info(ctype_pool).aggregate;
+                    for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
+                        if (outer_field_index > 0) try writer.writeByte(',');
+                        switch (if (has_tag)
+                            aggregate.fields.at(outer_field_index, ctype_pool).name.index
+                        else
+                            .payload) {
+                            .tag => try dg.renderValue(
+                                writer,
+                                Value.fromInterned(un.tag),
+                                initializer_type,
+                            ),
+                            .payload => {
+                                try writer.writeByte('{');
+                                if (field_ty.hasRuntimeBits(zcu)) {
+                                    try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});
+                                    try dg.renderValue(
+                                        writer,
+                                        Value.fromInterned(un.val),
+                                        initializer_type,
+                                    );
+                                    try writer.writeByte(' ');
+                                } else for (0..loaded_union.field_types.len) |inner_field_index| {
+                                    const inner_field_ty = Type.fromInterned(
+                                        loaded_union.field_types.get(ip)[inner_field_index],
+                                    );
+                                    if (!inner_field_ty.hasRuntimeBits(zcu)) continue;
+                                    try dg.renderUndefValue(writer, inner_field_ty, initializer_type);
+                                    break;
+                                }
+                                try writer.writeByte('}');
+                            },
+                            else => unreachable,
                         }
-                        if (ty.unionHasAllZeroBitFieldTypes(zcu)) return try writer.writeByte('}');
-                        if (layout.tag_size != 0) try writer.writeByte(',');
-                        try writer.writeAll(" .payload = {");
-                    }
-                    if (field_ty.hasRuntimeBits(zcu)) {
-                        try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});
-                        try dg.renderValue(writer, Value.fromInterned(un.val), initializer_type);
-                        try writer.writeByte(' ');
-                    } else for (0..loaded_union.field_types.len) |this_field_index| {
-                        const this_field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[this_field_index]);
-                        if (!this_field_ty.hasRuntimeBits(zcu)) continue;
-                        try dg.renderUndefValue(writer, this_field_ty, initializer_type);
-                        break;
                     }
-                    if (ty.unionTagTypeSafety(zcu)) |_| try writer.writeByte('}');
-                    try writer.writeByte('}');
+                    if (has_tag) try writer.writeByte('}');
                 }
             },
         }
@@ -1417,6 +1498,7 @@ pub const DeclGen = struct {
         const zcu = dg.zcu;
         const ip = &zcu.intern_pool;
         const target = &dg.mod.resolved_target.result;
+        const ctype_pool = &dg.ctype_pool;
 
         const initializer_type: ValueRenderLocation = switch (location) {
             .StaticInitializer => .StaticInitializer,
@@ -1428,6 +1510,7 @@ pub const DeclGen = struct {
             .ReleaseFast, .ReleaseSmall => false,
         };
 
+        const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
         switch (ty.toIntern()) {
             .c_longdouble_type,
             .f16_type,
@@ -1465,48 +1548,64 @@ pub const DeclGen = struct {
                 => return writer.print("{x}", .{
                     try dg.fmtIntLiteral(try zcu.undefValue(ty), location),
                 }),
-                .ptr_type => if (ty.isSlice(zcu)) {
-                    if (!location.isInitializer()) {
-                        try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
-                        try writer.writeByte(')');
-                    }
+                .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
+                    .One, .Many, .C => {
+                        try writer.writeAll("((");
+                        try dg.renderCType(writer, ctype);
+                        return writer.print("){x})", .{
+                            try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),
+                        });
+                    },
+                    .Slice => {
+                        if (!location.isInitializer()) {
+                            try writer.writeByte('(');
+                            try dg.renderCType(writer, ctype);
+                            try writer.writeByte(')');
+                        }
 
-                    try writer.writeAll("{(");
-                    const ptr_ty = ty.slicePtrFieldType(zcu);
-                    try dg.renderType(writer, ptr_ty);
-                    return writer.print("){x}, {0x}}}", .{
-                        try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),
-                    });
-                } else {
-                    try writer.writeAll("((");
-                    try dg.renderType(writer, ty);
-                    return writer.print("){x})", .{
-                        try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),
-                    });
+                        try writer.writeAll("{(");
+                        const ptr_ty = ty.slicePtrFieldType(zcu);
+                        try dg.renderType(writer, ptr_ty);
+                        return writer.print("){x}, {0x}}}", .{
+                            try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),
+                        });
+                    },
                 },
-                .opt_type => {
-                    const payload_ty = ty.optionalChild(zcu);
-
-                    if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-                        return dg.renderUndefValue(writer, Type.bool, location);
-                    }
-
-                    if (ty.optionalReprIsPayload(zcu)) {
-                        return dg.renderUndefValue(writer, payload_ty, location);
-                    }
-
-                    if (!location.isInitializer()) {
-                        try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
-                        try writer.writeByte(')');
-                    }
-
-                    try writer.writeAll("{ .payload = ");
-                    try dg.renderUndefValue(writer, payload_ty, initializer_type);
-                    try writer.writeAll(", .is_null = ");
-                    try dg.renderUndefValue(writer, Type.bool, initializer_type);
-                    return writer.writeAll(" }");
+                .opt_type => |child_type| switch (ctype.info(ctype_pool)) {
+                    .basic, .pointer => try dg.renderUndefValue(
+                        writer,
+                        Type.fromInterned(if (ctype.isBool()) .bool_type else child_type),
+                        location,
+                    ),
+                    .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+                    .aggregate => |aggregate| {
+                        switch (aggregate.fields.at(0, ctype_pool).name.index) {
+                            .is_null, .payload => {},
+                            .ptr, .len => return dg.renderUndefValue(
+                                writer,
+                                Type.fromInterned(child_type),
+                                location,
+                            ),
+                            else => unreachable,
+                        }
+                        if (!location.isInitializer()) {
+                            try writer.writeByte('(');
+                            try dg.renderCType(writer, ctype);
+                            try writer.writeByte(')');
+                        }
+                        try writer.writeByte('{');
+                        for (0..aggregate.fields.len) |field_index| {
+                            if (field_index > 0) try writer.writeByte(',');
+                            try dg.renderUndefValue(writer, Type.fromInterned(
+                                switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
+                                    .is_null => .bool_type,
+                                    .payload => child_type,
+                                    else => unreachable,
+                                },
+                            ), initializer_type);
+                        }
+                        try writer.writeByte('}');
+                    },
                 },
                 .struct_type => {
                     const loaded_struct = ip.loadStructType(ty.toIntern());
@@ -1514,7 +1613,7 @@ pub const DeclGen = struct {
                         .auto, .@"extern" => {
                             if (!location.isInitializer()) {
                                 try writer.writeByte('(');
-                                try dg.renderType(writer, ty);
+                                try dg.renderCType(writer, ctype);
                                 try writer.writeByte(')');
                             }
 
@@ -1539,7 +1638,7 @@ pub const DeclGen = struct {
                 .anon_struct_type => |anon_struct_info| {
                     if (!location.isInitializer()) {
                         try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
+                        try dg.renderCType(writer, ctype);
                         try writer.writeByte(')');
                     }
 
@@ -1562,54 +1661,80 @@ pub const DeclGen = struct {
                         .auto, .@"extern" => {
                             if (!location.isInitializer()) {
                                 try writer.writeByte('(');
-                                try dg.renderType(writer, ty);
+                                try dg.renderCType(writer, ctype);
                                 try writer.writeByte(')');
                             }
 
-                            try writer.writeByte('{');
-                            if (ty.unionTagTypeSafety(zcu)) |tag_ty| {
-                                const layout = ty.unionGetLayout(zcu);
-                                if (layout.tag_size != 0) {
-                                    try writer.writeAll(" .tag = ");
-                                    try dg.renderUndefValue(writer, tag_ty, initializer_type);
+                            const has_tag = loaded_union.hasTag(ip);
+                            if (has_tag) try writer.writeByte('{');
+                            const aggregate = ctype.info(ctype_pool).aggregate;
+                            for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
+                                if (outer_field_index > 0) try writer.writeByte(',');
+                                switch (if (has_tag)
+                                    aggregate.fields.at(outer_field_index, ctype_pool).name.index
+                                else
+                                    .payload) {
+                                    .tag => try dg.renderUndefValue(
+                                        writer,
+                                        Type.fromInterned(loaded_union.enum_tag_ty),
+                                        initializer_type,
+                                    ),
+                                    .payload => {
+                                        try writer.writeByte('{');
+                                        for (0..loaded_union.field_types.len) |inner_field_index| {
+                                            const inner_field_ty = Type.fromInterned(
+                                                loaded_union.field_types.get(ip)[inner_field_index],
+                                            );
+                                            if (!inner_field_ty.hasRuntimeBits(zcu)) continue;
+                                            try dg.renderUndefValue(
+                                                writer,
+                                                inner_field_ty,
+                                                initializer_type,
+                                            );
+                                            break;
+                                        }
+                                        try writer.writeByte('}');
+                                    },
+                                    else => unreachable,
                                 }
-                                if (ty.unionHasAllZeroBitFieldTypes(zcu)) return try writer.writeByte('}');
-                                if (layout.tag_size != 0) try writer.writeByte(',');
-                                try writer.writeAll(" .payload = {");
-                            }
-                            for (0..loaded_union.field_types.len) |field_index| {
-                                const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
-                                if (!field_ty.hasRuntimeBits(zcu)) continue;
-                                try dg.renderUndefValue(writer, field_ty, initializer_type);
-                                break;
                             }
-                            if (ty.unionTagTypeSafety(zcu)) |_| try writer.writeByte('}');
-                            return writer.writeByte('}');
+                            if (has_tag) try writer.writeByte('}');
                         },
                         .@"packed" => return writer.print("{x}", .{
                             try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other),
                         }),
                     }
                 },
-                .error_union_type => {
-                    const payload_ty = ty.errorUnionPayload(zcu);
-                    const error_ty = ty.errorUnionSet(zcu);
-
-                    if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-                        return dg.renderUndefValue(writer, error_ty, location);
-                    }
-
-                    if (!location.isInitializer()) {
-                        try writer.writeByte('(');
-                        try dg.renderType(writer, ty);
-                        try writer.writeByte(')');
-                    }
-
-                    try writer.writeAll("{ .payload = ");
-                    try dg.renderUndefValue(writer, payload_ty, initializer_type);
-                    try writer.writeAll(", .error = ");
-                    try dg.renderUndefValue(writer, error_ty, initializer_type);
-                    return writer.writeAll(" }");
+                .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {
+                    .basic => try dg.renderUndefValue(
+                        writer,
+                        Type.fromInterned(error_union_type.error_set_type),
+                        location,
+                    ),
+                    .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+                    .aggregate => |aggregate| {
+                        if (!location.isInitializer()) {
+                            try writer.writeByte('(');
+                            try dg.renderCType(writer, ctype);
+                            try writer.writeByte(')');
+                        }
+                        try writer.writeByte('{');
+                        for (0..aggregate.fields.len) |field_index| {
+                            if (field_index > 0) try writer.writeByte(',');
+                            try dg.renderUndefValue(
+                                writer,
+                                Type.fromInterned(
+                                    switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
+                                        .@"error" => error_union_type.error_set_type,
+                                        .payload => error_union_type.payload_type,
+                                        else => unreachable,
+                                    },
+                                ),
+                                initializer_type,
+                            );
+                        }
+                        try writer.writeByte('}');
+                    },
                 },
                 .array_type, .vector_type => {
                     const ai = ty.arrayInfo(zcu);
@@ -1624,7 +1749,7 @@ pub const DeclGen = struct {
                     } else {
                         if (!location.isInitializer()) {
                             try writer.writeByte('(');
-                            try dg.renderType(writer, ty);
+                            try dg.renderCType(writer, ctype);
                             try writer.writeByte(')');
                         }
 
@@ -1674,6 +1799,7 @@ pub const DeclGen = struct {
         name: union(enum) {
             export_index: u32,
             ident: []const u8,
+            fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString),
         },
     ) !void {
         const zcu = dg.zcu;
@@ -1717,6 +1843,7 @@ pub const DeclGen = struct {
                 try dg.renderDeclName(w, fn_decl_index, export_index);
             },
             .ident => |ident| try w.print("{}{ }", .{ trailing, fmtIdent(ident) }),
+            .fmt_ctype_pool_string => |fmt| try w.print("{}{ }", .{ trailing, fmt }),
         }
 
         try renderTypeSuffix(
@@ -1772,7 +1899,7 @@ pub const DeclGen = struct {
                             });
                         }
                     },
-                    .ident => {},
+                    .ident, .fmt_ctype_pool_string => {},
                 }
             },
             .complete => {},
@@ -1800,11 +1927,11 @@ pub const DeclGen = struct {
     ///   | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
     ///   | `renderType`        | "uint8_t *"     | "uint8_t *[10]"     |
     ///
-    fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void {
+    fn renderType(dg: *DeclGen, w: anytype, t: Type) error{OutOfMemory}!void {
         try dg.renderCType(w, try dg.ctypeFromType(t, .complete));
     }
 
-    fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{ OutOfMemory, AnalysisFail }!void {
+    fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {
         _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{});
         try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{});
     }
@@ -1829,7 +1956,26 @@ pub const DeclGen = struct {
             }
         }
     };
+    fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool {
+        const zcu = dg.zcu;
+        const dest_bits = dest_ty.bitSize(zcu);
+        const dest_int_info = dest_ty.intInfo(zcu);
+
+        const src_is_ptr = src_ty.isPtrAtRuntime(zcu);
+        const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
+            .unsigned => Type.usize,
+            .signed => Type.isize,
+        } else src_ty;
 
+        const src_bits = src_eff_ty.bitSize(zcu);
+        const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;
+        if (dest_bits <= 64 and src_bits <= 64) {
+            const needs_cast = src_int_info == null or
+                (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
+                dest_int_info.signedness != src_int_info.?.signedness);
+            return !needs_cast and !src_is_ptr;
+        } else return false;
+    }
     /// Renders a cast to an int type, from either an int or a pointer.
     ///
     /// Some platforms don't have 128 bit integers, so we need to use
@@ -1843,7 +1989,14 @@ pub const DeclGen = struct {
     ///   | > 64 bit integer | pointer          | zig_make_<dest_ty>(0, (zig_<u|i>size)src)
     ///   | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
     ///   | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
-    fn renderIntCast(dg: *DeclGen, w: anytype, dest_ty: Type, context: IntCastContext, src_ty: Type, location: ValueRenderLocation) !void {
+    fn renderIntCast(
+        dg: *DeclGen,
+        w: anytype,
+        dest_ty: Type,
+        context: IntCastContext,
+        src_ty: Type,
+        location: ValueRenderLocation,
+    ) !void {
         const zcu = dg.zcu;
         const dest_bits = dest_ty.bitSize(zcu);
         const dest_int_info = dest_ty.intInfo(zcu);
@@ -1998,12 +2151,23 @@ pub const DeclGen = struct {
                 fmtIdent("payload"),
                 fmtIdent(ident),
             }),
+            .ctype_pool_string => |string| try w.print("{ }", .{
+                fmtCTypePoolString(string, &dg.ctype_pool),
+            }),
         }
     }
 
     fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {
         switch (c_value) {
-            .none, .new_local, .local, .local_ref, .constant, .arg, .arg_array => unreachable,
+            .none,
+            .new_local,
+            .local,
+            .local_ref,
+            .constant,
+            .arg,
+            .arg_array,
+            .ctype_pool_string,
+            => unreachable,
             .field => |i| try w.print("f{d}", .{i}),
             .decl => |decl| {
                 try w.writeAll("(*");
@@ -2033,7 +2197,17 @@ pub const DeclGen = struct {
 
     fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
         switch (c_value) {
-            .none, .new_local, .local, .local_ref, .constant, .field, .undef, .arg, .arg_array => unreachable,
+            .none,
+            .new_local,
+            .local,
+            .local_ref,
+            .constant,
+            .field,
+            .undef,
+            .arg,
+            .arg_array,
+            .ctype_pool_string,
+            => unreachable,
             .decl, .identifier, .payload_identifier => {
                 try dg.writeCValue(writer, c_value);
                 try writer.writeAll("->");
@@ -2172,11 +2346,7 @@ pub const DeclGen = struct {
         loc: ValueRenderLocation,
     ) !std.fmt.Formatter(formatIntLiteral) {
         const zcu = dg.zcu;
-        const kind: CType.Kind = switch (loc) {
-            .FunctionArgument => .parameter,
-            .Initializer, .Other => .complete,
-            .StaticInitializer => .global,
-        };
+        const kind = loc.toCTypeKind();
         const ty = val.typeOf(zcu);
         return std.fmt.Formatter(formatIntLiteral){ .data = .{
             .dg = dg,
@@ -2439,7 +2609,7 @@ fn renderFields(
             .suffix,
             .{},
         );
-        try writer.print("{}{ }", .{ trailing, fmtIdent(field_info.name.slice(ctype_pool)) });
+        try writer.print("{}{ }", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool) });
         try renderTypeSuffix(.flush, ctype_pool, zcu, writer, field_info.ctype, .suffix, .{});
         try writer.writeAll(";\n");
     }
@@ -2698,9 +2868,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
 
             try w.writeAll("static ");
             try o.dg.renderType(w, name_slice_ty);
-            try w.writeByte(' ');
-            try w.writeAll(val.fn_name.slice(lazy_ctype_pool));
-            try w.writeByte('(');
+            try w.print(" {}(", .{val.fn_name.fmt(lazy_ctype_pool)});
             try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
             try w.writeAll(") {\n switch (tag) {\n");
             const tag_names = enum_ty.enumFields(zcu);
@@ -2744,21 +2912,18 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
             const fn_decl = zcu.declPtr(fn_decl_index);
             const fn_ctype = try o.dg.ctypeFromType(fn_decl.typeOf(zcu), .complete);
             const fn_info = fn_ctype.info(ctype_pool).function;
-            const fn_name = val.fn_name.slice(lazy_ctype_pool);
+            const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);
 
             const fwd_decl_writer = o.dg.fwdDeclWriter();
             try fwd_decl_writer.print("static zig_{s} ", .{@tagName(key)});
-            try o.dg.renderFunctionSignature(
-                fwd_decl_writer,
-                fn_decl_index,
-                .forward,
-                .{ .ident = fn_name },
-            );
+            try o.dg.renderFunctionSignature(fwd_decl_writer, fn_decl_index, .forward, .{
+                .fmt_ctype_pool_string = fn_name,
+            });
             try fwd_decl_writer.writeAll(";\n");
 
             try w.print("static zig_{s} ", .{@tagName(key)});
             try o.dg.renderFunctionSignature(w, fn_decl_index, .complete, .{
-                .ident = fn_name,
+                .fmt_ctype_pool_string = fn_name,
             });
             try w.writeAll(" {\n return ");
             try o.dg.renderDeclName(w, fn_decl_index, 0);
@@ -3143,8 +3308,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
             .shl_exact          => try airBinOp(f, inst, "<<", "shl", .none),
             .not                => try airNot  (f, inst),
 
-            .optional_payload         => try airOptionalPayload(f, inst),
-            .optional_payload_ptr     => try airOptionalPayloadPtr(f, inst),
+            .optional_payload         => try airOptionalPayload(f, inst, false),
+            .optional_payload_ptr     => try airOptionalPayload(f, inst, true),
             .optional_payload_ptr_set => try airOptionalPayloadPtrSet(f, inst),
             .wrap_optional            => try airWrapOptional(f, inst),
 
@@ -3153,10 +3318,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
             .is_err_ptr      => try airIsErr(f, inst, true, "!="),
             .is_non_err_ptr  => try airIsErr(f, inst, true, "=="),
 
-            .is_null         => try airIsNull(f, inst, "==", false),
-            .is_non_null     => try airIsNull(f, inst, "!=", false),
-            .is_null_ptr     => try airIsNull(f, inst, "==", true),
-            .is_non_null_ptr => try airIsNull(f, inst, "!=", true),
+            .is_null         => try airIsNull(f, inst, .eq, false),
+            .is_non_null     => try airIsNull(f, inst, .neq, false),
+            .is_null_ptr     => try airIsNull(f, inst, .eq, true),
+            .is_non_null_ptr => try airIsNull(f, inst, .neq, true),
 
             .alloc            => try airAlloc(f, inst),
             .ret_ptr          => try airRetPtr(f, inst),
@@ -3239,8 +3404,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
             .slice_ptr        => try airSliceField(f, inst, false, "ptr"),
             .slice_len        => try airSliceField(f, inst, false, "len"),
 
-            .ptr_slice_len_ptr => try airSliceField(f, inst, true, "len"),
             .ptr_slice_ptr_ptr => try airSliceField(f, inst, true, "ptr"),
+            .ptr_slice_len_ptr => try airSliceField(f, inst, true, "len"),
 
             .ptr_elem_val       => try airPtrElemVal(f, inst),
             .ptr_elem_ptr       => try airPtrElemPtr(f, inst),
@@ -3308,7 +3473,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
         }
         try f.value_map.putNoClobber(inst.toRef(), switch (result_value) {
             .none => continue,
-            .new_local => |i| .{ .local = i },
+            .new_local => |local_index| .{ .local = local_index },
             else => result_value,
         });
     }
@@ -3323,7 +3488,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     if (is_ptr) {
@@ -3349,7 +3514,7 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValue(writer, ptr, .Other);
@@ -3375,7 +3540,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try writer.writeByte('(');
@@ -3410,7 +3575,7 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
@@ -3437,7 +3602,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     if (elem_has_bits) try writer.writeByte('&');
@@ -3466,7 +3631,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValue(writer, array, .Other);
@@ -3691,17 +3856,18 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
     const operand_ty = f.typeOf(ty_op.operand);
     const scalar_ty = operand_ty.scalarType(zcu);
 
+    if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);
+
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     const v = try Vectorize.start(f, inst, writer, operand_ty);
-    const a = try Assignment.start(f, writer, scalar_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try v.elem(f, writer);
     try a.assign(f, writer);
     try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);
     try a.end(f, writer);
     try v.end(f, inst, writer);
-
     return local;
 }
 
@@ -3711,38 +3877,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const operand = try f.resolveInst(ty_op.operand);
     try reap(f, inst, &.{ty_op.operand});
+
     const inst_ty = f.typeOfIndex(inst);
     const inst_scalar_ty = inst_ty.scalarType(zcu);
     const dest_int_info = inst_scalar_ty.intInfo(zcu);
     const dest_bits = dest_int_info.bits;
-    const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
+    const dest_c_bits = toCIntBits(dest_bits) orelse
         return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
     const operand_ty = f.typeOf(ty_op.operand);
     const scalar_ty = operand_ty.scalarType(zcu);
     const scalar_int_info = scalar_ty.intInfo(zcu);
 
+    const need_cast = dest_c_bits < 64;
+    const need_lo = scalar_int_info.bits > 64 and dest_bits <= 64;
+    const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
+    if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
+
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     const v = try Vectorize.start(f, inst, writer, operand_ty);
-
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try v.elem(f, writer);
-    try writer.writeAll(" = ");
-
-    if (dest_c_bits < 64) {
+    try a.assign(f, writer);
+    if (need_cast) {
         try writer.writeByte('(');
         try f.renderType(writer, inst_scalar_ty);
         try writer.writeByte(')');
     }
-
-    const needs_lo = scalar_int_info.bits > 64 and dest_bits <= 64;
-    if (needs_lo) {
+    if (need_lo) {
         try writer.writeAll("zig_lo_");
         try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
         try writer.writeByte('(');
     }
-
-    if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
+    if (!need_mask) {
         try f.writeCValue(writer, operand, .Other);
         try v.elem(f, writer);
     } else switch (dest_int_info.signedness) {
@@ -3782,11 +3950,9 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
             try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});
         },
     }
-
-    if (needs_lo) try writer.writeByte(')');
-    try writer.writeAll(";\n");
+    if (need_lo) try writer.writeByte(')');
+    try a.end(f, writer);
     try v.end(f, inst, writer);
-
     return local;
 }
 
@@ -3797,7 +3963,7 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
     const inst_ty = f.typeOfIndex(inst);
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValue(writer, operand, .Other);
@@ -3842,9 +4008,8 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
     const src_val = try f.resolveInst(bin_op.rhs);
     try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
 
+    const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);
     const writer = f.object.writer();
-    const v = try Vectorize.start(f, inst, writer, ptr_ty);
-
     if (need_memcpy) {
         // For this memcpy to safely work we need the rhs to have the same
         // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
@@ -3863,6 +4028,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
             break :blk new_local;
         } else src_val;
 
+        const v = try Vectorize.start(f, inst, writer, ptr_ty);
         try writer.writeAll("memcpy((char *)");
         try f.writeCValue(writer, ptr_val, .FunctionArgument);
         try v.elem(f, writer);
@@ -3873,9 +4039,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
         try writer.writeAll(", sizeof(");
         try f.renderType(writer, src_ty);
         try writer.writeAll("))");
-        if (src_val == .constant) {
-            try freeLocal(f, inst, array_src.new_local, null);
-        }
+        try f.freeCValue(inst, array_src);
+        try writer.writeAll(";\n");
+        try v.end(f, inst, writer);
     } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
         const host_bits = ptr_info.packed_offset.host_size * 8;
         const host_ty = try zcu.intType(.unsigned, host_bits);
@@ -3898,9 +4064,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
 
         const mask_val = try zcu.intValue_big(host_ty, mask.toConst());
 
+        const v = try Vectorize.start(f, inst, writer, ptr_ty);
+        const a = try Assignment.start(f, writer, src_scalar_ctype);
         try f.writeCValueDeref(writer, ptr_val);
         try v.elem(f, writer);
-        try writer.writeAll(" = zig_or_");
+        try a.assign(f, writer);
+        try writer.writeAll("zig_or_");
         try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
         try writer.writeAll("(zig_and_");
         try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
@@ -3931,16 +4100,27 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
         try v.elem(f, writer);
         if (cant_cast) try writer.writeByte(')');
         try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_val)});
+        try a.end(f, writer);
+        try v.end(f, inst, writer);
     } else {
+        switch (ptr_val) {
+            .local_ref => |ptr_local_index| switch (src_val) {
+                .new_local, .local => |src_local_index| if (ptr_local_index == src_local_index)
+                    return .none,
+                else => {},
+            },
+            else => {},
+        }
+        const v = try Vectorize.start(f, inst, writer, ptr_ty);
+        const a = try Assignment.start(f, writer, src_scalar_ctype);
         try f.writeCValueDeref(writer, ptr_val);
         try v.elem(f, writer);
-        try writer.writeAll(" = ");
+        try a.assign(f, writer);
         try f.writeCValue(writer, src_val, .Other);
         try v.elem(f, writer);
+        try a.end(f, writer);
+        try v.end(f, inst, writer);
     }
-    try writer.writeAll(";\n");
-    try v.end(f, inst, writer);
-
     return .none;
 }
 
@@ -4103,6 +4283,7 @@ fn airEquality(
     operator: std.math.CompareOperator,
 ) !CValue {
     const zcu = f.object.dg.zcu;
+    const ctype_pool = &f.object.dg.ctype_pool;
     const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
 
     const operand_ty = f.typeOf(bin_op.lhs);
@@ -4124,28 +4305,47 @@ fn airEquality(
     try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
 
     const writer = f.object.writer();
-    const inst_ty = f.typeOfIndex(inst);
-    const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const local = try f.allocLocal(inst, Type.bool);
+    const a = try Assignment.start(f, writer, CType.bool);
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
 
-    if (operand_ty.zigTypeTag(zcu) == .Optional and !operand_ty.optionalReprIsPayload(zcu)) {
-        try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
-        try writer.writeAll(" || ");
-        try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
-        try writer.writeAll(" ? ");
-        try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
-        try writer.writeAll(compareOperatorC(operator));
-        try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
-        try writer.writeAll(" : ");
-        try f.writeCValueMember(writer, lhs, .{ .identifier = "payload" });
-        try writer.writeAll(compareOperatorC(operator));
-        try f.writeCValueMember(writer, rhs, .{ .identifier = "payload" });
-    } else {
-        try f.writeCValue(writer, lhs, .Other);
-        try writer.writeAll(compareOperatorC(operator));
-        try f.writeCValue(writer, rhs, .Other);
+    const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
+    switch (operand_ctype.info(ctype_pool)) {
+        .basic, .pointer => {
+            try f.writeCValue(writer, lhs, .Other);
+            try writer.writeAll(compareOperatorC(operator));
+            try f.writeCValue(writer, rhs, .Other);
+        },
+        .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+        .aggregate => |aggregate| if (aggregate.fields.len == 2 and
+            (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
+            aggregate.fields.at(1, ctype_pool).name.index == .is_null))
+        {
+            try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
+            try writer.writeAll(" || ");
+            try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
+            try writer.writeAll(" ? ");
+            try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
+            try writer.writeAll(compareOperatorC(operator));
+            try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
+            try writer.writeAll(" : ");
+            try f.writeCValueMember(writer, lhs, .{ .identifier = "payload" });
+            try writer.writeAll(compareOperatorC(operator));
+            try f.writeCValueMember(writer, rhs, .{ .identifier = "payload" });
+        } else for (0..aggregate.fields.len) |field_index| {
+            if (field_index > 0) try writer.writeAll(switch (operator) {
+                .lt, .lte, .gte, .gt => unreachable,
+                .eq => " && ",
+                .neq => " || ",
+            });
+            const field_name: CValue = .{
+                .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,
+            };
+            try f.writeCValueMember(writer, lhs, field_name);
+            try writer.writeAll(compareOperatorC(operator));
+            try f.writeCValueMember(writer, rhs, field_name);
+        },
     }
     try a.end(f, writer);
 
@@ -4155,12 +4355,11 @@ fn airEquality(
 fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
     const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
 
-    const inst_ty = f.typeOfIndex(inst);
     const operand = try f.resolveInst(un_op);
     try reap(f, inst, &.{un_op});
 
     const writer = f.object.writer();
-    const local = try f.allocLocal(inst, inst_ty);
+    const local = try f.allocLocal(inst, Type.bool);
     try f.writeCValue(writer, local, .Other);
     try writer.writeAll(" = ");
     try f.writeCValue(writer, operand, .Other);
@@ -4180,39 +4379,34 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
     const inst_ty = f.typeOfIndex(inst);
     const inst_scalar_ty = inst_ty.scalarType(zcu);
     const elem_ty = inst_scalar_ty.elemType2(zcu);
+    if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs);
+    const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
 
     const local = try f.allocLocal(inst, inst_ty);
     const writer = f.object.writer();
     const v = try Vectorize.start(f, inst, writer, inst_ty);
+    const a = try Assignment.start(f, writer, inst_scalar_ctype);
     try f.writeCValue(writer, local, .Other);
     try v.elem(f, writer);
-    try writer.writeAll(" = ");
-
-    if (elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-        // We must convert to and from integer types to prevent UB if the operation
-        // results in a NULL pointer, or if LHS is NULL. The operation is only UB
-        // if the result is NULL and then dereferenced.
-        try writer.writeByte('(');
-        try f.renderType(writer, inst_scalar_ty);
-        try writer.writeAll(")(((uintptr_t)");
-        try f.writeCValue(writer, lhs, .Other);
-        try v.elem(f, writer);
-        try writer.writeAll(") ");
-        try writer.writeByte(operator);
-        try writer.writeAll(" (");
-        try f.writeCValue(writer, rhs, .Other);
-        try v.elem(f, writer);
-        try writer.writeAll("*sizeof(");
-        try f.renderType(writer, elem_ty);
-        try writer.writeAll(")))");
-    } else {
-        try f.writeCValue(writer, lhs, .Other);
-        try v.elem(f, writer);
-    }
-
-    try writer.writeAll(";\n");
+    try a.assign(f, writer);
+    // We must convert to and from integer types to prevent UB if the operation
+    // results in a NULL pointer, or if LHS is NULL. The operation is only UB
+    // if the result is NULL and then dereferenced.
+    try writer.writeByte('(');
+    try f.renderCType(writer, inst_scalar_ctype);
+    try writer.writeAll(")(((uintptr_t)");
+    try f.writeCValue(writer, lhs, .Other);
+    try v.elem(f, writer);
+    try writer.writeAll(") ");
+    try writer.writeByte(operator);
+    try writer.writeAll(" (");
+    try f.writeCValue(writer, rhs, .Other);
+    try v.elem(f, writer);
+    try writer.writeAll("*sizeof(");
+    try f.renderType(writer, elem_ty);
+    try writer.writeAll(")))");
+    try a.end(f, writer);
     try v.end(f, inst, writer);
-
     return local;
 }
 
@@ -4273,14 +4467,14 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     {
-        const a = try Assignment.start(f, writer, ptr_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));
         try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
         try a.assign(f, writer);
         try f.writeCValue(writer, ptr, .Other);
         try a.end(f, writer);
     }
     {
-        const a = try Assignment.start(f, writer, Type.usize);
+        const a = try Assignment.start(f, writer, CType.usize);
         try f.writeCValueMember(writer, local, .{ .identifier = "len" });
         try a.assign(f, writer);
         try f.writeCValue(writer, len, .Initializer);
@@ -4347,7 +4541,7 @@ fn airCall(
     }).?;
     const ret_ty = Type.fromInterned(fn_info.return_type);
     const ret_ctype: CType = if (ret_ty.isNoReturn(zcu))
-        .{ .index = .void }
+        CType.void
     else
         try f.ctypeFromType(ret_ty, .parameter);
 
@@ -4359,7 +4553,7 @@ fn airCall(
             break :result .none;
         } else if (f.liveness.isUnused(inst)) {
             try writer.writeByte('(');
-            try f.renderCType(writer, .{ .index = .void });
+            try f.renderCType(writer, CType.void);
             try writer.writeByte(')');
             break :result .none;
         } else {
@@ -4414,10 +4608,7 @@ fn airCall(
         if (need_comma) try writer.writeAll(", ");
         need_comma = true;
         try f.writeCValue(writer, resolved_arg, .FunctionArgument);
-        switch (resolved_arg) {
-            .new_local => |local| try freeLocal(f, inst, local, null),
-            else => {},
-        }
+        try f.freeCValue(inst, resolved_arg);
     }
     try writer.writeAll(");\n");
 
@@ -4601,7 +4792,7 @@ fn lowerTry(
     }
 
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     if (is_ptr) {
@@ -4624,7 +4815,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
         const operand = try f.resolveInst(branch.operand);
         try reap(f, inst, &.{branch.operand});
 
-        const a = try Assignment.start(f, writer, operand_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));
         try f.writeCValue(writer, result, .Other);
         try a.assign(f, writer);
         try f.writeCValue(writer, operand, .Other);
@@ -4637,53 +4828,17 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
 
 fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
     const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
-    const dest_ty = f.typeOfIndex(inst);
+    const inst_ty = f.typeOfIndex(inst);
 
     const operand = try f.resolveInst(ty_op.operand);
     const operand_ty = f.typeOf(ty_op.operand);
 
-    const bitcasted = try bitcast(f, dest_ty, operand, operand_ty);
+    const bitcasted = try bitcast(f, inst_ty, operand, operand_ty);
     try reap(f, inst, &.{ty_op.operand});
-    return bitcasted.move(f, inst, dest_ty);
+    return f.moveCValue(inst, inst_ty, bitcasted);
 }
 
-const LocalResult = struct {
-    c_value: CValue,
-    need_free: bool,
-
-    fn move(lr: LocalResult, f: *Function, inst: Air.Inst.Index, dest_ty: Type) !CValue {
-        const zcu = f.object.dg.zcu;
-
-        if (lr.need_free) {
-            // Move the freshly allocated local to be owned by this instruction,
-            // by returning it here instead of freeing it.
-            return lr.c_value;
-        }
-
-        const local = try f.allocLocal(inst, dest_ty);
-        try lr.free(f);
-        const writer = f.object.writer();
-        try f.writeCValue(writer, local, .Other);
-        if (dest_ty.isAbiInt(zcu)) {
-            try writer.writeAll(" = ");
-        } else {
-            try writer.writeAll(" = (");
-            try f.renderType(writer, dest_ty);
-            try writer.writeByte(')');
-        }
-        try f.writeCValue(writer, lr.c_value, .Initializer);
-        try writer.writeAll(";\n");
-        return local;
-    }
-
-    fn free(lr: LocalResult, f: *Function) !void {
-        if (lr.need_free) {
-            try freeLocal(f, null, lr.c_value.new_local, null);
-        }
-    }
-};
-
-fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !LocalResult {
+fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue {
     const zcu = f.object.dg.zcu;
     const target = &f.object.dg.mod.resolved_target.result;
     const ctype_pool = &f.object.dg.ctype_pool;
@@ -4693,13 +4848,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
         const src_info = dest_ty.intInfo(zcu);
         const dest_info = operand_ty.intInfo(zcu);
         if (src_info.signedness == dest_info.signedness and
-            src_info.bits == dest_info.bits)
-        {
-            return .{
-                .c_value = operand,
-                .need_free = false,
-            };
-        }
+            src_info.bits == dest_info.bits) return operand;
     }
 
     if (dest_ty.isPtrAtRuntime(zcu) and operand_ty.isPtrAtRuntime(zcu)) {
@@ -4710,10 +4859,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
         try writer.writeByte(')');
         try f.writeCValue(writer, operand, .Other);
         try writer.writeAll(";\n");
-        return .{
-            .c_value = local,
-            .need_free = true,
-        };
+        return local;
     }
 
     const operand_lval = if (operand == .constant) blk: {
@@ -4800,14 +4946,8 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
         try writer.writeAll(");\n");
     }
 
-    if (operand == .constant) {
-        try freeLocal(f, null, operand_lval.new_local, null);
-    }
-
-    return .{
-        .c_value = local,
-        .need_free = true,
-    };
+    try f.freeCValue(null, operand_lval);
+    return local;
 }
 
 fn airTrap(f: *Function, writer: anytype) !CValue {
@@ -4918,13 +5058,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
 
     try writer.writeAll("switch (");
-    if (condition_ty.zigTypeTag(zcu) == .Bool) {
-        try writer.writeByte('(');
-        try f.renderType(writer, Type.u1);
-        try writer.writeByte(')');
-    } else if (condition_ty.isPtrAtRuntime(zcu)) {
+
+    const lowered_condition_ty = if (condition_ty.toIntern() == .bool_type)
+        Type.u1
+    else if (condition_ty.isPtrAtRuntime(zcu))
+        Type.usize
+    else
+        condition_ty;
+    if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {
         try writer.writeByte('(');
-        try f.renderType(writer, Type.usize);
+        try f.renderType(writer, lowered_condition_ty);
         try writer.writeByte(')');
     }
     try f.writeCValue(writer, condition, .Other);
@@ -4943,18 +5086,24 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
     for (0..switch_br.data.cases_len) |case_i| {
         const case = f.air.extraData(Air.SwitchBr.Case, extra_index);
         const items = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[case.end..][0..case.data.items_len]));
-        const case_body: []const Air.Inst.Index = @ptrCast(f.air.extra[case.end + items.len ..][0..case.data.body_len]);
+        const case_body: []const Air.Inst.Index =
+            @ptrCast(f.air.extra[case.end + items.len ..][0..case.data.body_len]);
         extra_index = case.end + case.data.items_len + case_body.len;
 
         for (items) |item| {
             try f.object.indent_writer.insertNewline();
             try writer.writeAll("case ");
-            if (condition_ty.isPtrAtRuntime(zcu)) {
-                try writer.writeByte('(');
-                try f.renderType(writer, Type.usize);
-                try writer.writeByte(')');
+            const item_value = try f.air.value(item, zcu);
+            if (item_value.?.getUnsignedInt(zcu)) |item_int| try writer.print("{}\n", .{
+                try f.fmtIntLiteral(try zcu.intValue(lowered_condition_ty, item_int)),
+            }) else {
+                if (condition_ty.isPtrAtRuntime(zcu)) {
+                    try writer.writeByte('(');
+                    try f.renderType(writer, Type.usize);
+                    try writer.writeByte(')');
+                }
+                try f.object.dg.renderValue(writer, (try f.air.value(item, zcu)).?, .Other);
             }
-            try f.object.dg.renderValue(writer, (try f.air.value(item, zcu)).?, .Other);
             try writer.writeByte(':');
         }
         try writer.writeByte(' ');
@@ -5276,10 +5425,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
 fn airIsNull(
     f: *Function,
     inst: Air.Inst.Index,
-    operator: []const u8,
+    operator: std.math.CompareOperator,
     is_ptr: bool,
 ) !CValue {
     const zcu = f.object.dg.zcu;
+    const ctype_pool = &f.object.dg.ctype_pool;
     const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
 
     const writer = f.object.writer();
@@ -5287,106 +5437,84 @@ fn airIsNull(
     try reap(f, inst, &.{un_op});
 
     const local = try f.allocLocal(inst, Type.bool);
+    const a = try Assignment.start(f, writer, CType.bool);
     try f.writeCValue(writer, local, .Other);
-    try writer.writeAll(" = ");
-    if (is_ptr) {
-        try f.writeCValueDeref(writer, operand);
-    } else {
-        try f.writeCValue(writer, operand, .Other);
-    }
+    try a.assign(f, writer);
 
     const operand_ty = f.typeOf(un_op);
     const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
-    const payload_ty = optional_ty.optionalChild(zcu);
-    const err_int_ty = try zcu.errorIntType();
-
-    const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
-        Value.true
-    else if (optional_ty.isPtrLikeOptional(zcu))
-        // operand is a regular pointer, test `operand !=/== NULL`
-        try zcu.getCoerced(Value.null, optional_ty)
-    else if (payload_ty.zigTypeTag(zcu) == .ErrorSet)
-        try zcu.intValue(err_int_ty, 0)
-    else if (payload_ty.isSlice(zcu) and optional_ty.optionalReprIsPayload(zcu)) rhs: {
-        try writer.writeAll(".ptr");
-        const slice_ptr_ty = payload_ty.slicePtrFieldType(zcu);
-        const opt_slice_ptr_ty = try zcu.optionalType(slice_ptr_ty.toIntern());
-        break :rhs try zcu.nullValue(opt_slice_ptr_ty);
-    } else rhs: {
-        try writer.writeAll(".is_null");
-        break :rhs Value.true;
+    const opt_ctype = try f.ctypeFromType(optional_ty, .complete);
+    const rhs = switch (opt_ctype.info(ctype_pool)) {
+        .basic, .pointer => rhs: {
+            if (is_ptr)
+                try f.writeCValueDeref(writer, operand)
+            else
+                try f.writeCValue(writer, operand, .Other);
+            break :rhs if (opt_ctype.isBool())
+                "true"
+            else if (opt_ctype.isInteger())
+                "0"
+            else
+                "NULL";
+        },
+        .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+        .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
+            .is_null, .payload => rhs: {
+                if (is_ptr)
+                    try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" })
+                else
+                    try f.writeCValueMember(writer, operand, .{ .identifier = "is_null" });
+                break :rhs "true";
+            },
+            .ptr, .len => rhs: {
+                if (is_ptr)
+                    try f.writeCValueDerefMember(writer, operand, .{ .identifier = "ptr" })
+                else
+                    try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });
+                break :rhs "NULL";
+            },
+            else => unreachable,
+        },
     };
-    try writer.writeByte(' ');
-    try writer.writeAll(operator);
-    try writer.writeByte(' ');
-    try f.object.dg.renderValue(writer, rhs, .Other);
-    try writer.writeAll(";\n");
-    return local;
-}
-
-fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
-    const zcu = f.object.dg.zcu;
-    const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
-
-    const operand = try f.resolveInst(ty_op.operand);
-    try reap(f, inst, &.{ty_op.operand});
-    const opt_ty = f.typeOf(ty_op.operand);
-
-    const payload_ty = opt_ty.optionalChild(zcu);
-
-    if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-        return .none;
-    }
-
-    const inst_ty = f.typeOfIndex(inst);
-    const writer = f.object.writer();
-    const local = try f.allocLocal(inst, inst_ty);
-
-    if (opt_ty.optionalReprIsPayload(zcu)) {
-        try f.writeCValue(writer, local, .Other);
-        try writer.writeAll(" = ");
-        try f.writeCValue(writer, operand, .Other);
-        try writer.writeAll(";\n");
-        return local;
-    }
-
-    const a = try Assignment.start(f, writer, inst_ty);
-    try f.writeCValue(writer, local, .Other);
-    try a.assign(f, writer);
-    try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
+    try writer.writeAll(compareOperatorC(operator));
+    try writer.writeAll(rhs);
     try a.end(f, writer);
     return local;
 }
 
-fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
+fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
     const zcu = f.object.dg.zcu;
+    const ctype_pool = &f.object.dg.ctype_pool;
     const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
 
-    const writer = f.object.writer();
-    const operand = try f.resolveInst(ty_op.operand);
-    try reap(f, inst, &.{ty_op.operand});
-    const ptr_ty = f.typeOf(ty_op.operand);
-    const opt_ty = ptr_ty.childType(zcu);
     const inst_ty = f.typeOfIndex(inst);
+    const operand_ty = f.typeOf(ty_op.operand);
+    const opt_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
+    const opt_ctype = try f.ctypeFromType(opt_ty, .complete);
+    if (opt_ctype.isBool()) return if (is_ptr) .{ .undef = inst_ty } else .none;
 
-    if (!inst_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) {
-        return .{ .undef = inst_ty };
-    }
-
-    const local = try f.allocLocal(inst, inst_ty);
-    try f.writeCValue(writer, local, .Other);
-
-    if (opt_ty.optionalReprIsPayload(zcu)) {
-        // the operand is just a regular pointer, no need to do anything special.
-        // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
-        try writer.writeAll(" = ");
-        try f.writeCValue(writer, operand, .Other);
-    } else {
-        try writer.writeAll(" = &");
-        try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
+    const operand = try f.resolveInst(ty_op.operand);
+    switch (opt_ctype.info(ctype_pool)) {
+        .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),
+        .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+        .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
+            .is_null, .payload => {
+                const writer = f.object.writer();
+                const local = try f.allocLocal(inst, inst_ty);
+                const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
+                try f.writeCValue(writer, local, .Other);
+                try a.assign(f, writer);
+                if (is_ptr) {
+                    try writer.writeByte('&');
+                    try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
+                } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
+                try a.end(f, writer);
+                return local;
+            },
+            .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
+            else => unreachable,
+        },
     }
-    try writer.writeAll(";\n");
-    return local;
 }
 
 fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
@@ -5397,38 +5525,46 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
     try reap(f, inst, &.{ty_op.operand});
     const operand_ty = f.typeOf(ty_op.operand);
 
-    const opt_ty = operand_ty.childType(zcu);
-
     const inst_ty = f.typeOfIndex(inst);
-
-    if (opt_ty.optionalReprIsPayload(zcu)) {
-        if (f.liveness.isUnused(inst)) {
-            return .none;
-        }
-        const local = try f.allocLocal(inst, inst_ty);
-        // The payload and the optional are the same value.
-        // Setting to non-null will be done when the payload is set.
-        try f.writeCValue(writer, local, .Other);
-        try writer.writeAll(" = ");
-        try f.writeCValue(writer, operand, .Other);
-        try writer.writeAll(";\n");
-        return local;
-    } else {
-        try f.writeCValueDeref(writer, operand);
-        try writer.writeAll(".is_null = ");
-        try f.object.dg.renderValue(writer, Value.false, .Initializer);
-        try writer.writeAll(";\n");
-
-        if (f.liveness.isUnused(inst)) {
+    const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);
+    switch (opt_ctype.info(&f.object.dg.ctype_pool)) {
+        .basic => {
+            const a = try Assignment.start(f, writer, opt_ctype);
+            try f.writeCValueDeref(writer, operand);
+            try a.assign(f, writer);
+            try f.object.dg.renderValue(writer, Value.false, .Initializer);
+            try a.end(f, writer);
             return .none;
-        }
-
-        const local = try f.allocLocal(inst, inst_ty);
-        try f.writeCValue(writer, local, .Other);
-        try writer.writeAll(" = &");
-        try f.writeCValueDeref(writer, operand);
-        try writer.writeAll(".payload;\n");
-        return local;
+        },
+        .pointer => {
+            if (f.liveness.isUnused(inst)) return .none;
+            const local = try f.allocLocal(inst, inst_ty);
+            const a = try Assignment.start(f, writer, opt_ctype);
+            try f.writeCValue(writer, local, .Other);
+            try a.assign(f, writer);
+            try f.writeCValue(writer, operand, .Other);
+            try a.end(f, writer);
+            return local;
+        },
+        .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+        .aggregate => {
+            {
+                const a = try Assignment.start(f, writer, opt_ctype);
+                try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" });
+                try a.assign(f, writer);
+                try f.object.dg.renderValue(writer, Value.false, .Initializer);
+                try a.end(f, writer);
+            }
+            if (f.liveness.isUnused(inst)) return .none;
+            const local = try f.allocLocal(inst, inst_ty);
+            const a = try Assignment.start(f, writer, opt_ctype);
+            try f.writeCValue(writer, local, .Other);
+            try a.assign(f, writer);
+            try writer.writeByte('&');
+            try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
+            try a.end(f, writer);
+            return local;
+        },
     }
 }
 
@@ -5688,13 +5824,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
                     if (inst_ty.eql(field_int_ty, f.object.dg.zcu)) return temp_local;
 
                     const local = try f.allocLocal(inst, inst_ty);
-                    try writer.writeAll("memcpy(");
-                    try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);
-                    try writer.writeAll(", ");
-                    try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
-                    try writer.writeAll(", sizeof(");
-                    try f.renderType(writer, inst_ty);
-                    try writer.writeAll("));\n");
+                    if (local.new_local != temp_local.new_local) {
+                        try writer.writeAll("memcpy(");
+                        try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);
+                        try writer.writeAll(", ");
+                        try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
+                        try writer.writeAll(", sizeof(");
+                        try f.renderType(writer, inst_ty);
+                        try writer.writeAll("));\n");
+                    }
                     try freeLocal(f, inst, temp_local.new_local, null);
                     return local;
                 },
@@ -5723,20 +5861,23 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
                         try writer.writeAll(";\n");
                         break :blk operand_local;
                     } else struct_byval;
-
                     const local = try f.allocLocal(inst, inst_ty);
-                    try writer.writeAll("memcpy(&");
-                    try f.writeCValue(writer, local, .Other);
-                    try writer.writeAll(", &");
-                    try f.writeCValue(writer, operand_lval, .Other);
-                    try writer.writeAll(", sizeof(");
-                    try f.renderType(writer, inst_ty);
-                    try writer.writeAll("));\n");
-
-                    if (struct_byval == .constant) {
-                        try freeLocal(f, inst, operand_lval.new_local, null);
+                    if (switch (local) {
+                        .new_local, .local => |local_index| switch (operand_lval) {
+                            .new_local, .local => |operand_local_index| local_index != operand_local_index,
+                            else => true,
+                        },
+                        else => true,
+                    }) {
+                        try writer.writeAll("memcpy(&");
+                        try f.writeCValue(writer, local, .Other);
+                        try writer.writeAll(", &");
+                        try f.writeCValue(writer, operand_lval, .Other);
+                        try writer.writeAll(", sizeof(");
+                        try f.renderType(writer, inst_ty);
+                        try writer.writeAll("));\n");
                     }
-
+                    try f.freeCValue(inst, operand_lval);
                     return local;
                 },
             }
@@ -5745,7 +5886,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
     };
 
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValueMember(writer, struct_byval, field_name);
@@ -5818,7 +5959,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
     }
 
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     if (is_ptr) {
@@ -5830,35 +5971,42 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
 }
 
 fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
-    const zcu = f.object.dg.zcu;
+    const ctype_pool = &f.object.dg.ctype_pool;
     const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
 
     const inst_ty = f.typeOfIndex(inst);
-    const repr_is_payload = inst_ty.optionalReprIsPayload(zcu);
-    const payload_ty = f.typeOf(ty_op.operand);
-    const payload = try f.resolveInst(ty_op.operand);
-    try reap(f, inst, &.{ty_op.operand});
+    const inst_ctype = try f.ctypeFromType(inst_ty, .complete);
+    if (inst_ctype.isBool()) return .{ .constant = Value.true };
 
-    const writer = f.object.writer();
-    const local = try f.allocLocal(inst, inst_ty);
-    {
-        const a = try Assignment.start(f, writer, payload_ty);
-        if (repr_is_payload)
-            try f.writeCValue(writer, local, .Other)
-        else
-            try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
-        try a.assign(f, writer);
-        try f.writeCValue(writer, payload, .Other);
-        try a.end(f, writer);
-    }
-    if (!repr_is_payload) {
-        const a = try Assignment.start(f, writer, Type.bool);
-        try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
-        try a.assign(f, writer);
-        try f.object.dg.renderValue(writer, Value.false, .Other);
-        try a.end(f, writer);
+    const operand = try f.resolveInst(ty_op.operand);
+    switch (inst_ctype.info(ctype_pool)) {
+        .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),
+        .aligned, .array, .vector, .fwd_decl, .function => unreachable,
+        .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
+            .is_null, .payload => {
+                const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);
+                const writer = f.object.writer();
+                const local = try f.allocLocal(inst, inst_ty);
+                {
+                    const a = try Assignment.start(f, writer, CType.bool);
+                    try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
+                    try a.assign(f, writer);
+                    try writer.writeAll("false");
+                    try a.end(f, writer);
+                }
+                {
+                    const a = try Assignment.start(f, writer, operand_ctype);
+                    try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
+                    try a.assign(f, writer);
+                    try f.writeCValue(writer, operand, .Initializer);
+                    try a.end(f, writer);
+                }
+                return local;
+            },
+            .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
+            else => unreachable,
+        },
     }
-    return local;
 }
 
 fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
@@ -5881,14 +6029,14 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
     }
 
     if (!repr_is_err) {
-        const a = try Assignment.start(f, writer, payload_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
         try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
         try a.assign(f, writer);
         try f.object.dg.renderUndefValue(writer, payload_ty, .Other);
         try a.end(f, writer);
     }
     {
-        const a = try Assignment.start(f, writer, err_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));
         if (repr_is_err)
             try f.writeCValue(writer, local, .Other)
         else
@@ -5904,31 +6052,43 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
     const zcu = f.object.dg.zcu;
     const writer = f.object.writer();
     const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
+    const inst_ty = f.typeOfIndex(inst);
     const operand = try f.resolveInst(ty_op.operand);
-    const error_union_ty = f.typeOf(ty_op.operand).childType(zcu);
+    const operand_ty = f.typeOf(ty_op.operand);
+    const error_union_ty = operand_ty.childType(zcu);
 
     const payload_ty = error_union_ty.errorUnionPayload(zcu);
     const err_int_ty = try zcu.errorIntType();
     const no_err = try zcu.intValue(err_int_ty, 0);
+    try reap(f, inst, &.{ty_op.operand});
 
     // First, set the non-error value.
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));
         try f.writeCValueDeref(writer, operand);
-        try writer.print(" = {};\n", .{try f.fmtIntLiteral(no_err)});
-        return operand;
+        try a.assign(f, writer);
+        try writer.print("{}", .{try f.fmtIntLiteral(no_err)});
+        try a.end(f, writer);
+        return .none;
+    }
+    {
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(err_int_ty, .complete));
+        try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" });
+        try a.assign(f, writer);
+        try writer.print("{}", .{try f.fmtIntLiteral(no_err)});
+        try a.end(f, writer);
     }
-    try reap(f, inst, &.{ty_op.operand});
-    try f.writeCValueDeref(writer, operand);
-    try writer.print(".error = {};\n", .{try f.fmtIntLiteral(no_err)});
 
     // Then return the payload pointer (only if it is used)
     if (f.liveness.isUnused(inst)) return .none;
 
-    const local = try f.allocLocal(inst, f.typeOfIndex(inst));
+    const local = try f.allocLocal(inst, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
-    try writer.writeAll(" = &(");
-    try f.writeCValueDeref(writer, operand);
-    try writer.writeAll(").payload;\n");
+    try a.assign(f, writer);
+    try writer.writeByte('&');
+    try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
+    try a.end(f, writer);
     return local;
 }
 
@@ -5961,14 +6121,14 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     if (!repr_is_err) {
-        const a = try Assignment.start(f, writer, payload_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
         try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
         try a.assign(f, writer);
         try f.writeCValue(writer, payload, .Other);
         try a.end(f, writer);
     }
     {
-        const a = try Assignment.start(f, writer, err_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));
         if (repr_is_err)
             try f.writeCValue(writer, local, .Other)
         else
@@ -5993,7 +6153,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
     const payload_ty = err_union_ty.errorUnionPayload(zcu);
     const error_ty = err_union_ty.errorUnionSet(zcu);
 
-    const a = try Assignment.start(f, writer, Type.bool);
+    const a = try Assignment.start(f, writer, CType.bool);
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     const err_int_ty = try zcu.errorIntType();
@@ -6030,7 +6190,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
     const array_ty = operand_ty.childType(zcu);
 
     {
-        const a = try Assignment.start(f, writer, ptr_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));
         try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
         try a.assign(f, writer);
         if (operand == .undef) {
@@ -6056,7 +6216,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
         try a.end(f, writer);
     }
     {
-        const a = try Assignment.start(f, writer, Type.usize);
+        const a = try Assignment.start(f, writer, CType.usize);
         try f.writeCValueMember(writer, local, .{ .identifier = "len" });
         try a.assign(f, writer);
         try writer.print("{}", .{
@@ -6091,7 +6251,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     const v = try Vectorize.start(f, inst, writer, operand_ty);
-    const a = try Assignment.start(f, writer, scalar_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try v.elem(f, writer);
     try a.assign(f, writer);
@@ -6133,11 +6293,10 @@ fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {
     try writer.writeAll(" = (");
     try f.renderType(writer, inst_ty);
     try writer.writeByte(')');
-    if (operand_ty.isSlice(zcu)) {
-        try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });
-    } else {
+    if (operand_ty.isSlice(zcu))
+        try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" })
+    else
         try f.writeCValue(writer, operand, .Other);
-    }
     try writer.writeAll(";\n");
     return local;
 }
@@ -6306,9 +6465,10 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
     const new_value = try f.resolveInst(extra.new_value);
     const ptr_ty = f.typeOf(extra.ptr);
     const ty = ptr_ty.childType(zcu);
+    const ctype = try f.ctypeFromType(ty, .complete);
 
     const writer = f.object.writer();
-    const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);
+    const new_value_mat = try Materialize.start(f, inst, ty, new_value);
     try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
 
     const repr_ty = if (ty.isRuntimeFloat())
@@ -6319,7 +6479,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
     const local = try f.allocLocal(inst, inst_ty);
     if (inst_ty.isPtrLikeOptional(zcu)) {
         {
-            const a = try Assignment.start(f, writer, ty);
+            const a = try Assignment.start(f, writer, ctype);
             try f.writeCValue(writer, local, .Other);
             try a.assign(f, writer);
             try f.writeCValue(writer, expected_value, .Other);
@@ -6349,7 +6509,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
         try writer.writeAll(") {\n");
         f.object.indent_writer.pushIndent();
         {
-            const a = try Assignment.start(f, writer, ty);
+            const a = try Assignment.start(f, writer, ctype);
             try f.writeCValue(writer, local, .Other);
             try a.assign(f, writer);
             try writer.writeAll("NULL");
@@ -6359,14 +6519,14 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
         try writer.writeAll("}\n");
     } else {
         {
-            const a = try Assignment.start(f, writer, ty);
+            const a = try Assignment.start(f, writer, ctype);
             try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
             try a.assign(f, writer);
             try f.writeCValue(writer, expected_value, .Other);
             try a.end(f, writer);
         }
         {
-            const a = try Assignment.start(f, writer, Type.bool);
+            const a = try Assignment.start(f, writer, CType.bool);
             try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
             try a.assign(f, writer);
             try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
@@ -6412,7 +6572,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
     const operand = try f.resolveInst(extra.operand);
 
     const writer = f.object.writer();
-    const operand_mat = try Materialize.start(f, inst, writer, ty, operand);
+    const operand_mat = try Materialize.start(f, inst, ty, operand);
     try reap(f, inst, &.{ pl_op.operand, extra.operand });
 
     const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8));
@@ -6501,7 +6661,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
     const element = try f.resolveInst(bin_op.rhs);
 
     const writer = f.object.writer();
-    const element_mat = try Materialize.start(f, inst, writer, ty, element);
+    const element_mat = try Materialize.start(f, inst, ty, element);
     try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
 
     const repr_ty = if (ty.isRuntimeFloat())
@@ -6612,7 +6772,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
         try f.writeCValue(writer, index, .Other);
         try writer.writeAll(") ");
 
-        const a = try Assignment.start(f, writer, elem_ty);
+        const a = try Assignment.start(f, writer, try f.ctypeFromType(elem_ty, .complete));
         try writer.writeAll("((");
         try f.renderType(writer, elem_ptr_ty);
         try writer.writeByte(')');
@@ -6637,7 +6797,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
         .Slice => {
             try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });
             try writer.writeAll(", ");
-            try f.writeCValue(writer, bitcasted.c_value, .FunctionArgument);
+            try f.writeCValue(writer, bitcasted, .FunctionArgument);
             try writer.writeAll(", ");
             try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });
             try writer.writeAll(");\n");
@@ -6648,12 +6808,12 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
 
             try f.writeCValue(writer, dest_slice, .FunctionArgument);
             try writer.writeAll(", ");
-            try f.writeCValue(writer, bitcasted.c_value, .FunctionArgument);
+            try f.writeCValue(writer, bitcasted, .FunctionArgument);
             try writer.print(", {d});\n", .{len});
         },
         .Many, .C => unreachable,
     }
-    try bitcasted.free(f);
+    try f.freeCValue(inst, bitcasted);
     try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
     return .none;
 }
@@ -6700,7 +6860,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
     const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
 
     const writer = f.object.writer();
-    const a = try Assignment.start(f, writer, tag_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));
     try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });
     try a.assign(f, writer);
     try f.writeCValue(writer, new_tag, .Other);
@@ -6722,7 +6882,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
     const inst_ty = f.typeOfIndex(inst);
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
-    const a = try Assignment.start(f, writer, inst_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try a.assign(f, writer);
     try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });
@@ -6780,7 +6940,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, inst_ty);
     const v = try Vectorize.start(f, inst, writer, inst_ty);
-    const a = try Assignment.init(f, inst_scalar_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));
     try f.writeCValue(writer, local, .Other);
     try v.elem(f, writer);
     try a.assign(f, writer);
@@ -7033,7 +7193,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
     const local = try f.allocLocal(inst, inst_ty);
     switch (ip.indexToKey(inst_ty.toIntern())) {
         inline .array_type, .vector_type => |info, tag| {
-            const a = try Assignment.init(f, Type.fromInterned(info.child));
+            const a: Assignment = .{
+                .ctype = try f.ctypeFromType(Type.fromInterned(info.child), .complete),
+            };
             for (resolved_elements, 0..) |element, i| {
                 try a.restart(f, writer);
                 try f.writeCValue(writer, local, .Other);
@@ -7060,7 +7222,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
                         const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
                         if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
 
-                        const a = try Assignment.start(f, writer, field_ty);
+                        const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
                         try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
                             .{ .identifier = field_name.toSlice(ip) }
                         else
@@ -7140,7 +7302,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
             const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
             if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
 
-            const a = try Assignment.start(f, writer, field_ty);
+            const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
             try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
                 .{ .identifier = field_name.toSlice(ip) }
             else
@@ -7170,13 +7332,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
 
     const writer = f.object.writer();
     const local = try f.allocLocal(inst, union_ty);
-    if (loaded_union.getLayout(ip) == .@"packed") {
-        try f.writeCValue(writer, local, .Other);
-        try writer.writeAll(" = ");
-        try f.writeCValue(writer, payload, .Initializer);
-        try writer.writeAll(";\n");
-        return local;
-    }
+    if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload);
 
     const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {
         const layout = union_ty.unionGetLayout(zcu);
@@ -7184,7 +7340,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
             const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
             const tag_val = try zcu.enumValueFieldIndex(tag_ty, field_index);
 
-            const a = try Assignment.start(f, writer, tag_ty);
+            const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));
             try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
             try a.assign(f, writer);
             try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, zcu))});
@@ -7193,7 +7349,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
         break :field .{ .payload_identifier = field_name.toSlice(ip) };
     } else .{ .identifier = field_name.toSlice(ip) };
 
-    const a = try Assignment.start(f, writer, payload_ty);
+    const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
     try f.writeCValueMember(writer, local, field);
     try a.assign(f, writer);
     try f.writeCValue(writer, payload, .Other);
@@ -7648,11 +7804,13 @@ fn StringLiteral(comptime WriterType: type) type {
     // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,
     // regardless of the length of the string literal initializing it. Array initializer syntax is
     // used instead.
-    const max_string_initializer_len = 65535;
+    // C99 only requires 4095.
+    const max_string_initializer_len = @min(65535, 4095);
 
     // MSVC has a length limit of 16380 per string literal (before concatenation)
+    // C99 only requires 4095.
     const max_char_len = 4;
-    const max_literal_len = 16380 - max_char_len;
+    const max_literal_len = @min(16380 - max_char_len, 4095);
 
     return struct {
         len: u64,
@@ -7824,13 +7982,13 @@ fn formatIntLiteral(
     } = switch (data.ctype.info(ctype_pool)) {
         .basic => |basic_info| switch (basic_info) {
             else => .{
-                .ctype = .{ .index = .void },
+                .ctype = CType.void,
                 .count = 1,
                 .endian = .little,
                 .homogeneous = true,
             },
             .zig_u128, .zig_i128 => .{
-                .ctype = .{ .index = .uint64_t },
+                .ctype = CType.u64,
                 .count = 2,
                 .endian = .big,
                 .homogeneous = false,
@@ -7946,28 +8104,12 @@ fn formatIntLiteral(
 const Materialize = struct {
     local: CValue,
 
-    pub fn start(
-        f: *Function,
-        inst: Air.Inst.Index,
-        writer: anytype,
-        ty: Type,
-        value: CValue,
-    ) !Materialize {
-        switch (value) {
-            .local_ref, .constant, .decl_ref, .undef => {
-                const local = try f.allocLocal(inst, ty);
-
-                const a = try Assignment.start(f, writer, ty);
-                try f.writeCValue(writer, local, .Other);
-                try a.assign(f, writer);
-                try f.writeCValue(writer, value, .Other);
-                try a.end(f, writer);
-
-                return .{ .local = local };
-            },
-            .new_local => |local| return .{ .local = .{ .local = local } },
-            else => return .{ .local = value },
-        }
+    pub fn start(f: *Function, inst: Air.Inst.Index, ty: Type, value: CValue) !Materialize {
+        return .{ .local = switch (value) {
+            .local_ref, .constant, .decl_ref, .undef => try f.moveCValue(inst, ty, value),
+            .new_local => |local| .{ .local = local },
+            else => value,
+        } };
     }
 
     pub fn mat(self: Materialize, f: *Function, writer: anytype) !void {
@@ -7975,22 +8117,15 @@ const Materialize = struct {
     }
 
     pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
-        switch (self.local) {
-            .new_local => |local| try freeLocal(f, inst, local, null),
-            else => {},
-        }
+        try f.freeCValue(inst, self.local);
     }
 };
 
 const Assignment = struct {
     ctype: CType,
 
-    pub fn init(f: *Function, ty: Type) !Assignment {
-        return .{ .ctype = try f.ctypeFromType(ty, .complete) };
-    }
-
-    pub fn start(f: *Function, writer: anytype, ty: Type) !Assignment {
-        const self = try init(f, ty);
+    pub fn start(f: *Function, writer: anytype, ctype: CType) !Assignment {
+        const self: Assignment = .{ .ctype = ctype };
         try self.restart(f, writer);
         return self;
     }
test/behavior/abs.zig
@@ -214,7 +214,6 @@ fn testAbsIntVectors(comptime len: comptime_int) !void {
 }
 
 test "@abs unsigned int vectors" {
-    if (builtin.zig_backend == .stage2_c) 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
@@ -274,7 +273,6 @@ fn testAbsUnsignedIntVectors(comptime len: comptime_int) !void {
 }
 
 test "@abs float vectors" {
-    if (builtin.zig_backend == .stage2_c) 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
test/behavior/call.zig
@@ -267,7 +267,6 @@ test "arguments to comptime parameters generated in comptime blocks" {
 test "forced tail call" {
     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_c) 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_sparc64) return error.SkipZigTest; // TODO
@@ -280,6 +279,8 @@ test "forced tail call" {
         }
     }
 
+    if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support always tail calls
+
     const S = struct {
         fn fibonacciTailInternal(n: u16, a: u16, b: u16) u16 {
             if (n == 0) return a;
@@ -301,7 +302,6 @@ test "forced tail call" {
 test "inline call preserves tail call" {
     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_c) 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_sparc64) return error.SkipZigTest; // TODO
@@ -314,6 +314,8 @@ test "inline call preserves tail call" {
         }
     }
 
+    if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support always tail calls
+
     const max = std.math.maxInt(u16);
     const S = struct {
         var a: u16 = 0;
@@ -432,7 +434,6 @@ test "method call as parameter type" {
 
 test "non-anytype generic parameters provide result type" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_c) 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
@@ -463,7 +464,6 @@ test "non-anytype generic parameters provide result type" {
 
 test "argument to generic function has correct result type" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_c) 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
test/behavior/call_tail.zig
@@ -45,9 +45,10 @@ test "arguments pointed to on stack into tailcall" {
         else => {},
     }
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
+    if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support always tail calls
+
     var data = [_]u64{ 1, 6, 2, 7, 1, 9, 3 };
     base = @intFromPtr(&data);
     insertionSort(data[0..]);
test/behavior/cast.zig
@@ -1119,7 +1119,6 @@ fn foobar(func: PFN_void) !void {
 }
 
 test "cast function with an opaque parameter" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     if (builtin.zig_backend == .stage2_c) {
@@ -1461,6 +1460,7 @@ test "pointer to empty struct literal to mutable slice" {
 test "coerce between pointers of compatible differently-named floats" {
     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_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) 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 and builtin.target.ofmt != .macho) return error.SkipZigTest;
@@ -2558,7 +2558,6 @@ test "@intCast vector of signed integer" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_wasm) 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_x86_64) return error.SkipZigTest; // TODO
 
     var x: @Vector(4, i32) = .{ 1, 2, 3, 4 };
test/behavior/export_builtin.zig
@@ -5,7 +5,6 @@ const expect = std.testing.expect;
 test "exporting enum type and value" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     const S = struct {
         const E = enum(c_int) { one, two };
@@ -20,7 +19,6 @@ test "exporting enum type and value" {
 test "exporting with internal linkage" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     const S = struct {
         fn foo() callconv(.C) void {}
@@ -34,7 +32,6 @@ test "exporting with internal linkage" {
 test "exporting using field access" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     const S = struct {
         const Inner = struct {
test/behavior/extern.zig
@@ -16,7 +16,6 @@ test "anyopaque extern symbol" {
 export var a_mystery_symbol: i32 = 1234;
 
 test "function extern symbol" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
@@ -30,7 +29,6 @@ export fn a_mystery_function() i32 {
 }
 
 test "function extern symbol matches extern decl" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
test/behavior/fn.zig
@@ -582,7 +582,6 @@ test "pass and return comptime-only types" {
 test "pointer to alias behaves same as pointer to function" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const S = struct {
test/behavior/globals.zig
@@ -7,7 +7,6 @@ test "store to global array" {
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     try expect(pos[1] == 0.0);
     pos = [2]f32{ 0.0, 1.0 };
@@ -19,7 +18,6 @@ test "store to global vector" {
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     try expect(vpos[1] == 0.0);
     vpos = @Vector(2, f32){ 0.0, 1.0 };
@@ -49,7 +47,6 @@ test "global loads can affect liveness" {
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 
     const S = struct {
         const ByRef = struct {
test/behavior/optional.zig
@@ -55,17 +55,57 @@ fn testNullPtrsEql() !void {
     try expect(&number == x);
 }
 
-test "optional with void type" {
-    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+test "optional with zero-bit type" {
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
 
-    const Foo = struct {
-        x: ?void,
+    const S = struct {
+        fn doTheTest(comptime ZeroBit: type, comptime zero_bit: ZeroBit) !void {
+            const WithRuntime = struct {
+                zero_bit: ZeroBit,
+                runtime: u1,
+            };
+            var with_runtime: WithRuntime = undefined;
+            with_runtime = .{ .zero_bit = zero_bit, .runtime = 0 };
+
+            const Opt = struct { opt: ?ZeroBit };
+            var opt: Opt = .{ .opt = null };
+            try expect(opt.opt == null);
+            try expect(opt.opt != zero_bit);
+            try expect(opt.opt != with_runtime.zero_bit);
+            opt.opt = zero_bit;
+            try expect(opt.opt != null);
+            try expect(opt.opt == zero_bit);
+            try expect(opt.opt == with_runtime.zero_bit);
+            opt = .{ .opt = zero_bit };
+            try expect(opt.opt != null);
+            try expect(opt.opt == zero_bit);
+            try expect(opt.opt == with_runtime.zero_bit);
+            opt.opt = with_runtime.zero_bit;
+            try expect(opt.opt != null);
+            try expect(opt.opt == zero_bit);
+            try expect(opt.opt == with_runtime.zero_bit);
+            opt = .{ .opt = with_runtime.zero_bit };
+            try expect(opt.opt != null);
+            try expect(opt.opt == zero_bit);
+            try expect(opt.opt == with_runtime.zero_bit);
+
+            var two: ?struct { ZeroBit, ZeroBit } = undefined;
+            two = .{ with_runtime.zero_bit, with_runtime.zero_bit };
+            if (!@inComptime()) {
+                try expect(two != null);
+                try expect(two.?[0] == zero_bit);
+                try expect(two.?[0] == with_runtime.zero_bit);
+                try expect(two.?[1] == zero_bit);
+                try expect(two.?[1] == with_runtime.zero_bit);
+            }
+        }
     };
-    var x = Foo{ .x = null };
-    _ = &x;
-    try expect(x.x == null);
+
+    try S.doTheTest(void, {});
+    try comptime S.doTheTest(void, {});
+    try S.doTheTest(enum { only }, .only);
+    try comptime S.doTheTest(enum { only }, .only);
 }
 
 test "address of unwrap optional" {
test/behavior/packed-struct.zig
@@ -1125,12 +1125,13 @@ test "pointer loaded correctly from packed struct" {
             }
         }
     };
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
+    if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // crashes MSVC
+
     var ram = try RAM.new();
     var cpu = try CPU.new(&ram);
     try cpu.tick();
test/behavior/undefined.zig
@@ -101,7 +101,6 @@ test "reslice of undefined global var slice" {
 test "returned undef is 0xaa bytes when runtime safety is enabled" {
     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_c) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
test/behavior/union.zig
@@ -1644,7 +1644,6 @@ test "undefined-layout union field pointer has correct alignment" {
 }
 
 test "packed union field pointer has correct alignment" {
-    if (builtin.zig_backend == .stage2_c) 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_sparc64) return error.SkipZigTest; // TODO
test/behavior/vector.zig
@@ -1392,7 +1392,6 @@ test "store vector with memset" {
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
 
     if (builtin.zig_backend == .stage2_llvm) {
         switch (builtin.target.cpu.arch) {
test/tests.zig
@@ -1092,9 +1092,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
                     // Tracking issue for making the C backend generate C89 compatible code:
                     // https://github.com/ziglang/zig/issues/19468
                     "-std=c99",
-                    "-pedantic",
                     "-Werror",
 
+                    "-Wall",
+                    "-Wembedded-directive",
+                    "-Wempty-translation-unit",
+                    "-Wextra",
+                    "-Wgnu",
+                    "-Winvalid-utf8",
+                    "-Wkeyword-macro",
+                    "-Woverlength-strings",
+
                     // Tracking issue for making the C backend generate code
                     // that does not trigger warnings:
                     // https://github.com/ziglang/zig/issues/19467
@@ -1103,14 +1111,14 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
                     "-Wno-builtin-requires-header",
 
                     // spotted on linux
-                    "-Wno-gnu-folding-constant",
-                    "-Wno-incompatible-function-pointer-types",
-                    "-Wno-incompatible-pointer-types",
-                    "-Wno-overlength-strings",
+                    "-Wno-braced-scalar-init",
+                    "-Wno-excess-initializers",
+                    "-Wno-incompatible-pointer-types-discards-qualifiers",
+                    "-Wno-unused",
+                    "-Wno-unused-parameter",
 
                     // spotted on darwin
-                    "-Wno-dollar-in-identifier-extension",
-                    "-Wno-absolute-value",
+                    "-Wno-incompatible-pointer-types",
                 },
             });
             compile_c.addIncludePath(b.path("lib")); // for zig.h