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 {
27252725 if (self.liveness.isUnused(inst)) return null;
27262726
27272727 const mod = self.module;
2728 const ip = &mod.intern_pool;
27282729 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
27292730 const result_ty = self.typeOfIndex(inst);
27302731 const result_ty_ref = try self.resolveType(result_ty, .direct);
......@@ -2733,15 +2734,53 @@ const DeclGen = struct {
27332734
27342735 switch (result_ty.zigTypeTag(mod)) {
27352736 .Vector => unreachable, // TODO
2736 .Struct => unreachable, // TODO
2737 .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 },
27372776 .Array => {
27382777 const array_info = result_ty.arrayInfo(mod);
27392778 const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));
27402779 const elem_ids = try self.gpa.alloc(IdRef, n_elems);
27412780 defer self.gpa.free(elem_ids);
27422781
2743 for (elements, 0..) |elem_inst, i| {
2744 const id = try self.resolve(elem_inst);
2782 for (elements, 0..) |element, i| {
2783 const id = try self.resolve(element);
27452784 elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);
27462785 }
27472786
test/behavior/basic.zig-5
......@@ -357,8 +357,6 @@ fn f2(x: bool) []const u8 {
357357}
358358
359359test "variable is allowed to be a pointer to an opaque type" {
360 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
361
362360 var x: i32 = 1234;
363361 _ = hereIsAnOpaqueType(@as(*OpaqueA, @ptrCast(&x)));
364362}
......@@ -397,7 +395,6 @@ test "array 2D const double ptr" {
397395 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
398396 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
399397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
400 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
401398
402399 const rect_2d_vertexes = [_][1]f32{
403400 [_]f32{1.0},
......@@ -410,7 +407,6 @@ test "array 2D const double ptr with offset" {
410407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
411408 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
412409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
413 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
414410
415411 const rect_2d_vertexes = [_][2]f32{
416412 [_]f32{ 3.0, 4.239 },
......@@ -423,7 +419,6 @@ test "array 3D const double ptr with offset" {
423419 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
424420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
425421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
426 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
427422
428423 const rect_3d_vertexes = [_][2][2]f32{
429424 [_][2]f32{
test/behavior/struct.zig-6
......@@ -311,7 +311,6 @@ test "struct point to self" {
311311test "void struct fields" {
312312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
313313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
314 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
315314
316315 const foo = VoidStructFieldsFoo{
317316 .a = void{},
......@@ -340,7 +339,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {
340339
341340test "pass slice of empty struct to fn" {
342341 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
343 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
344342
345343 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
346344}
......@@ -1229,7 +1227,6 @@ test "typed init through error unions and optionals" {
12291227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12301228 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12311229 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1232 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12331230
12341231 const S = struct {
12351232 a: u32,
......@@ -1550,7 +1547,6 @@ test "no dependency loop on optional field wrapped in generic function" {
15501547test "optional field init with tuple" {
15511548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15521549 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1553 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15541550
15551551 const S = struct {
15561552 a: ?struct { b: u32 },
......@@ -1652,7 +1648,6 @@ test "struct field pointer has correct alignment" {
16521648 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16531649 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16541650 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1655 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
16561651
16571652 const S = struct {
16581653 fn doTheTest() !void {
......@@ -1683,7 +1678,6 @@ test "extern struct field pointer has correct alignment" {
16831678 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16841679 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16851680 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1686 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
16871681
16881682 const S = struct {
16891683 fn doTheTest() !void {