aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-05-20 23:26:04 +0300
committerGitHub <noreply@github.com>2023-05-20 23:26:04 +0300
commit413ef3aa38899195d113fc51a5c035a7c15103eb (patch)
treec66ecc65b4ea5e7c4886e335856aabeb15606c9d /src
parent56d8a1c89c4dd66c497ed37eac0643c8a1834597 (diff)
parentd7ddaf64a2978d80814ac7f57e3db2d1c6a45c2e (diff)
downloadzig-413ef3aa38899195d113fc51a5c035a7c15103eb.tar.gz
zig-413ef3aa38899195d113fc51a5c035a7c15103eb.zip
Merge pull request #15748 from alichraghi/ali-spirv
spirv: lower get_union_tag
Diffstat (limited to 'src')
-rw-r--r--src/codegen/spirv.zig27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index d1def8a02e..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) {
@@ -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;