| author | |
| committer | |
| log | 413ef3aa38899195d113fc51a5c035a7c15103eb |
| tree | c66ecc65b4ea5e7c4886e335856aabeb15606c9d |
| parent | 56d8a1c89c4dd66c497ed37eac0643c8a1834597 |
| parent | d7ddaf64a2978d80814ac7f57e3db2d1c6a45c2e |
| signature |
spirv: lower get_union_tag4 files changed, 22 insertions(+), 17 deletions(-)
src/codegen/spirv.zig+22-5| ... | ... | @@ -1116,21 +1116,20 @@ pub const DeclGen = struct { |
| 1116 | 1116 | return self.todo("packed union types", .{}); |
| 1117 | 1117 | } |
| 1118 | 1118 | |
| 1119 | const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); | |
| 1120 | 1119 | if (layout.payload_size == 0) { |
| 1121 | 1120 | // No payload, so represent this as just the tag type. |
| 1122 | return tag_ty_ref; | |
| 1121 | return try self.resolveType(union_ty.tag_ty, .indirect); | |
| 1123 | 1122 | } |
| 1124 | 1123 | |
| 1125 | 1124 | var members = std.BoundedArray(SpvType.Payload.Struct.Member, 4){}; |
| 1126 | 1125 | |
| 1127 | 1126 | const has_tag = layout.tag_size != 0; |
| 1128 | 1127 | const tag_first = layout.tag_align >= layout.payload_align; |
| 1129 | const tag_member = .{ .name = "tag", .ty = tag_ty_ref }; | |
| 1130 | 1128 | const u8_ty_ref = try self.intType(.unsigned, 8); // TODO: What if Int8Type is not enabled? |
| 1131 | 1129 | |
| 1132 | 1130 | if (has_tag and tag_first) { |
| 1133 | members.appendAssumeCapacity(tag_member); | |
| 1131 | const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); | |
| 1132 | members.appendAssumeCapacity(.{ .name = "tag", .ty = tag_ty_ref }); | |
| 1134 | 1133 | } |
| 1135 | 1134 | |
| 1136 | 1135 | const active_field = maybe_active_field orelse layout.most_aligned_field; |
| ... | ... | @@ -1149,7 +1148,8 @@ pub const DeclGen = struct { |
| 1149 | 1148 | } |
| 1150 | 1149 | |
| 1151 | 1150 | if (has_tag and !tag_first) { |
| 1152 | members.appendAssumeCapacity(tag_member); | |
| 1151 | const tag_ty_ref = try self.resolveType(union_ty.tag_ty, .indirect); | |
| 1152 | members.appendAssumeCapacity(.{ .name = "tag", .ty = tag_ty_ref }); | |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | 1155 | if (layout.padding != 0) { |
| ... | ... | @@ -1735,6 +1735,7 @@ pub const DeclGen = struct { |
| 1735 | 1735 | .slice_elem_val => try self.airSliceElemVal(inst), |
| 1736 | 1736 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), |
| 1737 | 1737 | |
| 1738 | .get_union_tag => try self.airGetUnionTag(inst), | |
| 1738 | 1739 | .struct_field_val => try self.airStructFieldVal(inst), |
| 1739 | 1740 | |
| 1740 | 1741 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), |
| ... | ... | @@ -2320,6 +2321,22 @@ pub const DeclGen = struct { |
| 2320 | 2321 | return result_id; |
| 2321 | 2322 | } |
| 2322 | 2323 | |
| 2324 | fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | |
| 2325 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | |
| 2326 | const un_ty = self.air.typeOf(ty_op.operand); | |
| 2327 | ||
| 2328 | const target = self.module.getTarget(); | |
| 2329 | const layout = un_ty.unionGetLayout(target); | |
| 2330 | if (layout.tag_size == 0) return null; | |
| 2331 | ||
| 2332 | const union_handle = try self.resolve(ty_op.operand); | |
| 2333 | if (layout.payload_size == 0) return union_handle; | |
| 2334 | ||
| 2335 | const tag_ty = un_ty.unionTagTypeSafety().?; | |
| 2336 | const tag_index = @boolToInt(layout.tag_align < layout.payload_align); | |
| 2337 | return try self.extractField(tag_ty, union_handle, tag_index); | |
| 2338 | } | |
| 2339 | ||
| 2323 | 2340 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2324 | 2341 | if (self.liveness.isUnused(inst)) return null; |
| 2325 | 2342 |
test/behavior/enum.zig-1| ... | ... | @@ -910,7 +910,6 @@ test "enum literal casting to tagged union" { |
| 910 | 910 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 911 | 911 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 912 | 912 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 913 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 914 | 913 | |
| 915 | 914 | const Arch = union(enum) { |
| 916 | 915 | x86_64, |
test/behavior/pub_enum.zig-2| ... | ... | @@ -3,8 +3,6 @@ const other = @import("pub_enum/other.zig"); |
| 3 | 3 | const expect = @import("std").testing.expect; |
| 4 | 4 | |
| 5 | 5 | test "pub enum" { |
| 6 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 7 | ||
| 8 | 6 | try pubEnumTest(other.APubEnum.Two); |
| 9 | 7 | } |
| 10 | 8 | fn pubEnumTest(foo: other.APubEnum) !void { |
test/behavior/union.zig-9| ... | ... | @@ -272,7 +272,6 @@ test "comparison between union and enum literal" { |
| 272 | 272 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 273 | 273 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 274 | 274 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 275 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 276 | 275 | |
| 277 | 276 | try testComparison(); |
| 278 | 277 | comptime try testComparison(); |
| ... | ... | @@ -288,7 +287,6 @@ test "cast union to tag type of union" { |
| 288 | 287 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 289 | 288 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 290 | 289 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 291 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 292 | 290 | |
| 293 | 291 | try testCastUnionToTag(); |
| 294 | 292 | comptime try testCastUnionToTag(); |
| ... | ... | @@ -309,7 +307,6 @@ test "cast tag type of union to union" { |
| 309 | 307 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 310 | 308 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 311 | 309 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 312 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 313 | 310 | |
| 314 | 311 | var x: Value2 = Letter2.B; |
| 315 | 312 | try expect(@as(Letter2, x) == Letter2.B); |
| ... | ... | @@ -325,7 +322,6 @@ test "implicit cast union to its tag type" { |
| 325 | 322 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 326 | 323 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 327 | 324 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 328 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 329 | 325 | |
| 330 | 326 | var x: Value2 = Letter2.B; |
| 331 | 327 | try expect(x == Letter2.B); |
| ... | ... | @@ -422,7 +418,6 @@ test "tagged union with no payloads" { |
| 422 | 418 | |
| 423 | 419 | test "union with only 1 field casted to its enum type" { |
| 424 | 420 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 425 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 426 | 421 | |
| 427 | 422 | const Literal = union(enum) { |
| 428 | 423 | Number: f64, |
| ... | ... | @@ -736,7 +731,6 @@ test "@enumToInt works on unions" { |
| 736 | 731 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 737 | 732 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 738 | 733 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 739 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 740 | 734 | |
| 741 | 735 | const Bar = union(enum) { |
| 742 | 736 | A: bool, |
| ... | ... | @@ -959,7 +953,6 @@ test "function call result coerces from tagged union to the tag" { |
| 959 | 953 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 960 | 954 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 961 | 955 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 962 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 963 | 956 | |
| 964 | 957 | const S = struct { |
| 965 | 958 | const Arch = union(enum) { |
| ... | ... | @@ -1467,8 +1460,6 @@ test "packed union in packed struct" { |
| 1467 | 1460 | } |
| 1468 | 1461 | |
| 1469 | 1462 | test "Namespace-like union" { |
| 1470 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 1471 | ||
| 1472 | 1463 | const DepType = enum { |
| 1473 | 1464 | git, |
| 1474 | 1465 | http, |