authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-07 18:53:33+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-15 13:59:55+02:00
log89b1dafa7808d22eab78ea486f158f794da46a2c
tree7f743c2d4604f622d6c6da6f29254dc98cd61eb2
parent28dda3bf898cc338eb0040f3f21799eda1e25be0
signaturebadge-check Signed by SSH key SHA256:CQ99aPxq+RueiL9u7z0FEki5Fm7V6T8q4PrEGmINrA4

spirv: aggregate_init for structs


3 files changed, 42 insertions(+), 14 deletions(-)

src/codegen/spirv.zig+42-3
...@@ -2725,6 +2725,7 @@ const DeclGen = struct {...@@ -2725,6 +2725,7 @@ const DeclGen = struct {
2725 if (self.liveness.isUnused(inst)) return null;2725 if (self.liveness.isUnused(inst)) return null;
27262726
2727 const mod = self.module;2727 const mod = self.module;
2728 const ip = &mod.intern_pool;
2728 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2729 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2729 const result_ty = self.typeOfIndex(inst);2730 const result_ty = self.typeOfIndex(inst);
2730 const result_ty_ref = try self.resolveType(result_ty, .direct);2731 const result_ty_ref = try self.resolveType(result_ty, .direct);
...@@ -2733,15 +2734,53 @@ const DeclGen = struct {...@@ -2733,15 +2734,53 @@ const DeclGen = struct {
27332734
2734 switch (result_ty.zigTypeTag(mod)) {2735 switch (result_ty.zigTypeTag(mod)) {
2735 .Vector => unreachable, // TODO2736 .Vector => unreachable, // TODO
2736 .Struct => unreachable, // TODO2737 .Struct => {
2738 if (mod.typeToPackedStruct(result_ty)) |struct_type| {
2739 _ = struct_type;
2740 unreachable; // TODO
2741 }
2742
2743 const constituents = try self.gpa.alloc(IdRef, elements.len);
2744 defer self.gpa.free(constituents);
2745 var index: usize = 0;
2746
2747 switch (ip.indexToKey(result_ty.toIntern())) {
2748 .anon_struct_type => |tuple| {
2749 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
2750 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
2751 assert(field_ty.toType().hasRuntimeBits(mod));
2752
2753 const id = try self.resolve(element);
2754 constituents[index] = try self.convertToIndirect(field_ty.toType(), id);
2755 index += 1;
2756 }
2757 },
2758 .struct_type => |struct_type| {
2759 var it = struct_type.iterateRuntimeOrder(ip);
2760 for (elements, 0..) |element, i| {
2761 const field_index = it.next().?;
2762 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
2763 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
2764 assert(field_ty.hasRuntimeBitsIgnoreComptime(mod));
2765
2766 const id = try self.resolve(element);
2767 constituents[index] = try self.convertToIndirect(field_ty, id);
2768 index += 1;
2769 }
2770 },
2771 else => unreachable,
2772 }
2773
2774 return try self.constructStruct(result_ty_ref, constituents[0..index]);
2775 },
2737 .Array => {2776 .Array => {
2738 const array_info = result_ty.arrayInfo(mod);2777 const array_info = result_ty.arrayInfo(mod);
2739 const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));2778 const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));
2740 const elem_ids = try self.gpa.alloc(IdRef, n_elems);2779 const elem_ids = try self.gpa.alloc(IdRef, n_elems);
2741 defer self.gpa.free(elem_ids);2780 defer self.gpa.free(elem_ids);
27422781
2743 for (elements, 0..) |elem_inst, i| {2782 for (elements, 0..) |element, i| {
2744 const id = try self.resolve(elem_inst);2783 const id = try self.resolve(element);
2745 elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);2784 elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);
2746 }2785 }
27472786
test/behavior/basic.zig-5
...@@ -357,8 +357,6 @@ fn f2(x: bool) []const u8 {...@@ -357,8 +357,6 @@ fn f2(x: bool) []const u8 {
357}357}
358358
359test "variable is allowed to be a pointer to an opaque type" {359test "variable is allowed to be a pointer to an opaque type" {
360 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
361
362 var x: i32 = 1234;360 var x: i32 = 1234;
363 _ = hereIsAnOpaqueType(@as(*OpaqueA, @ptrCast(&x)));361 _ = hereIsAnOpaqueType(@as(*OpaqueA, @ptrCast(&x)));
364}362}
...@@ -397,7 +395,6 @@ test "array 2D const double ptr" {...@@ -397,7 +395,6 @@ test "array 2D const double ptr" {
397 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;395 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
398 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO396 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
400 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
401398
402 const rect_2d_vertexes = [_][1]f32{399 const rect_2d_vertexes = [_][1]f32{
403 [_]f32{1.0},400 [_]f32{1.0},
...@@ -410,7 +407,6 @@ test "array 2D const double ptr with offset" {...@@ -410,7 +407,6 @@ test "array 2D const double ptr with offset" {
410 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
411 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO408 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
412 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
413 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
414410
415 const rect_2d_vertexes = [_][2]f32{411 const rect_2d_vertexes = [_][2]f32{
416 [_]f32{ 3.0, 4.239 },412 [_]f32{ 3.0, 4.239 },
...@@ -423,7 +419,6 @@ test "array 3D const double ptr with offset" {...@@ -423,7 +419,6 @@ test "array 3D const double ptr with offset" {
423 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;419 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
424 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
426 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
427422
428 const rect_3d_vertexes = [_][2][2]f32{423 const rect_3d_vertexes = [_][2][2]f32{
429 [_][2]f32{424 [_][2]f32{
test/behavior/struct.zig-6
...@@ -311,7 +311,6 @@ test "struct point to self" {...@@ -311,7 +311,6 @@ test "struct point to self" {
311test "void struct fields" {311test "void struct fields" {
312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
314 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
315314
316 const foo = VoidStructFieldsFoo{315 const foo = VoidStructFieldsFoo{
317 .a = void{},316 .a = void{},
...@@ -340,7 +339,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {...@@ -340,7 +339,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {
340339
341test "pass slice of empty struct to fn" {340test "pass slice of empty struct to fn" {
342 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO341 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
343 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
344342
345 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);343 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
346}344}
...@@ -1229,7 +1227,6 @@ test "typed init through error unions and optionals" {...@@ -1229,7 +1227,6 @@ test "typed init through error unions and optionals" {
1229 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1230 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1228 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1231 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1229 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1232 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12331230
1234 const S = struct {1231 const S = struct {
1235 a: u32,1232 a: u32,
...@@ -1550,7 +1547,6 @@ test "no dependency loop on optional field wrapped in generic function" {...@@ -1550,7 +1547,6 @@ test "no dependency loop on optional field wrapped in generic function" {
1550test "optional field init with tuple" {1547test "optional field init with tuple" {
1551 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1552 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1549 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1553 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15541550
1555 const S = struct {1551 const S = struct {
1556 a: ?struct { b: u32 },1552 a: ?struct { b: u32 },
...@@ -1652,7 +1648,6 @@ test "struct field pointer has correct alignment" {...@@ -1652,7 +1648,6 @@ test "struct field pointer has correct alignment" {
1652 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1648 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1653 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1649 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1654 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1650 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1655 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
16561651
1657 const S = struct {1652 const S = struct {
1658 fn doTheTest() !void {1653 fn doTheTest() !void {
...@@ -1683,7 +1678,6 @@ test "extern struct field pointer has correct alignment" {...@@ -1683,7 +1678,6 @@ test "extern struct field pointer has correct alignment" {
1683 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1678 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1679 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1680 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1686 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
16871681
1688 const S = struct {1682 const S = struct {
1689 fn doTheTest() !void {1683 fn doTheTest() !void {