authorgravatar for alichraghi@noreply.codeberg.orgAli Cheraghi <alichraghi@noreply.codeberg.org> 2026-06-28 18:25:43+02:00
committergravatar for alichraghi@noreply.codeberg.orgAli Cheraghi <alichraghi@noreply.codeberg.org> 2026-06-28 18:25:43+02:00
log902b71eafa9c92d01a6c0195dfdc5a59294dfe20
tree5e47d5a3ed96a6b22a6d29a6fca3bcf41403bb5a
parente0e145048d4b7b80bdbf15c78b33dea06edadc0a
parentbae68c8a458690a7fedeed7541f80b960a4bd1f6

Merge pull request 'Type: allow vectors in externs for SPIR-V target' (#35953) from alichraghi/zig:master into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35953

23 files changed, 42 insertions(+), 43 deletions(-)

lib/std/Target/spirv.zig+18-6
...@@ -1766,32 +1766,44 @@ pub const all_features = blk: {...@@ -1766,32 +1766,44 @@ pub const all_features = blk: {
1766 result[@intFromEnum(Feature.v1_1)] = .{1766 result[@intFromEnum(Feature.v1_1)] = .{
1767 .llvm_name = null,1767 .llvm_name = null,
1768 .description = "Enable v1_1 Extension.",1768 .description = "Enable v1_1 Extension.",
1769 .dependencies = featureSet(&[_]Feature{}),1769 .dependencies = featureSet(&[_]Feature{
1770 .v1_0,
1771 }),
1770 };1772 };
1771 result[@intFromEnum(Feature.v1_2)] = .{1773 result[@intFromEnum(Feature.v1_2)] = .{
1772 .llvm_name = null,1774 .llvm_name = null,
1773 .description = "Enable v1_2 Extension.",1775 .description = "Enable v1_2 Extension.",
1774 .dependencies = featureSet(&[_]Feature{}),1776 .dependencies = featureSet(&[_]Feature{
1777 .v1_1,
1778 }),
1775 };1779 };
1776 result[@intFromEnum(Feature.v1_3)] = .{1780 result[@intFromEnum(Feature.v1_3)] = .{
1777 .llvm_name = null,1781 .llvm_name = null,
1778 .description = "Enable v1_3 Extension.",1782 .description = "Enable v1_3 Extension.",
1779 .dependencies = featureSet(&[_]Feature{}),1783 .dependencies = featureSet(&[_]Feature{
1784 .v1_2,
1785 }),
1780 };1786 };
1781 result[@intFromEnum(Feature.v1_4)] = .{1787 result[@intFromEnum(Feature.v1_4)] = .{
1782 .llvm_name = null,1788 .llvm_name = null,
1783 .description = "Enable v1_4 Extension.",1789 .description = "Enable v1_4 Extension.",
1784 .dependencies = featureSet(&[_]Feature{}),1790 .dependencies = featureSet(&[_]Feature{
1791 .v1_3,
1792 }),
1785 };1793 };
1786 result[@intFromEnum(Feature.v1_5)] = .{1794 result[@intFromEnum(Feature.v1_5)] = .{
1787 .llvm_name = null,1795 .llvm_name = null,
1788 .description = "Enable v1_5 Extension.",1796 .description = "Enable v1_5 Extension.",
1789 .dependencies = featureSet(&[_]Feature{}),1797 .dependencies = featureSet(&[_]Feature{
1798 .v1_4,
1799 }),
1790 };1800 };
1791 result[@intFromEnum(Feature.v1_6)] = .{1801 result[@intFromEnum(Feature.v1_6)] = .{
1792 .llvm_name = null,1802 .llvm_name = null,
1793 .description = "Enable v1_6 Extension.",1803 .description = "Enable v1_6 Extension.",
1794 .dependencies = featureSet(&[_]Feature{}),1804 .dependencies = featureSet(&[_]Feature{
1805 .v1_5,
1806 }),
1795 };1807 };
1796 result[@intFromEnum(Feature.variable_pointers)] = .{1808 result[@intFromEnum(Feature.variable_pointers)] = .{
1797 .llvm_name = null,1809 .llvm_name = null,
src/Sema.zig+1
...@@ -27032,6 +27032,7 @@ fn elemPtrOneLayerOnly(...@@ -27032,6 +27032,7 @@ fn elemPtrOneLayerOnly(
27032 .vector => try sema.elemPtrVector(block, indexable_src, indexable, elem_index_src, elem_index, init),27032 .vector => try sema.elemPtrVector(block, indexable_src, indexable, elem_index_src, elem_index, init),
27033 .array => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety),27033 .array => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety),
27034 .@"struct" => try sema.tupleElemPtr(block, indexable_src, indexable, elem_index, elem_index_src),27034 .@"struct" => try sema.tupleElemPtr(block, indexable_src, indexable, elem_index, elem_index_src),
27035 .spirv => try sema.elemPtrSpirvRuntimeArray(block, indexable, elem_index),
27035 else => unreachable, // Guaranteed by checkIndexable27036 else => unreachable, // Guaranteed by checkIndexable
27036 };27037 };
27037 try sema.checkKnownAllocPtr(block, indexable, elem_ptr);27038 try sema.checkKnownAllocPtr(block, indexable, elem_ptr);
src/Type.zig+4-1
...@@ -3087,7 +3087,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool...@@ -3087,7 +3087,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
3087 .frame,3087 .frame,
3088 => false,3088 => false,
30893089
3090 .vector => position == .param_ty or position == .ret_ty,3090 .vector => {
3091 if (zcu.getTarget().cpu.arch.isSpirV()) return true;
3092 return position == .param_ty or position == .ret_ty;
3093 },
30913094
3092 .void => switch (position) {3095 .void => switch (position) {
3093 .ret_ty,3096 .ret_ty,
src/codegen/spirv/CodeGen.zig+2-11
...@@ -1881,17 +1881,8 @@ fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {...@@ -1881,17 +1881,8 @@ fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {
1881 const parent_ptr_ty = try oac.parent.ptrType(pt);1881 const parent_ptr_ty = try oac.parent.ptrType(pt);
1882 const result_ty_id = try cg.resolveType(oac.new_ptr_ty, .direct);1882 const result_ty_id = try cg.resolveType(oac.new_ptr_ty, .direct);
18831883
1884 if (parent_ptr_ty.childType(zcu).isVector(zcu)) {1884 if (oac.new_ptr_ty.ptrInfo(zcu).flags.vector_index != .none) {
1885 // Vector element ptr accesses are derived as offset_and_cast.1885 return parent_ptr_id;
1886 // We can just use OpAccessChain.
1887 const child_size = oac.new_ptr_ty.childType(zcu).abiSize(zcu);
1888 if (oac.byte_offset % child_size == 0) {
1889 return cg.accessChain(
1890 result_ty_id,
1891 parent_ptr_id,
1892 &.{@intCast(@divExact(oac.byte_offset, child_size))},
1893 );
1894 }
1895 }1886 }
18961887
1897 if (oac.byte_offset == 0) {1888 if (oac.byte_offset == 0) {
test/behavior/align.zig-1
...@@ -432,7 +432,6 @@ test "read 128-bit field from default aligned struct in stack memory" {...@@ -432,7 +432,6 @@ test "read 128-bit field from default aligned struct in stack memory" {
432 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO432 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
435 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
436435
437 var default_aligned = DefaultAligned{436 var default_aligned = DefaultAligned{
438 .nevermind = 1,437 .nevermind = 1,
test/behavior/array.zig-1
...@@ -1077,7 +1077,6 @@ test "initialize sentinel-terminated slice with reference to empty array initial...@@ -1077,7 +1077,6 @@ test "initialize sentinel-terminated slice with reference to empty array initial
1077}1077}
10781078
1079test "initialize sentinel-terminated many-pointer with reference to empty array initializer" {1079test "initialize sentinel-terminated many-pointer with reference to empty array initializer" {
1080 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1081 const a: [*:0]const u8 = &.{};1080 const a: [*:0]const u8 = &.{};
1082 comptime assert(a[0] == 0);1081 comptime assert(a[0] == 0);
1083}1082}
test/behavior/cast.zig-2
...@@ -433,8 +433,6 @@ test "implicit cast from *[N]T to [*c]T" {...@@ -433,8 +433,6 @@ test "implicit cast from *[N]T to [*c]T" {
433}433}
434434
435test "*usize to *void" {435test "*usize to *void" {
436 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
437
438 var i = @as(usize, 0);436 var i = @as(usize, 0);
439 const v: *void = @ptrCast(&i);437 const v: *void = @ptrCast(&i);
440 v.* = {};438 v.* = {};
test/behavior/destructure.zig-2
...@@ -94,8 +94,6 @@ test "destructure from labeled block" {...@@ -94,8 +94,6 @@ test "destructure from labeled block" {
94}94}
9595
96test "destructure tuple value" {96test "destructure tuple value" {
97 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
98
99 const tup: struct { f32, u32, i64 } = .{ 10.0, 20, 30 };97 const tup: struct { f32, u32, i64 } = .{ 10.0, 20, 30 };
100 const x, const y, const z = tup;98 const x, const y, const z = tup;
10199
test/behavior/error.zig-2
...@@ -145,8 +145,6 @@ test "implicit cast to optional to error union to return result loc" {...@@ -145,8 +145,6 @@ test "implicit cast to optional to error union to return result loc" {
145}145}
146146
147test "fn returning empty error set can be passed as fn returning any error" {147test "fn returning empty error set can be passed as fn returning any error" {
148 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
149
150 entry();148 entry();
151 comptime entry();149 comptime entry();
152}150}
test/behavior/eval.zig-2
...@@ -1445,8 +1445,6 @@ test "struct in comptime false branch is not evaluated" {...@@ -1445,8 +1445,6 @@ test "struct in comptime false branch is not evaluated" {
1445}1445}
14461446
1447test "result of nested switch assigned to variable" {1447test "result of nested switch assigned to variable" {
1448 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1449
1450 var zds: u32 = 0;1448 var zds: u32 = 0;
1451 zds = switch (zds) {1449 zds = switch (zds) {
1452 0 => switch (zds) {1450 0 => switch (zds) {
test/behavior/fn.zig-1
...@@ -292,7 +292,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void {...@@ -292,7 +292,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void {
292292
293test "call function with empty string" {293test "call function with empty string" {
294 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO294 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
295 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
296295
297 acceptsString("");296 acceptsString("");
298}297}
test/behavior/generics.zig-1
...@@ -519,7 +519,6 @@ test "call generic function with from function called by the generic function" {...@@ -519,7 +519,6 @@ test "call generic function with from function called by the generic function" {
519 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;519 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
520 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;520 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
522 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
523522
524 const GET = struct {523 const GET = struct {
525 key: []const u8,524 key: []const u8,
test/behavior/globals.zig-1
...@@ -16,7 +16,6 @@ var vpos = @Vector(2, f32){ 0.0, 0.0 };...@@ -16,7 +16,6 @@ var vpos = @Vector(2, f32){ 0.0, 0.0 };
16test "store to global vector" {16test "store to global vector" {
17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2019
21 try expect(vpos[1] == 0.0);20 try expect(vpos[1] == 0.0);
22 vpos = @Vector(2, f32){ 0.0, 1.0 };21 vpos = @Vector(2, f32){ 0.0, 1.0 };
test/behavior/inline_switch.zig+1-1
...@@ -81,7 +81,7 @@ test "inline else bool" {...@@ -81,7 +81,7 @@ test "inline else bool" {
8181
82test "inline else error" {82test "inline else error" {
83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;84
85 const Err = error{ a, b, c };85 const Err = error{ a, b, c };
86 var a = Err.a;86 var a = Err.a;
87 _ = &a;87 _ = &a;
test/behavior/math.zig-1
...@@ -1389,7 +1389,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1389,7 +1389,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void {
1389test "or > 128 bits" {1389test "or > 128 bits" {
1390 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1390 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1391 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;1391 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1392 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13931392
1394 try testOr(u140, 0, 1 << 139, 1 << 139);1393 try testOr(u140, 0, 1 << 139, 1 << 139);
1395 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);1394 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);
test/behavior/muladd.zig-1
...@@ -101,7 +101,6 @@ test "vector f16" {...@@ -101,7 +101,6 @@ test "vector f16" {
101 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO101 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
103 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;103 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
104 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
105104
106 try comptime vector16();105 try comptime vector16();
107 try vector16();106 try vector16();
test/behavior/optional.zig-1
...@@ -426,7 +426,6 @@ test "optional pointer to zero bit optional payload" {...@@ -426,7 +426,6 @@ test "optional pointer to zero bit optional payload" {
426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
428 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;428 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
429 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
430429
431 const B = struct {430 const B = struct {
432 fn foo(_: *@This()) void {}431 fn foo(_: *@This()) void {}
test/behavior/slice.zig-3
...@@ -787,8 +787,6 @@ test "slice bounds in comptime concatenation" {...@@ -787,8 +787,6 @@ test "slice bounds in comptime concatenation" {
787}787}
788788
789test "slice sentinel access at comptime" {789test "slice sentinel access at comptime" {
790 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
791
792 {790 {
793 const str0 = &[_:0]u8{ '1', '2', '3' };791 const str0 = &[_:0]u8{ '1', '2', '3' };
794 const slice0: [:0]const u8 = str0;792 const slice0: [:0]const u8 = str0;
...@@ -809,7 +807,6 @@ test "slice sentinel access at comptime" {...@@ -809,7 +807,6 @@ test "slice sentinel access at comptime" {
809test "slicing array with sentinel as end index" {807test "slicing array with sentinel as end index" {
810 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO808 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
811 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;809 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
812
813 const S = struct {810 const S = struct {
814 fn do() !void {811 fn do() !void {
815 var array = [_:0]u8{ 1, 2, 3, 4 };812 var array = [_:0]u8{ 1, 2, 3, 4 };
test/behavior/struct.zig-1
...@@ -567,7 +567,6 @@ test "bit field access" {...@@ -567,7 +567,6 @@ test "bit field access" {
567 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;567 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
569 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO569 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
570 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
571 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO570 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
572571
573 var data = bit_field_1;572 var data = bit_field_1;
test/behavior/switch.zig+2-1
...@@ -314,7 +314,6 @@ fn testSwitchEnumPtrCapture() !void {...@@ -314,7 +314,6 @@ fn testSwitchEnumPtrCapture() !void {
314314
315test "switch handles all cases of number" {315test "switch handles all cases of number" {
316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
317 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
318317
319 try testSwitchHandleAllCases();318 try testSwitchHandleAllCases();
320 try comptime testSwitchHandleAllCases();319 try comptime testSwitchHandleAllCases();
...@@ -1576,6 +1575,8 @@ test "repeated switch analysis overrides previous analysis results" {...@@ -1576,6 +1575,8 @@ test "repeated switch analysis overrides previous analysis results" {
1576}1575}
15771576
1578test "union field pointer capture preserves alignment in inline prong" {1577test "union field pointer capture preserves alignment in inline prong" {
1578 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1579
1579 const U = union(enum) {1580 const U = union(enum) {
1580 a: u32,1581 a: u32,
1581 b: u32,1582 b: u32,
test/behavior/tuple.zig-1
...@@ -242,7 +242,6 @@ test "tuple in tuple passed to generic function" {...@@ -242,7 +242,6 @@ test "tuple in tuple passed to generic function" {
242test "coerce tuple to tuple" {242test "coerce tuple to tuple" {
243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
245 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
246245
247 const T = @Tuple(&.{u8});246 const T = @Tuple(&.{u8});
248 const S = struct {247 const S = struct {
test/behavior/vector.zig-1
...@@ -414,7 +414,6 @@ test "vector @splat" {...@@ -414,7 +414,6 @@ test "vector @splat" {
414}414}
415415
416test "load vector elements via comptime index" {416test "load vector elements via comptime index" {
417 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
418 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO417 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
419 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO418 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
420419
tools/update_cpu_features.zig+14-1
...@@ -80,7 +80,20 @@ const spirv_extra_features = blk: {...@@ -80,7 +80,20 @@ const spirv_extra_features = blk: {
80 feature.* = .{80 feature.* = .{
81 .zig_name = name,81 .zig_name = name,
82 .desc = "Enable " ++ name ++ " extension",82 .desc = "Enable " ++ name ++ " extension",
83 .deps = &.{},83 .deps = if (std.mem.eql(u8, name, "v1_6"))
84 &.{"v1_5"}
85 else if (std.mem.eql(u8, name, "v1_5"))
86 &.{"v1_4"}
87 else if (std.mem.eql(u8, name, "v1_4"))
88 &.{"v1_3"}
89 else if (std.mem.eql(u8, name, "v1_3"))
90 &.{"v1_2"}
91 else if (std.mem.eql(u8, name, "v1_2"))
92 &.{"v1_1"}
93 else if (std.mem.eql(u8, name, "v1_1"))
94 &.{"v1_0"}
95 else
96 &.{},
84 };97 };
85 }98 }
8699