diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index d1def8a02ef5..c684842f298b 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -290,9 +290,6 @@ pub const DeclGen = struct { fn backingIntBits(self: *DeclGen, bits: u16) ?u16 { const target = self.getTarget(); - // The backend will never be asked to compiler a 0-bit integer, so we won't have to handle those in this function. - assert(bits != 0); - // 8, 16 and 64-bit integers require the Int8, Int16 and Inr64 capabilities respectively. // 32-bit integers are always supported (see spec, 2.16.1, Data rules). const ints = [_]struct { bits: u16, feature: ?Target.spirv.Feature }{ @@ -1735,6 +1732,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 +2318,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; diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 097caaad19e8..61ad010ed75a 100644 --- a/test/behavior/enum.zig +++ b/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, diff --git a/test/behavior/pub_enum.zig b/test/behavior/pub_enum.zig index 672d097250c0..e17546157db4 100644 --- a/test/behavior/pub_enum.zig +++ b/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 { diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 26232159b650..2520241aff84 100644 --- a/test/behavior/union.zig +++ b/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,