authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-29 11:32:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:56-07:00
log5580a69d714af92883e2031a131c30917162dc15
tree0670bfea111f650038a883b29588be61a1f31101
parenta702af062bb65673ba554dba330b4c5ca8d50f3e

cbe: fix InternPool regressions


2 files changed, 164 insertions(+), 275 deletions(-)

src/Module.zig+5-2
......@@ -707,8 +707,11 @@ pub const Decl = struct {
707707 return TypedValue{ .ty = decl.ty, .val = decl.val };
708708 }
709709
710 pub fn internValue(decl: Decl, mod: *Module) Allocator.Error!InternPool.Index {
711 return decl.val.intern(decl.ty, mod);
710 pub fn internValue(decl: *Decl, mod: *Module) Allocator.Error!InternPool.Index {
711 assert(decl.has_tv);
712 const ip_index = try decl.val.intern(decl.ty, mod);
713 decl.val = ip_index.toValue();
714 return ip_index;
712715 }
713716
714717 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
src/codegen/c.zig+159-273
......@@ -560,7 +560,7 @@ pub const DeclGen = struct {
560560 // them). The analysis until now should ensure that the C function
561561 // pointers are compatible. If they are not, then there is a bug
562562 // somewhere and we should let the C compiler tell us about it.
563 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.eql(decl.ty, mod);
563 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.ty, mod);
564564 if (need_typecast) {
565565 try writer.writeAll("((");
566566 try dg.renderType(writer, ty);
......@@ -581,6 +581,7 @@ pub const DeclGen = struct {
581581 ) error{ OutOfMemory, AnalysisFail }!void {
582582 const mod = dg.module;
583583 const ptr_ty = mod.intern_pool.typeOf(ptr_val).toType();
584 const ptr_cty = try dg.typeToIndex(ptr_ty, .complete);
584585 const ptr = mod.intern_pool.indexToKey(ptr_val).ptr;
585586 switch (ptr.addr) {
586587 .decl, .mut_decl => try dg.renderDeclValue(
......@@ -598,22 +599,66 @@ pub const DeclGen = struct {
598599 try dg.fmtIntLiteral(Type.usize, int.toValue(), .Other),
599600 }),
600601 .eu_payload, .opt_payload => |base| {
601 const base_ty = mod.intern_pool.typeOf(base).toType().childType(mod);
602 const ptr_base_ty = mod.intern_pool.typeOf(base).toType();
603 const base_ty = ptr_base_ty.childType(mod);
602604 // Ensure complete type definition is visible before accessing fields.
603605 _ = try dg.typeToIndex(base_ty, .complete);
606 const payload_ty = switch (ptr.addr) {
607 .eu_payload => base_ty.errorUnionPayload(mod),
608 .opt_payload => base_ty.optionalChild(mod),
609 else => unreachable,
610 };
611 const ptr_payload_ty = try mod.adjustPtrTypeChild(ptr_base_ty, payload_ty);
612 const ptr_payload_cty = try dg.typeToIndex(ptr_payload_ty, .complete);
613 if (ptr_cty != ptr_payload_cty) {
614 try writer.writeByte('(');
615 try dg.renderCType(writer, ptr_cty);
616 try writer.writeByte(')');
617 }
604618 try writer.writeAll("&(");
605619 try dg.renderParentPtr(writer, base, location);
606620 try writer.writeAll(")->payload");
607621 },
608622 .elem => |elem| {
623 const ptr_base_ty = mod.intern_pool.typeOf(elem.base).toType();
624 const elem_ty = ptr_base_ty.elemType2(mod);
625 const ptr_elem_ty = try mod.adjustPtrTypeChild(ptr_base_ty, elem_ty);
626 const ptr_elem_cty = try dg.typeToIndex(ptr_elem_ty, .complete);
627 if (ptr_cty != ptr_elem_cty) {
628 try writer.writeByte('(');
629 try dg.renderCType(writer, ptr_cty);
630 try writer.writeByte(')');
631 }
609632 try writer.writeAll("&(");
633 if (mod.intern_pool.indexToKey(ptr_base_ty.toIntern()).ptr_type.size == .One)
634 try writer.writeByte('*');
610635 try dg.renderParentPtr(writer, elem.base, location);
611636 try writer.print(")[{d}]", .{elem.index});
612637 },
613638 .field => |field| {
614 const base_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod);
639 const ptr_base_ty = mod.intern_pool.typeOf(field.base).toType();
640 const base_ty = ptr_base_ty.childType(mod);
615641 // Ensure complete type definition is visible before accessing fields.
616642 _ = try dg.typeToIndex(base_ty, .complete);
643 const field_ty = switch (mod.intern_pool.indexToKey(base_ty.toIntern())) {
644 .anon_struct_type, .struct_type, .union_type => base_ty.structFieldType(field.index, mod),
645 .ptr_type => |ptr_type| switch (ptr_type.size) {
646 .One, .Many, .C => unreachable,
647 .Slice => switch (field.index) {
648 Value.slice_ptr_index => base_ty.slicePtrFieldType(mod),
649 Value.slice_len_index => Type.usize,
650 else => unreachable,
651 },
652 },
653 else => unreachable,
654 };
655 const ptr_field_ty = try mod.adjustPtrTypeChild(ptr_base_ty, field_ty);
656 const ptr_field_cty = try dg.typeToIndex(ptr_field_ty, .complete);
657 if (ptr_cty != ptr_field_cty) {
658 try writer.writeByte('(');
659 try dg.renderCType(writer, ptr_cty);
660 try writer.writeByte(')');
661 }
617662 switch (fieldLocation(base_ty, ptr_ty, @intCast(u32, field.index), mod)) {
618663 .begin => try dg.renderParentPtr(writer, field.base, location),
619664 .field => |name| {
......@@ -861,234 +906,6 @@ pub const DeclGen = struct {
861906 unreachable;
862907 }
863908
864 if (val.ip_index == .none) switch (ty.zigTypeTag(mod)) {
865 .Array, .Vector => {
866 if (location == .FunctionArgument) {
867 try writer.writeByte('(');
868 try dg.renderType(writer, ty);
869 try writer.writeByte(')');
870 }
871
872 // First try specific tag representations for more efficiency.
873 switch (val.toIntern()) {
874 .undef => {
875 const ai = ty.arrayInfo(mod);
876 try writer.writeByte('{');
877 if (ai.sentinel) |s| {
878 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
879 } else {
880 try writer.writeByte('0');
881 }
882 try writer.writeByte('}');
883 return;
884 },
885 .empty_struct => {
886 const ai = ty.arrayInfo(mod);
887 try writer.writeByte('{');
888 if (ai.sentinel) |s| {
889 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
890 } else {
891 try writer.writeByte('0');
892 }
893 try writer.writeByte('}');
894 return;
895 },
896 else => {},
897 }
898 // Fall back to generic implementation.
899
900 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal
901 const max_string_initializer_len = 65535;
902
903 const ai = ty.arrayInfo(mod);
904 if (ai.elem_type.eql(Type.u8, mod)) {
905 if (ai.len <= max_string_initializer_len) {
906 var literal = stringLiteral(writer);
907 try literal.start();
908 var index: usize = 0;
909 while (index < ai.len) : (index += 1) {
910 const elem_val = try val.elemValue(mod, index);
911 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
912 try literal.writeChar(elem_val_u8);
913 }
914 if (ai.sentinel) |s| {
915 const s_u8 = @intCast(u8, s.toUnsignedInt(mod));
916 if (s_u8 != 0) try literal.writeChar(s_u8);
917 }
918 try literal.end();
919 } else {
920 try writer.writeByte('{');
921 var index: usize = 0;
922 while (index < ai.len) : (index += 1) {
923 if (index != 0) try writer.writeByte(',');
924 const elem_val = try val.elemValue(mod, index);
925 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
926 try writer.print("'\\x{x}'", .{elem_val_u8});
927 }
928 if (ai.sentinel) |s| {
929 if (index != 0) try writer.writeByte(',');
930 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
931 }
932 try writer.writeByte('}');
933 }
934 } else {
935 try writer.writeByte('{');
936 var index: usize = 0;
937 while (index < ai.len) : (index += 1) {
938 if (index != 0) try writer.writeByte(',');
939 const elem_val = try val.elemValue(mod, index);
940 try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type);
941 }
942 if (ai.sentinel) |s| {
943 if (index != 0) try writer.writeByte(',');
944 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
945 }
946 try writer.writeByte('}');
947 }
948 },
949 .Struct => switch (ty.containerLayout(mod)) {
950 .Auto, .Extern => {
951 const field_vals = val.castTag(.aggregate).?.data;
952
953 if (!location.isInitializer()) {
954 try writer.writeByte('(');
955 try dg.renderType(writer, ty);
956 try writer.writeByte(')');
957 }
958
959 try writer.writeByte('{');
960 var empty = true;
961 for (field_vals, 0..) |field_val, field_i| {
962 if (ty.structFieldIsComptime(field_i, mod)) continue;
963 const field_ty = ty.structFieldType(field_i, mod);
964 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
965
966 if (!empty) try writer.writeByte(',');
967 try dg.renderValue(writer, field_ty, field_val, initializer_type);
968
969 empty = false;
970 }
971 try writer.writeByte('}');
972 },
973 .Packed => {
974 const field_vals = val.castTag(.aggregate).?.data;
975 const int_info = ty.intInfo(mod);
976
977 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
978 const bit_offset_ty = try mod.intType(.unsigned, bits);
979
980 var bit_offset: u64 = 0;
981
982 var eff_num_fields: usize = 0;
983 for (0..field_vals.len) |field_i| {
984 if (ty.structFieldIsComptime(field_i, mod)) continue;
985 const field_ty = ty.structFieldType(field_i, mod);
986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
987
988 eff_num_fields += 1;
989 }
990
991 if (eff_num_fields == 0) {
992 try writer.writeByte('(');
993 try dg.renderValue(writer, ty, Value.undef, initializer_type);
994 try writer.writeByte(')');
995 } else if (ty.bitSize(mod) > 64) {
996 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
997 var num_or = eff_num_fields - 1;
998 while (num_or > 0) : (num_or -= 1) {
999 try writer.writeAll("zig_or_");
1000 try dg.renderTypeForBuiltinFnName(writer, ty);
1001 try writer.writeByte('(');
1002 }
1003
1004 var eff_index: usize = 0;
1005 var needs_closing_paren = false;
1006 for (field_vals, 0..) |field_val, field_i| {
1007 if (ty.structFieldIsComptime(field_i, mod)) continue;
1008 const field_ty = ty.structFieldType(field_i, mod);
1009 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1010
1011 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
1012 if (bit_offset != 0) {
1013 try writer.writeAll("zig_shl_");
1014 try dg.renderTypeForBuiltinFnName(writer, ty);
1015 try writer.writeByte('(');
1016 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1017 try writer.writeAll(", ");
1018 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1019 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1020 try writer.writeByte(')');
1021 } else {
1022 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1023 }
1024
1025 if (needs_closing_paren) try writer.writeByte(')');
1026 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
1027
1028 bit_offset += field_ty.bitSize(mod);
1029 needs_closing_paren = true;
1030 eff_index += 1;
1031 }
1032 } else {
1033 try writer.writeByte('(');
1034 // a << a_off | b << b_off | c << c_off
1035 var empty = true;
1036 for (field_vals, 0..) |field_val, field_i| {
1037 if (ty.structFieldIsComptime(field_i, mod)) continue;
1038 const field_ty = ty.structFieldType(field_i, mod);
1039 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1040
1041 if (!empty) try writer.writeAll(" | ");
1042 try writer.writeByte('(');
1043 try dg.renderType(writer, ty);
1044 try writer.writeByte(')');
1045
1046 if (bit_offset != 0) {
1047 try dg.renderValue(writer, field_ty, field_val, .Other);
1048 try writer.writeAll(" << ");
1049 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1050 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1051 } else {
1052 try dg.renderValue(writer, field_ty, field_val, .Other);
1053 }
1054
1055 bit_offset += field_ty.bitSize(mod);
1056 empty = false;
1057 }
1058 try writer.writeByte(')');
1059 }
1060 },
1061 },
1062
1063 .Frame,
1064 .AnyFrame,
1065 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
1066 @tagName(tag),
1067 }),
1068
1069 .Float,
1070 .Union,
1071 .Optional,
1072 .ErrorUnion,
1073 .ErrorSet,
1074 .Int,
1075 .Enum,
1076 .Bool,
1077 .Pointer,
1078 => unreachable, // handled below
1079 .Type,
1080 .Void,
1081 .NoReturn,
1082 .ComptimeFloat,
1083 .ComptimeInt,
1084 .Undefined,
1085 .Null,
1086 .Opaque,
1087 .EnumLiteral,
1088 .Fn,
1089 => unreachable, // comptime-only types
1090 };
1091
1092909 switch (mod.intern_pool.indexToKey(val.ip_index)) {
1093910 // types, not values
1094911 .int_type,
......@@ -1144,10 +961,24 @@ pub const DeclGen = struct {
1144961 .error_union => |error_union| {
1145962 const payload_ty = ty.errorUnionPayload(mod);
1146963 const error_ty = ty.errorUnionSet(mod);
1147 const error_val = if (val.errorUnionIsPayload(mod)) try mod.intValue(Type.err_int, 0) else val;
1148
1149964 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1150 return dg.renderValue(writer, Type.err_int, error_val, location);
965 switch (error_union.val) {
966 .err_name => |err_name| return dg.renderValue(
967 writer,
968 error_ty,
969 (try mod.intern(.{ .err = .{
970 .ty = error_ty.toIntern(),
971 .name = err_name,
972 } })).toValue(),
973 location,
974 ),
975 .payload => return dg.renderValue(
976 writer,
977 Type.err_int,
978 try mod.intValue(Type.err_int, 0),
979 location,
980 ),
981 }
1151982 }
1152983
1153984 if (!location.isInitializer()) {
......@@ -1156,15 +987,34 @@ pub const DeclGen = struct {
1156987 try writer.writeByte(')');
1157988 }
1158989
1159 const payload_val = switch (error_union.val) {
1160 .err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
1161 .payload => |payload| payload,
1162 }.toValue();
1163
1164990 try writer.writeAll("{ .payload = ");
1165 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);
991 try dg.renderValue(
992 writer,
993 payload_ty,
994 switch (error_union.val) {
995 .err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
996 .payload => |payload| payload,
997 }.toValue(),
998 initializer_type,
999 );
11661000 try writer.writeAll(", .error = ");
1167 try dg.renderValue(writer, error_ty, error_val, initializer_type);
1001 switch (error_union.val) {
1002 .err_name => |err_name| try dg.renderValue(
1003 writer,
1004 error_ty,
1005 (try mod.intern(.{ .err = .{
1006 .ty = error_ty.toIntern(),
1007 .name = err_name,
1008 } })).toValue(),
1009 location,
1010 ),
1011 .payload => try dg.renderValue(
1012 writer,
1013 Type.err_int,
1014 try mod.intValue(Type.err_int, 0),
1015 location,
1016 ),
1017 }
11681018 try writer.writeAll(" }");
11691019 },
11701020 .enum_tag => {
......@@ -1272,30 +1122,42 @@ pub const DeclGen = struct {
12721122 }
12731123 try writer.writeByte('{');
12741124 }
1125 const ptr_location = switch (ptr.len) {
1126 .none => location,
1127 else => initializer_type,
1128 };
1129 const ptr_ty = switch (ptr.len) {
1130 .none => ty,
1131 else => ty.slicePtrFieldType(mod),
1132 };
1133 const ptr_val = switch (ptr.len) {
1134 .none => val,
1135 else => val.slicePtr(mod),
1136 };
12751137 switch (ptr.addr) {
12761138 .decl, .mut_decl => try dg.renderDeclValue(
12771139 writer,
1278 ty,
1279 val,
1140 ptr_ty,
1141 ptr_val,
12801142 switch (ptr.addr) {
12811143 .decl => |decl| decl,
12821144 .mut_decl => |mut_decl| mut_decl.decl,
12831145 else => unreachable,
12841146 },
1285 location,
1147 ptr_location,
12861148 ),
12871149 .int => |int| {
12881150 try writer.writeAll("((");
1289 try dg.renderType(writer, ty);
1151 try dg.renderType(writer, ptr_ty);
12901152 try writer.print("){x})", .{
1291 try dg.fmtIntLiteral(Type.usize, int.toValue(), .Other),
1153 try dg.fmtIntLiteral(Type.usize, int.toValue(), ptr_location),
12921154 });
12931155 },
12941156 .eu_payload,
12951157 .opt_payload,
12961158 .elem,
12971159 .field,
1298 => try dg.renderParentPtr(writer, val.ip_index, location),
1160 => try dg.renderParentPtr(writer, ptr_val.ip_index, ptr_location),
12991161 .comptime_field => unreachable,
13001162 }
13011163 if (ptr.len != .none) {
......@@ -1311,10 +1173,19 @@ pub const DeclGen = struct {
13111173 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
13121174 return dg.renderValue(writer, Type.bool, is_null_val, location);
13131175
1314 if (ty.optionalReprIsPayload(mod)) switch (opt.val) {
1315 .none => return writer.writeByte('0'),
1316 else => |payload| return dg.renderValue(writer, payload_ty, payload.toValue(), location),
1317 };
1176 if (ty.optionalReprIsPayload(mod)) return dg.renderValue(
1177 writer,
1178 payload_ty,
1179 switch (opt.val) {
1180 .none => switch (payload_ty.zigTypeTag(mod)) {
1181 .ErrorSet => try mod.intValue(Type.err_int, 0),
1182 .Pointer => try mod.getCoerced(val, payload_ty),
1183 else => unreachable,
1184 },
1185 else => |payload| payload.toValue(),
1186 },
1187 location,
1188 );
13181189
13191190 if (!location.isInitializer()) {
13201191 try writer.writeByte('(');
......@@ -2535,7 +2406,7 @@ pub fn genErrDecls(o: *Object) !void {
25352406 try writer.writeAll("enum {\n");
25362407 o.indent_writer.pushIndent();
25372408 var max_name_len: usize = 0;
2538 for (mod.error_name_list.items, 0..) |name, value| {
2409 for (mod.error_name_list.items[1..], 1..) |name, value| {
25392410 max_name_len = std.math.max(name.len, max_name_len);
25402411 const err_val = try mod.intern(.{ .err = .{
25412412 .ty = .anyerror_type,
......@@ -2562,21 +2433,21 @@ pub fn genErrDecls(o: *Object) !void {
25622433 .child = .u8_type,
25632434 .sentinel = .zero_u8,
25642435 });
2565
2566 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };
2567 const name_val = Value.initPayload(&name_pl.base);
2436 const name_val = try mod.intern(.{ .aggregate = .{
2437 .ty = name_ty.toIntern(),
2438 .storage = .{ .bytes = name },
2439 } });
25682440
25692441 try writer.writeAll("static ");
25702442 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, Const, 0, .complete);
25712443 try writer.writeAll(" = ");
2572 try o.dg.renderValue(writer, name_ty, name_val, .StaticInitializer);
2444 try o.dg.renderValue(writer, name_ty, name_val.toValue(), .StaticInitializer);
25732445 try writer.writeAll(";\n");
25742446 }
25752447
25762448 const name_array_ty = try mod.arrayType(.{
25772449 .len = mod.error_name_list.items.len,
25782450 .child = .slice_const_u8_sentinel_0_type,
2579 .sentinel = .zero_u8,
25802451 });
25812452
25822453 try writer.writeAll("static ");
......@@ -2588,7 +2459,7 @@ pub fn genErrDecls(o: *Object) !void {
25882459 const len_val = try mod.intValue(Type.usize, name.len);
25892460
25902461 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2591 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),
2462 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .StaticInitializer),
25922463 });
25932464 }
25942465 try writer.writeAll("};\n");
......@@ -2642,10 +2513,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
26422513 .child = .u8_type,
26432514 .sentinel = .zero_u8,
26442515 });
2645
2646 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };
2647 const name_val = Value.initPayload(&name_pl.base);
2648
2516 const name_val = try mod.intern(.{ .aggregate = .{
2517 .ty = name_ty.toIntern(),
2518 .storage = .{ .bytes = name },
2519 } });
26492520 const len_val = try mod.intValue(Type.usize, name.len);
26502521
26512522 try w.print(" case {}: {{\n static ", .{
......@@ -2653,7 +2524,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
26532524 });
26542525 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, 0, .complete);
26552526 try w.writeAll(" = ");
2656 try o.dg.renderValue(w, name_ty, name_val, .Initializer);
2527 try o.dg.renderValue(w, name_ty, name_val.toValue(), .Initializer);
26572528 try w.writeAll(";\n return (");
26582529 try o.dg.renderType(w, name_slice_ty);
26592530 try w.print("){{{}, {}}};\n", .{
......@@ -2789,7 +2660,7 @@ pub fn genDecl(o: *Object) !void {
27892660 const mod = o.dg.module;
27902661 const decl = o.dg.decl.?;
27912662 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };
2792 const tv: TypedValue = .{ .ty = decl.ty, .val = decl.val };
2663 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
27932664
27942665 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
27952666 if (tv.val.getExternFunc(mod)) |_| {
......@@ -4771,6 +4642,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
47714642 try writer.writeAll(") ");
47724643
47734644 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
4645 try writer.writeByte('\n');
47744646
47754647 // We don't need to use `genBodyResolveState` for the else block, because this instruction is
47764648 // noreturn so must terminate a body, therefore we don't need to leave `value_map` or
......@@ -5165,7 +5037,7 @@ fn airIsNull(
51655037 TypedValue{ .ty = Type.bool, .val = Value.true }
51665038 else if (optional_ty.isPtrLikeOptional(mod))
51675039 // operand is a regular pointer, test `operand !=/== NULL`
5168 TypedValue{ .ty = optional_ty, .val = try mod.nullValue(optional_ty) }
5040 TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }
51695041 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
51705042 TypedValue{ .ty = Type.err_int, .val = try mod.intValue(Type.err_int, 0) }
51715043 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
......@@ -5778,7 +5650,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
57785650 try reap(f, inst, &.{ty_op.operand});
57795651 try f.writeCValueDeref(writer, operand);
57805652 try writer.writeAll(".error = ");
5781 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);
5653 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
57825654 try writer.writeAll(";\n");
57835655
57845656 // Then return the payload pointer (only if it is used)
......@@ -6760,27 +6632,41 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67606632 try writer.writeAll(" = ");
67616633
67626634 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
6763 .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0),
6635 .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
6636 .Bool => Value.false,
6637 .Int => try mod.intValue(scalar_ty, 0),
6638 else => unreachable,
6639 },
67646640 .And => switch (scalar_ty.zigTypeTag(mod)) {
6765 .Bool => try mod.intValue(Type.comptime_int, 1),
6766 else => switch (scalar_ty.intInfo(mod).signedness) {
6641 .Bool => Value.true,
6642 .Int => switch (scalar_ty.intInfo(mod).signedness) {
67676643 .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty),
67686644 .signed => try mod.intValue(scalar_ty, -1),
67696645 },
6646 else => unreachable,
6647 },
6648 .Add => switch (scalar_ty.zigTypeTag(mod)) {
6649 .Int => try mod.intValue(scalar_ty, 0),
6650 .Float => try mod.floatValue(scalar_ty, 0.0),
6651 else => unreachable,
6652 },
6653 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
6654 .Int => try mod.intValue(scalar_ty, 1),
6655 .Float => try mod.floatValue(scalar_ty, 1.0),
6656 else => unreachable,
67706657 },
67716658 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6772 .Bool => Value.one_comptime_int,
6659 .Bool => Value.true,
67736660 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),
67746661 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
67756662 else => unreachable,
67766663 },
67776664 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6778 .Bool => try mod.intValue(scalar_ty, 0),
6779 .Int => try scalar_ty.minInt(mod, scalar_ty),
6665 .Bool => Value.false,
6666 .Int => try scalar_ty.minIntScalar(mod, scalar_ty),
67806667 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
67816668 else => unreachable,
67826669 },
6783 .Mul => try mod.intValue(Type.comptime_int, 1),
67846670 }, .Initializer);
67856671 try writer.writeAll(";\n");
67866672