From fedc9a19e7909694fac107c3da245e08616fd6e4 Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Wed, 17 May 2023 11:24:09 +0330 Subject: spirv: lower get_union_tag --- src/codegen/spirv.zig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/codegen') diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index d1def8a02e..1793e9fe18 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1735,6 +1735,7 @@ pub const DeclGen = struct { .slice_elem_val => try self.airSliceElemVal(inst), .ptr_elem_ptr => try self.airPtrElemPtr(inst), + .get_union_tag => try self.airGetUnionTag(inst), .struct_field_val => try self.airStructFieldVal(inst), .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), @@ -2320,6 +2321,22 @@ pub const DeclGen = struct { return result_id; } + fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const un_ty = self.air.typeOf(ty_op.operand); + + const target = self.module.getTarget(); + const layout = un_ty.unionGetLayout(target); + if (layout.tag_size == 0) return null; + + const union_handle = try self.resolve(ty_op.operand); + if (layout.payload_size == 0) return union_handle; + + const tag_ty = un_ty.unionTagTypeSafety().?; + const tag_index = @boolToInt(layout.tag_align < layout.payload_align); + return try self.extractField(tag_ty, union_handle, tag_index); + } + fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; -- cgit v1.2.3 From d7ddaf64a2978d80814ac7f57e3db2d1c6a45c2e Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 20 May 2023 17:25:17 +0200 Subject: spirv: don't generate union tag type if it doesnt exist Previously the tag type was generated even if it was nonexistant, triggering an assertion that an integer type should never have zero bits. Now its only generated when the tag type is actually emitted. --- src/codegen/spirv.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 1793e9fe18..644bb95cca 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1116,21 +1116,20 @@ pub const DeclGen = struct { return self.todo("packed union types", .{}); } - const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); if (layout.payload_size == 0) { // No payload, so represent this as just the tag type. - return tag_ty_ref; + return try self.resolveType(union_ty.tag_ty, .indirect); } var members = std.BoundedArray(SpvType.Payload.Struct.Member, 4){}; const has_tag = layout.tag_size != 0; const tag_first = layout.tag_align >= layout.payload_align; - const tag_member = .{ .name = "tag", .ty = tag_ty_ref }; const u8_ty_ref = try self.intType(.unsigned, 8); // TODO: What if Int8Type is not enabled? if (has_tag and tag_first) { - members.appendAssumeCapacity(tag_member); + const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); + members.appendAssumeCapacity(.{ .name = "tag", .ty = tag_ty_ref }); } const active_field = maybe_active_field orelse layout.most_aligned_field; @@ -1149,7 +1148,8 @@ pub const DeclGen = struct { } if (has_tag and !tag_first) { - members.appendAssumeCapacity(tag_member); + const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); + members.appendAssumeCapacity(.{ .name = "tag", .ty = tag_ty_ref }); } if (layout.padding != 0) { -- cgit v1.2.3