authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-02-23 13:24:05+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:13+00:00
log2651b5ccdf2485172e9ba0345b9529733ee39273
tree5b87af9d557825b371f6209f9ab45864adcfba2a
parent160da8d6a4b82fa54f33e15025aaccc6f36f896f
signaturelock-open Commit is signed but in an unrecognized format.

llvm: fix some bugs


3 files changed, 48 insertions(+), 16 deletions(-)

src/Sema.zig+10
...@@ -24756,6 +24756,16 @@ fn zirBuiltinExtern(...@@ -24756,6 +24756,16 @@ fn zirBuiltinExtern(
24756 }24756 }
24757 const ptr_info = ty.ptrInfo(zcu);24757 const ptr_info = ty.ptrInfo(zcu);
2475824758
24759 if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") {
24760 const func_type = ip.indexToKey(ptr_info.child).func_type;
24761 for (func_type.param_types.get(ip)) |param_ty_ip| {
24762 const param_ty: Type = .fromInterned(param_ty_ip);
24763 if (param_ty.isPtrAtRuntime(zcu) or param_ty.isSliceAtRuntime(zcu)) {
24764 // LLVM wants this information for an "align" attribute on the parameter.
24765 try sema.ensureLayoutResolved(param_ty.nullablePtrElem(zcu), ty_src, .parameter);
24766 }
24767 }
24768 }
24759 const extern_val = try pt.getExtern(.{24769 const extern_val = try pt.getExtern(.{
24760 .name = options.name,24770 .name = options.name,
24761 .ty = ptr_info.child,24771 .ty = ptr_info.child,
src/Zcu/PerThread.zig+10
...@@ -1691,6 +1691,16 @@ fn analyzeNavVal(...@@ -1691,6 +1691,16 @@ fn analyzeNavVal(
1691 const lib_name_src = block.src(.{ .node_offset_lib_name = .zero });1691 const lib_name_src = block.src(.{ .node_offset_lib_name = .zero });
1692 try sema.handleExternLibName(&block, lib_name_src, l);1692 try sema.handleExternLibName(&block, lib_name_src, l);
1693 }1693 }
1694 if (nav_ty.zigTypeTag(zcu) == .@"fn") {
1695 const func_type = ip.indexToKey(nav_ty.toIntern()).func_type;
1696 for (func_type.param_types.get(ip)) |param_ty_ip| {
1697 const param_ty: Type = .fromInterned(param_ty_ip);
1698 if (param_ty.isPtrAtRuntime(zcu) or param_ty.isSliceAtRuntime(zcu)) {
1699 // LLVM wants this information for an "align" attribute on the parameter.
1700 try sema.ensureLayoutResolved(param_ty.nullablePtrElem(zcu), ty_src, .parameter);
1701 }
1702 }
1703 }
1694 break :val .fromInterned(try pt.getExtern(.{1704 break :val .fromInterned(try pt.getExtern(.{
1695 .name = old_nav.name,1705 .name = old_nav.name,
1696 .ty = nav_ty.toIntern(),1706 .ty = nav_ty.toIntern(),
src/codegen/llvm.zig+28-16
...@@ -2327,16 +2327,21 @@ pub const Object = struct {...@@ -2327,16 +2327,21 @@ pub const Object = struct {
2327 const layout = Type.getUnionLayout(union_type, zcu);2327 const layout = Type.getUnionLayout(union_type, zcu);
23282328
2329 if (layout.payload_size == 0) {2329 if (layout.payload_size == 0) {
2330 const tag_member = try o.builder.debugMemberType(2330 const fields_tuple: ?Builder.Metadata = fields: {
2331 try o.builder.metadataString("tag"),2331 if (layout.tag_size == 0) break :fields null;
2332 null, // file2332 break :fields try o.builder.metadataTuple(&.{
2333 ty_fwd_ref,2333 try o.builder.debugMemberType(
2334 0, // line2334 try o.builder.metadataString("tag"),
2335 try o.getDebugType(pt, enum_tag_ty),2335 null, // file
2336 layout.tag_size * 8,2336 ty_fwd_ref,
2337 layout.tag_align.toByteUnits().? * 8,2337 0, // line
2338 0, // offset2338 try o.getDebugType(pt, enum_tag_ty),
2339 );2339 layout.tag_size * 8,
2340 layout.tag_align.toByteUnits().? * 8,
2341 0, // offset
2342 ),
2343 });
2344 };
2340 return o.builder.debugStructType(2345 return o.builder.debugStructType(
2341 name,2346 name,
2342 file,2347 file,
...@@ -2345,7 +2350,7 @@ pub const Object = struct {...@@ -2345,7 +2350,7 @@ pub const Object = struct {
2345 null, // underlying type2350 null, // underlying type
2346 ty.abiSize(zcu) * 8,2351 ty.abiSize(zcu) * 8,
2347 ty.abiAlignment(zcu).toByteUnits().? * 8,2352 ty.abiAlignment(zcu).toByteUnits().? * 8,
2348 try o.builder.metadataTuple(&.{tag_member}),2353 fields_tuple,
2349 );2354 );
2350 }2355 }
23512356
...@@ -3141,12 +3146,16 @@ pub const Object = struct {...@@ -3141,12 +3146,16 @@ pub const Object = struct {
3141 var struct_kind: Builder.Type.Structure.Kind = .normal;3146 var struct_kind: Builder.Type.Structure.Kind = .normal;
3142 // When we encounter a zero-bit field, we place it here so we know to map it to the next non-zero-bit field (if any).3147 // When we encounter a zero-bit field, we place it here so we know to map it to the next non-zero-bit field (if any).
3143 var it = struct_type.iterateRuntimeOrder(ip);3148 var it = struct_type.iterateRuntimeOrder(ip);
3149 var max_field_ty_align: InternPool.Alignment = .@"1";
3144 while (it.next()) |field_index| {3150 while (it.next()) |field_index| {
3145 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3151 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3152 const field_ty_align = field_ty.abiAlignment(zcu);
3153 max_field_ty_align = max_field_ty_align.maxStrict(field_ty_align);
3154
3146 const prev_offset = offset;3155 const prev_offset = offset;
3147 offset = struct_type.field_offsets.get(ip)[field_index];3156 offset = struct_type.field_offsets.get(ip)[field_index];
3148 if (@ctz(offset) < field_ty.abiAlignment(zcu).toLog2Units()) {3157 if (@ctz(offset) < field_ty_align.toLog2Units()) {
3149 struct_kind = .@"packed";3158 struct_kind = .@"packed"; // prevent unexpected padding before this field
3150 }3159 }
31513160
3152 const padding_len = offset - prev_offset;3161 const padding_len = offset - prev_offset;
...@@ -3184,6 +3193,9 @@ pub const Object = struct {...@@ -3184,6 +3193,9 @@ pub const Object = struct {
3184 o.gpa,3193 o.gpa,
3185 try o.builder.arrayType(padding_len, .i8),3194 try o.builder.arrayType(padding_len, .i8),
3186 );3195 );
3196 if (@ctz(offset) < max_field_ty_align.toLog2Units()) {
3197 struct_kind = .@"packed"; // prevent unexpected trailing padding
3198 }
3187 }3199 }
31883200
3189 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));3201 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
...@@ -3883,7 +3895,7 @@ pub const Object = struct {...@@ -3883,7 +3895,7 @@ pub const Object = struct {
3883 const payload = try o.lowerValue(pt, un.val);3895 const payload = try o.lowerValue(pt, un.val);
3884 const payload_ty = payload.typeOf(&o.builder);3896 const payload_ty = payload.typeOf(&o.builder);
3885 if (payload_ty != union_ty.structFields(&o.builder)[3897 if (payload_ty != union_ty.structFields(&o.builder)[
3886 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))3898 @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align))
3887 ]) need_unnamed = true;3899 ]) need_unnamed = true;
3888 const field_size = field_ty.abiSize(zcu);3900 const field_size = field_ty.abiSize(zcu);
3889 if (field_size == layout.payload_size) break :p payload;3901 if (field_size == layout.payload_size) break :p payload;
...@@ -6806,7 +6818,7 @@ pub const FuncGen = struct {...@@ -6806,7 +6818,7 @@ pub const FuncGen = struct {
6806 .@"union" => {6818 .@"union" => {
6807 const union_llvm_ty = try o.lowerType(pt, struct_ty);6819 const union_llvm_ty = try o.lowerType(pt, struct_ty);
6808 const layout = struct_ty.unionGetLayout(zcu);6820 const layout = struct_ty.unionGetLayout(zcu);
6809 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));6821 const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align));
6810 const field_ptr =6822 const field_ptr =
6811 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");6823 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
6812 const payload_alignment = layout.payload_align.toLlvm();6824 const payload_alignment = layout.payload_align.toLlvm();
...@@ -11063,7 +11075,7 @@ pub const FuncGen = struct {...@@ -11063,7 +11075,7 @@ pub const FuncGen = struct {
11063 .@"union" => {11075 .@"union" => {
11064 const layout = struct_ty.unionGetLayout(zcu);11076 const layout = struct_ty.unionGetLayout(zcu);
11065 if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr;11077 if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr;
11066 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));11078 const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align));
11067 const union_llvm_ty = try o.lowerType(pt, struct_ty);11079 const union_llvm_ty = try o.lowerType(pt, struct_ty);
11068 return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, "");11080 return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, "");
11069 },11081 },