authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-05 23:17:51+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-05 23:17:51+02:00
logc0f9b51d846e71f46f37ffa010152c7776d77991
tree84d9ecf50159a66bbdc56713f9e1140936f00f73
parent002f324dfcd4f70d98cbfb7df57cee27bdf3db9f
parent827c3d528c02b0f2b708718254b10621c08c8b19

Merge pull request 'spirv: bug fixes' (#36051) from alichraghi/zig:master into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36051 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

25 files changed, 154 insertions(+), 91 deletions(-)

src/Sema.zig+9-1
......@@ -25377,12 +25377,16 @@ pub fn explainWhyTypeIsNotExtern(
2537725377 .noreturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
2537825378
2537925379 .@"opaque",
25380 .spirv,
2538125380 .bool,
2538225381 .float,
2538325382 .@"anyframe",
2538425383 => unreachable, // these *are* allowed
2538525384
25385 .spirv => {
25386 assert(ty.isSpirvRuntimeArray(zcu));
25387 try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{});
25388 },
25389
2538625390 .pointer => if (ty.isSlice(zcu)) {
2538725391 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
2538825392 } else {
......@@ -30541,6 +30545,10 @@ fn analyzeLoad(
3054130545
3054230546 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
3054330547
30548 if (elem_ty.isSpirvRuntimeArray(zcu)) {
30549 return sema.fail(block, src, "cannot load SPIR-V runtime array value", .{});
30550 }
30551
3054430552 const comptime_only = switch (elem_ty.classify(zcu)) {
3054530553 .no_possible_value => switch (elem_ty.zigTypeTag(zcu)) {
3054630554 .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)}),
src/Type.zig+5-1
......@@ -3119,12 +3119,16 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
31193119 .noreturn => position == .ret_ty,
31203120
31213121 .@"opaque",
3122 .spirv,
31233122 .bool,
31243123 .float,
31253124 .@"anyframe",
31263125 => true,
31273126
3127 .spirv => switch (position) {
3128 .struct_field, .union_field => true,
3129 .ret_ty, .param_ty, .element, .other => !ty.isSpirvRuntimeArray(zcu),
3130 },
3131
31283132 .pointer => {
31293133 if (ty.isSlice(zcu)) return false;
31303134 const child_ty = ty.childType(zcu);
src/codegen/spirv/CodeGen.zig+88-4
......@@ -625,6 +625,49 @@ pub fn layoutType(cg: *CodeGen, ty: Type, is_block_root: bool) Error!Id {
625625 });
626626 break :id id;
627627 },
628 .@"union" => id: {
629 const union_obj = zcu.typeToUnion(ty).?;
630 if (union_obj.layout == .@"packed") return cg.resolveType(ty, .indirect);
631
632 const layout = cg.unionLayout(ty);
633 if (!layout.has_payload) return cg.resolveType(ty, .indirect);
634
635 const id = cg.allocId();
636 if (is_block_root) try cg.decorate(id, .block);
637
638 var member_types: [4]Id = undefined;
639 const u8_id = try cg.resolveType(.u8, .direct);
640 if (layout.tag_size != 0) {
641 const tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
642 try cg.decorateMember(id, layout.tag_index, .{ .offset = .{
643 .byte_offset = @intCast(ty.unionGetLayout(zcu).tagOffset()),
644 } });
645 member_types[layout.tag_index] = try cg.layoutType(tag_ty, false);
646 }
647 if (layout.payload_size != 0) {
648 try cg.decorateMember(id, layout.payload_index, .{ .offset = .{
649 .byte_offset = @intCast(ty.unionGetLayout(zcu).payloadOffset()),
650 } });
651 member_types[layout.payload_index] = try cg.layoutType(layout.payload_ty, false);
652 }
653 if (layout.payload_padding_size != 0) {
654 const len_id = try cg.constInt(.u32, layout.payload_padding_size);
655 const arr_id = try cg.arrayType(len_id, u8_id);
656 try cg.decorate(arr_id, .{ .array_stride = .{ .array_stride = 1 } });
657 member_types[layout.payload_padding_index] = arr_id;
658 }
659 if (layout.padding_size != 0) {
660 const len_id = try cg.constInt(.u32, layout.padding_size);
661 const arr_id = try cg.arrayType(len_id, u8_id);
662 try cg.decorate(arr_id, .{ .array_stride = .{ .array_stride = 1 } });
663 member_types[layout.padding_index] = arr_id;
664 }
665 try cg.sections.globals.emit(gpa, .OpTypeStruct, .{
666 .id_result = id,
667 .id_ref = member_types[0..layout.total_fields],
668 });
669 break :id id;
670 },
628671 .array => id: {
629672 const elem_ty = ty.childType(zcu);
630673 const elem_ty_id = try cg.layoutType(elem_ty, false);
......@@ -1883,8 +1926,13 @@ fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {
18831926
18841927 const nav_ty_id = try cg.resolveType(nav_ty, .indirect);
18851928 const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, storage_class);
1886 if (nav_ty.zigTypeTag(zcu) == .@"struct" and cg.needsLayout(nav.resolved.?.@"addrspace", nav_ty)) {
1887 try cg.block_var_ids.put(gpa, spv_decl.result_id, {});
1929 switch (nav_ty.zigTypeTag(zcu)) {
1930 .@"struct", .@"union" => {
1931 if (cg.needsLayout(nav.resolved.?.@"addrspace", nav_ty)) {
1932 try cg.block_var_ids.put(gpa, spv_decl.result_id, {});
1933 }
1934 },
1935 else => {},
18881936 }
18891937 if (decl_ptr_ty_id == ty_id) return spv_decl.result_id;
18901938 switch (target.os.tag) {
......@@ -4175,7 +4223,7 @@ fn needsLayout(cg: *CodeGen, as: std.lang.AddressSpace, pointee_ty: Type) bool {
41754223 else => return false,
41764224 }
41774225 return switch (pointee_ty.zigTypeTag(cg.zcu)) {
4178 .@"struct", .array => true,
4226 .@"struct", .@"union", .array => true,
41794227 .spirv => pointee_ty.isSpirvRuntimeArray(cg.zcu),
41804228 else => false,
41814229 };
......@@ -4222,6 +4270,8 @@ fn load(cg: *CodeGen, value_ty: Type, ptr_id: Id, options: MemoryOptions) !Id {
42224270}
42234271
42244272fn store(cg: *CodeGen, value_ty: Type, ptr_id: Id, value_id: Id, options: MemoryOptions) !void {
4273 const zcu = cg.zcu;
4274 const alignment: u32 = @intCast(value_ty.abiAlignment(zcu).toByteUnits().?);
42254275 const bare_value_id = try cg.convertToIndirect(value_ty, value_id);
42264276 const bare_ty_id = try cg.resolveType(value_ty, .indirect);
42274277 const store_ty_id = if (cg.needsLayout(options.ptr_address_space, value_ty))
......@@ -4232,7 +4282,10 @@ fn store(cg: *CodeGen, value_ty: Type, ptr_id: Id, value_id: Id, options: Memory
42324282 try cg.body.emit(cg.gpa, .OpStore, .{
42334283 .pointer = ptr_id,
42344284 .object = object_id,
4235 .memory_access = .{ .@"volatile" = options.is_volatile },
4285 .memory_access = .{
4286 .@"volatile" = options.is_volatile,
4287 .aligned = .{ .literal_integer = alignment },
4288 },
42364289 });
42374290}
42384291
......@@ -6896,6 +6949,20 @@ fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
68966949 const pl_ptr_ty_id = try cg.ptrType(layout_payload_ty_id, .function);
68976950 const pl_ptr_id = try cg.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});
68986951
6952 if (field_ty.toIntern() == layout.payload_ty.toIntern()) {
6953 return try cg.load(field_ty, pl_ptr_id, .{});
6954 }
6955
6956 switch (zcu.getTarget().os.tag) {
6957 .vulkan, .opengl => {
6958 // Logical addressing forbids OpBitcast on pointers. Load the
6959 // payload as its type and bitcast the value instead.
6960 const payload_id = try cg.load(layout.payload_ty, pl_ptr_id, .{});
6961 return try cg.bitCast(field_ty, layout.payload_ty, payload_id);
6962 },
6963 else => {},
6964 }
6965
68996966 const field_ty_id = try cg.resolveType(field_ty, .indirect);
69006967 const active_pl_ptr_ty_id = try cg.ptrType(field_ty_id, .function);
69016968 const active_pl_ptr_id = cg.allocId();
......@@ -7008,6 +7075,23 @@ fn structFieldPtr(
70087075 }
70097076
70107077 const storage_class = cg.storageClass(object_ptr_ty.ptrAddressSpace(zcu));
7078 const field_ty = result_ptr_ty.childType(zcu);
7079 if (field_ty.toIntern() == layout.payload_ty.toIntern()) {
7080 if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr;
7081 return try cg.accessChain(result_ty_id, object_ptr, &.{layout.payload_index});
7082 }
7083
7084 switch (zcu.getTarget().os.tag) {
7085 .vulkan, .opengl => {
7086 // Logical addressing forbids OpBitcast on pointers. If the field
7087 // type is structurally identical to the payload type (dedup will
7088 // unify them) the access chain typed as the field type is valid.
7089 if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr;
7090 return try cg.accessChain(result_ty_id, object_ptr, &.{layout.payload_index});
7091 },
7092 else => {},
7093 }
7094
70117095 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
70127096 const pl_ptr_ty_id = try cg.ptrType(layout_payload_ty_id, storage_class);
70137097 const pl_ptr_id = blk: {
test/behavior/align.zig-4
......@@ -89,8 +89,6 @@ test "implicitly-aligned pointer is coercible to equivalent explicitly-aligned p
8989}
9090
9191test "implicitly decreasing pointer alignment" {
92 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
93
9492 const a: u32 align(4) = 3;
9593 const b: u32 align(8) = 4;
9694 try expect(addUnaligned(&a, &b) == 7);
......@@ -450,7 +448,6 @@ test "read 128-bit field from default aligned struct in global memory" {
450448 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
451449 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
452450 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
453 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
454451
455452 try expect(12 == default_aligned_global.badguy);
456453}
......@@ -505,7 +502,6 @@ test "comptime alloc alignment" {
505502 if (true) return error.SkipZigTest;
506503 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
507504 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // flaky
509505
510506 comptime var bytes1 = [_]u8{0};
511507 _ = &bytes1;
test/behavior/array.zig-1
......@@ -7,7 +7,6 @@ const expect = testing.expect;
77const expectEqual = testing.expectEqual;
88
99test "array to slice" {
10 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1110 const a: u32 align(4) = 3;
1211 const b: u32 align(8) = 4;
1312 const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..];
test/behavior/bitcast.zig-1
......@@ -138,7 +138,6 @@ test "bitcast packed struct to integer and back" {
138138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
139139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
140140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
141 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
142141
143142 const LevelUpMove = packed struct {
144143 move_id: u9,
test/behavior/cast.zig-9
......@@ -1811,7 +1811,6 @@ test "cast compatible optional types" {
18111811}
18121812
18131813test "coerce undefined single-item pointer of array to error union of slice" {
1814 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18151814 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18161815
18171816 const a = @as([*]u8, undefined)[0..0];
......@@ -1901,8 +1900,6 @@ test "cast typed undefined to int" {
19011900// }
19021901
19031902test "bitcast packed struct with u0" {
1904 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1905
19061903 const S = packed struct(u2) { a: u0, b: u2 };
19071904 const s = @as(S, @bitCast(@as(u2, 2)));
19081905 try expect(s.a == 0);
......@@ -1976,7 +1973,6 @@ test "peer type resolution forms error union" {
19761973}
19771974
19781975test "@constCast without a result location" {
1979 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19801976 const x: i32 = 1234;
19811977 const y = @constCast(&x);
19821978 try expect(@TypeOf(y) == *i32);
......@@ -1984,7 +1980,6 @@ test "@constCast without a result location" {
19841980}
19851981
19861982test "@constCast optional" {
1987 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19881983 const x: u8 = 10;
19891984 const m: ?*const u8 = &x;
19901985 const p = @constCast(m);
......@@ -2552,7 +2547,6 @@ test "peer type resolution: many compatible pointers" {
25522547test "peer type resolution: tuples with comptime fields" {
25532548 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25542549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2555 // if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
25562550
25572551 const a = .{ 1, 2 };
25582552 const b = .{ @as(u32, 3), @as(i16, 4) };
......@@ -3029,7 +3023,6 @@ test "@intCast vector of signed integer" {
30293023 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
30303024 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30313025 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3032 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
30333026 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
30343027
30353028 var x: @Vector(4, i32) = .{ 1, 2, 3, 4 };
......@@ -3077,7 +3070,6 @@ test "peer type resolution: slice of sentinel-terminated array" {
30773070}
30783071
30793072test "@intFromFloat boundary cases" {
3080 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
30813073 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
30823074
30833075 const S = struct {
......@@ -3109,7 +3101,6 @@ test "@intFromFloat boundary cases" {
31093101}
31103102
31113103test "@intFromFloat vector boundary cases" {
3112 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
31133104 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
31143105 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
31153106
test/behavior/enum.zig-2
......@@ -1221,7 +1221,6 @@ test "bit field access with enum fields" {
12211221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12221222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
12231223 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1224 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
12251224 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
12261225
12271226 var data = bit_field_1;
......@@ -1406,7 +1405,6 @@ test "matching captures causes enum equivalence" {
14061405
14071406test "large enum field values" {
14081407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1409 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
14101408
14111409 {
14121410 const E = enum(u64) { min = std.math.minInt(u64), max = std.math.maxInt(u64) };
test/behavior/error.zig-4
......@@ -785,7 +785,6 @@ const NoReturn = struct {
785785test "error union of noreturn used with if" {
786786 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
787787 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
788 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
789788 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
790789
791790 NoReturn.a = 64;
......@@ -799,7 +798,6 @@ test "error union of noreturn used with if" {
799798test "error union of noreturn used with try" {
800799 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
801800 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
802 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
803801 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
804802
805803 NoReturn.a = 64;
......@@ -810,7 +808,6 @@ test "error union of noreturn used with try" {
810808test "error union of noreturn used with catch" {
811809 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
812810 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
813 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
814811 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
815812
816813 NoReturn.a = 64;
......@@ -1070,7 +1067,6 @@ test "result location initialization of error union with OPV payload" {
10701067
10711068test "return error union with i65" {
10721069 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1073 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
10741070
10751071 try expect(try add(1000, 234) == 1234);
10761072}
test/behavior/generics.zig-1
......@@ -559,7 +559,6 @@ fn StructCapture(comptime T: type) type {
559559
560560test "call generic function that uses capture from function declaration's scope" {
561561 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
562 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
563562
564563 const S = StructCapture(f64);
565564 const s = S.foo(123);
test/behavior/inline_switch.zig-6
......@@ -46,7 +46,6 @@ const U = union(E) { a: void, b: u2, c: u3, d: u4 };
4646test "inline switch unions" {
4747 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4848 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
5049 var x: U = .a;
5150 _ = &x;
5251 switch (x) {
......@@ -93,7 +92,6 @@ test "inline else error" {
9392
9493test "inline else enum" {
9594 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
96 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
9795
9896 const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };
9997 var a: E2 = .a;
......@@ -106,7 +104,6 @@ test "inline else enum" {
106104
107105test "inline else int with gaps" {
108106 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
110107
111108 var a: u8 = 0;
112109 _ = &a;
......@@ -124,7 +121,6 @@ test "inline else int with gaps" {
124121
125122test "inline else int all values" {
126123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
128124
129125 var a: u2 = 0;
130126 _ = &a;
......@@ -140,8 +136,6 @@ test "inline else int all values" {
140136}
141137
142138test "inline switch capture is set when switch operand is comptime known" {
143 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
144
145139 const U2 = union(enum) {
146140 a: u32,
147141 };
test/behavior/math.zig-3
......@@ -1744,7 +1744,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void {
17441744test "@abs > 128 bits" {
17451745 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
17461746 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1747 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17481747
17491748 try testAbs(u140, 0, 0);
17501749 try testAbs(u140, 1 << 139, 1 << 139);
......@@ -1877,8 +1876,6 @@ test "@divTrunc > 128 bits" {
18771876}
18781877
18791878test "overflow arithmetic with u0 values" {
1880 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1881
18821879 {
18831880 var a: u0 = 0;
18841881 _ = &a;
test/behavior/muladd.zig-2
......@@ -124,7 +124,6 @@ test "vector f32" {
124124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
125125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126126 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
127 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
128127
129128 try comptime vector32();
130129 try vector32();
......@@ -148,7 +147,6 @@ test "vector f64" {
148147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
149148 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
150149 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
151 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
152150
153151 try comptime vector64();
154152 try vector64();
test/behavior/optional.zig-1
......@@ -520,7 +520,6 @@ test "alignment of wrapping an optional payload" {
520520 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
521521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
522522 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
523 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
524523 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
525524
526525 const S = struct {
test/behavior/overlapping_assign.zig+3
......@@ -1,7 +1,10 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const expect = std.testing.expect;
34
45test "assignment to overlapping memory" {
6 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
7
58 try theTest();
69 try comptime theTest();
710}
test/behavior/slice.zig-3
......@@ -852,8 +852,6 @@ test "slice len modification at comptime" {
852852}
853853
854854test "slice field ptr const" {
855 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
856
857855 const const_slice: []const u8 = "string";
858856
859857 const const_ptr_const_slice = &const_slice;
......@@ -867,7 +865,6 @@ test "slice field ptr const" {
867865
868866test "slice field ptr var" {
869867 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
870 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
871868
872869 var var_slice: []const u8 = "string";
873870
test/behavior/splat.zig-1
......@@ -5,7 +5,6 @@ const expect = std.testing.expect;
55const assert = std.debug.assert;
66
77test "@splat array" {
8 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
98 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1110
test/behavior/struct.zig-6
......@@ -689,7 +689,6 @@ test "pointer to packed struct member in a stack variable" {
689689 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
690690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
691691 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
692 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
693692 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
694693
695694 const S = packed struct {
......@@ -819,7 +818,6 @@ test "packed struct field passed to generic function" {
819818 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
820819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
821820 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
822 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
823821
824822 const S = struct {
825823 const P = packed struct {
......@@ -1204,7 +1202,6 @@ test "packed struct field access via pointer" {
12041202 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12051203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12061204 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1207 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
12081205
12091206 const S = struct {
12101207 fn doTheTest() !void {
......@@ -1502,8 +1499,6 @@ test "struct fields get automatically reordered" {
15021499}
15031500
15041501test "directly initiating tuple like struct" {
1505 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1506
15071502 const a = struct { u8 }{8};
15081503 try expect(a[0] == 8);
15091504}
......@@ -2306,7 +2301,6 @@ test "struct queries typeinfo of struct containing pointer back to first struct"
23062301}
23072302
23082303test "pointer to runtime field of struct containing struct containing comptime-only optional" {
2309 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
23102304 const Foo = struct {
23112305 padding: struct { a: u8, b: ?comptime_int },
23122306 number: u8,
test/behavior/switch.zig-17
......@@ -354,7 +354,6 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {
354354test "switch on union with some prongs capturing" {
355355 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
356356 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
357 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
358357
359358 const X = union(enum) {
360359 a,
......@@ -391,7 +390,6 @@ test "switch on const enum with var" {
391390
392391test "anon enum literal used in switch on union enum" {
393392 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
394 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
395393
396394 const Foo = union(enum) {
397395 a: i32,
......@@ -534,7 +532,6 @@ test "switch prongs with error set cases make a new error set type for capture v
534532
535533test "return result loc and then switch with range implicit casted to error union" {
536534 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
538535
539536 const S = struct {
540537 fn doTheTest() !void {
......@@ -615,8 +612,6 @@ test "switch prongs with cases with identical payload types" {
615612}
616613
617614test "switch prong pointer capture alignment" {
618 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
619
620615 const U = union(enum) {
621616 a: u8 align(8),
622617 b: u8 align(4),
......@@ -755,7 +750,6 @@ test "switch capture copies its payload" {
755750
756751test "capture of integer forwards the switch condition directly" {
757752 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
758 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
759753
760754 const S = struct {
761755 fn foo(x: u8) !void {
......@@ -971,8 +965,6 @@ test "switch prong captures range" {
971965}
972966
973967test "prong with inline call to unreachable" {
974 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
975
976968 const U = union(enum) {
977969 void: void,
978970 bool: bool,
......@@ -1018,8 +1010,6 @@ test "block error return trace index is reset between prongs" {
10181010}
10191011
10201012test "labeled switch with break" {
1021 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1022
10231013 var six: u32 = undefined;
10241014 six = 6;
10251015
......@@ -1047,7 +1037,6 @@ test "unlabeled break ignores switch" {
10471037 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10481038 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10491039 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1050 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
10511040
10521041 const result = while (true) {
10531042 _ = s: switch (@as(u32, 1)) {
......@@ -1079,8 +1068,6 @@ test "switch on 8-bit mod result" {
10791068}
10801069
10811070test "switch on non-exhaustive enum" {
1082 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1083
10841071 const E = enum(u4) {
10851072 a,
10861073 b,
......@@ -1314,8 +1301,6 @@ test "single-item prong in switch on enum has comptime-known capture" {
13141301}
13151302
13161303test "single range switch prong capture" {
1317 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1318
13191304 const S = struct {
13201305 fn doTheTest(x: u8) !void {
13211306 switch (x) {
......@@ -1575,8 +1560,6 @@ test "repeated switch analysis overrides previous analysis results" {
15751560}
15761561
15771562test "union field pointer capture preserves alignment in inline prong" {
1578 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1579
15801563 const U = union(enum) {
15811564 a: u32,
15821565 b: u32,
test/behavior/switch_loop.zig-1
......@@ -179,7 +179,6 @@ test "switch loop with pointer capture" {
179179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
180180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
181181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
183182
184183 const S = struct {
185184 const U = union(enum) {
test/behavior/tuple.zig-6
......@@ -255,7 +255,6 @@ test "coerce tuple to tuple" {
255255test "tuple type with void field" {
256256 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
257257 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
258 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
259258
260259 const T = @Tuple(&.{void});
261260 const x = T{{}};
......@@ -280,7 +279,6 @@ test "zero sized struct in tuple handled correctly" {
280279
281280test "tuple type with void field and a runtime field" {
282281 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
284282
285283 const T = @Tuple(&.{ usize, void });
286284 var t: T = .{ 5, {} };
......@@ -291,7 +289,6 @@ test "tuple type with void field and a runtime field" {
291289test "branching inside tuple literal" {
292290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
293291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
294 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
295292
296293 const S = struct {
297294 fn foo(a: anytype) !void {
......@@ -371,7 +368,6 @@ test "sentinel slice in tuple" {
371368test "tuple pointer is indexable" {
372369 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
373370 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
374 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
375371
376372 const S = struct { u32, bool };
377373
......@@ -552,8 +548,6 @@ test "OPV tuple fields aren't comptime" {
552548}
553549
554550test "array of tuples that end with a zero-bit field followed by padding" {
555 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
556
557551 const S = struct {
558552 var foo: [2]struct { u32, u8, void } = .{ .{ 1, 2, {} }, .{ 3, 4, {} } };
559553 };
test/behavior/union.zig-13
......@@ -31,7 +31,6 @@ test "init union with runtime value - floats" {
3131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3333 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
34 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
3534
3635 var foo: FooWithFloats = undefined;
3736
......@@ -445,7 +444,6 @@ var glbl: Foo1 = undefined;
445444test "global union with single field is correctly initialized" {
446445 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
447446 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
448 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
449447
450448 glbl = Foo1{
451449 .f = @typeInfo(Foo1).@"union".field_types[0]{ .x = 123 },
......@@ -488,7 +486,6 @@ test "update the tag value for zero-sized unions" {
488486test "union initializer generates padding only if needed" {
489487 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
490488 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
491 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
492489
493490 const U = union(enum) {
494491 A: u24,
......@@ -659,7 +656,6 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {
659656test "switch on union with only 1 field" {
660657 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
661658 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
662 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
663659
664660 var r: PartialInst = undefined;
665661 r = PartialInst.Compiled;
......@@ -773,7 +769,6 @@ test "return union init with void payload" {
773769 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
774770 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
775771 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
776 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
777772
778773 const S = struct {
779774 fn entry() !void {
......@@ -925,7 +920,6 @@ test "function call result coerces from tagged union to the tag" {
925920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
926921 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
927922 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
928 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
929923
930924 const S = struct {
931925 const Arch = union(enum) {
......@@ -1142,7 +1136,6 @@ test "union tag is set when initiated as a temporary value at runtime" {
11421136 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11431137 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11441138 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1145 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11461139
11471140 const U = union(enum) {
11481141 a,
......@@ -1392,7 +1385,6 @@ test "no dependency loop when function pointer in union returns the union" {
13921385test "union reassignment can use previous value" {
13931386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13941387 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1395 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13961388
13971389 const U = union {
13981390 a: u32,
......@@ -1550,7 +1542,6 @@ test "packed union field pointer has correct alignment" {
15501542
15511543test "union with 128 bit integer" {
15521544 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1553 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
15541545
15551546 const ValueTag = enum { int, other };
15561547
......@@ -2040,7 +2031,6 @@ test "pass nested union with rls" {
20402031test "runtime union init, most-aligned field != largest" {
20412032 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
20422033 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2043 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
20442034 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20452035 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
20462036
......@@ -2202,7 +2192,6 @@ test "matching captures causes union equivalence" {
22022192
22032193test "signed enum tag with negative value" {
22042194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2205 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
22062195 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22072196
22082197 const Enum = enum(i8) {
......@@ -2278,8 +2267,6 @@ test "assign global tagged union" {
22782267}
22792268
22802269test "set mutable union by switching on same union" {
2281 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2282
22832270 const U = union(enum) {
22842271 foo,
22852272 bar: usize,
test/behavior/vector.zig-4
......@@ -395,7 +395,6 @@ test "load vector elements via comptime index" {
395395}
396396
397397test "store vector elements via comptime index" {
398 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
399398 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
400399 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
401400
......@@ -577,7 +576,6 @@ test "vector division operators" {
577576
578577test "vector bitwise not operator" {
579578 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
580 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
581579 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
582580 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
583581 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -610,7 +608,6 @@ test "vector bitwise not operator" {
610608
611609test "vector boolean not operator" {
612610 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
613 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
614611 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
615612 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
616613 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -1090,7 +1087,6 @@ test "multiplication-assignment operator with an array operand" {
10901087 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10911088 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10921089 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1093 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
10941090
10951091 const S = struct {
10961092 fn doTheTest() !void {
test/cases/compile_errors/loading_spirv_runtime_array_value.zig created+23
......@@ -0,0 +1,23 @@
1const RuntimeArray = @SpirvType(.{ .runtime_array = f32 });
2const Buffer = extern struct {
3 data: RuntimeArray,
4};
5const buf = @extern(*addrspace(.storage_buffer) Buffer, .{
6 .name = "buf",
7 .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } },
8});
9export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
10 const a = buf.data;
11 _ = a;
12}
13export fn main2() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
14 const p: *addrspace(.storage_buffer) const RuntimeArray = &buf.data;
15 _ = p.*;
16}
17
18// error
19// backend=selfhosted
20// target=spirv32-vulkan
21//
22// :10:15: error: cannot load SPIR-V runtime array value
23// :15:12: error: cannot load SPIR-V runtime array value
test/cases/compile_errors/spirv_runtime_array_as_value_type.zig created+26
......@@ -0,0 +1,26 @@
1const RuntimeArray = @SpirvType(.{ .runtime_array = u32 });
2
3const a = @extern(*addrspace(.storage_buffer) RuntimeArray, .{
4 .name = "a",
5 .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } },
6});
7const b = @extern(*addrspace(.uniform) const RuntimeArray, .{
8 .name = "b",
9 .decoration = .{ .descriptor = .{ .set = 0, .binding = 1 } },
10});
11
12comptime {
13 _ = a;
14 _ = b;
15}
16
17// error
18// backend=selfhosted
19// target=spirv32-vulkan
20//
21// :3:19: error: extern symbol cannot have type '*addrspace(.storage_buffer) @SpirvType(.runtime_array, u32)'
22// :3:19: note: pointer element type '@SpirvType(.runtime_array, u32)' is not extern compatible
23// :3:19: note: SPIR-V runtime arrays must be the last field of an extern struct
24// :7:19: error: extern symbol cannot have type '*addrspace(.uniform) const @SpirvType(.runtime_array, u32)'
25// :7:19: note: pointer element type '@SpirvType(.runtime_array, u32)' is not extern compatible
26// :7:19: note: SPIR-V runtime arrays must be the last field of an extern struct