Commit fedc9a19e7

Ali Chraghi <alichraghi@proton.me>
2023-05-17 09:54:09
spirv: lower get_union_tag
1 parent 40e8c22
Changed files (4)
src
codegen
test
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;
 
test/behavior/enum.zig
@@ -910,7 +910,6 @@ test "enum literal casting to tagged union" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const Arch = union(enum) {
         x86_64,
test/behavior/pub_enum.zig
@@ -3,8 +3,6 @@ const other = @import("pub_enum/other.zig");
 const expect = @import("std").testing.expect;
 
 test "pub enum" {
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
-
     try pubEnumTest(other.APubEnum.Two);
 }
 fn pubEnumTest(foo: other.APubEnum) !void {
test/behavior/union.zig
@@ -272,7 +272,6 @@ test "comparison between union and enum literal" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     try testComparison();
     comptime try testComparison();
@@ -288,7 +287,6 @@ test "cast union to tag type of union" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     try testCastUnionToTag();
     comptime try testCastUnionToTag();
@@ -309,7 +307,6 @@ test "cast tag type of union to union" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     var x: Value2 = Letter2.B;
     try expect(@as(Letter2, x) == Letter2.B);
@@ -325,7 +322,6 @@ test "implicit cast union to its tag type" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     var x: Value2 = Letter2.B;
     try expect(x == Letter2.B);
@@ -422,7 +418,6 @@ test "tagged union with no payloads" {
 
 test "union with only 1 field casted to its enum type" {
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const Literal = union(enum) {
         Number: f64,
@@ -736,7 +731,6 @@ test "@enumToInt works on unions" {
     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
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const Bar = union(enum) {
         A: bool,
@@ -959,7 +953,6 @@ test "function call result coerces from tagged union to the tag" {
     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
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const S = struct {
         const Arch = union(enum) {
@@ -1467,8 +1460,6 @@ test "packed union in packed struct" {
 }
 
 test "Namespace-like union" {
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
-
     const DepType = enum {
         git,
         http,