authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-01-21 20:38:56+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-02-04 19:09:32+01:00
log631d1b63a8027c49073995e28aab489534f01efa
tree0813aa7723ce71e83ac00d78a2c371d79af266b1
parent9641d2ebdb74926a56ff3b916082534052dc637f
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: fix shuffle properly


5 files changed, 13 insertions(+), 27 deletions(-)

src/codegen/spirv.zig+13-19
...@@ -2876,37 +2876,31 @@ const DeclGen = struct {...@@ -2876,37 +2876,31 @@ const DeclGen = struct {
2876 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2876 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2877 const mod = self.module;2877 const mod = self.module;
2878 if (self.liveness.isUnused(inst)) return null;2878 if (self.liveness.isUnused(inst)) return null;
2879 const ty = self.typeOfIndex(inst);
2880 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2879 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2881 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;2880 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
2882 const a = try self.resolve(extra.a);2881 const a = try self.resolve(extra.a);
2883 const b = try self.resolve(extra.b);2882 const b = try self.resolve(extra.b);
2884 const mask = Value.fromInterned(extra.mask);2883 const mask = Value.fromInterned(extra.mask);
2885 const mask_len = extra.mask_len;
2886 const a_len = self.typeOf(extra.a).vectorLen(mod);
28872884
2888 const result_id = self.spv.allocId();2885 const ty = self.typeOfIndex(inst);
2889 const result_type_id = try self.resolveTypeId(ty);
2890 // Similar to LLVM, SPIR-V uses indices larger than the length of the first vector
2891 // to index into the second vector.
2892 try self.func.body.emitRaw(self.spv.gpa, .OpVectorShuffle, 4 + mask_len);
2893 self.func.body.writeOperand(spec.IdResultType, result_type_id);
2894 self.func.body.writeOperand(spec.IdResult, result_id);
2895 self.func.body.writeOperand(spec.IdRef, a);
2896 self.func.body.writeOperand(spec.IdRef, b);
28972886
2898 var i: usize = 0;2887 var wip = try self.elementWise(ty);
2899 while (i < mask_len) : (i += 1) {2888 defer wip.deinit();
2889 for (wip.results, 0..) |*result_id, i| {
2900 const elem = try mask.elemValue(mod, i);2890 const elem = try mask.elemValue(mod, i);
2901 if (elem.isUndef(mod)) {2891 if (elem.isUndef(mod)) {
2902 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);2892 result_id.* = try self.spv.constUndef(wip.scalar_ty_ref);
2893 continue;
2894 }
2895
2896 const index = elem.toSignedInt(mod);
2897 if (index >= 0) {
2898 result_id.* = try self.extractField(wip.scalar_ty, a, @intCast(index));
2903 } else {2899 } else {
2904 const int = elem.toSignedInt(mod);2900 result_id.* = try self.extractField(wip.scalar_ty, b, @intCast(~index));
2905 const unsigned = if (int >= 0) @as(u32, @intCast(int)) else @as(u32, @intCast(~int + a_len));
2906 self.func.body.writeOperand(spec.LiteralInteger, unsigned);
2907 }2901 }
2908 }2902 }
2909 return result_id;2903 return try wip.finalize();
2910 }2904 }
29112905
2912 fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef {2906 fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef {
test/behavior/abs.zig-1
...@@ -224,7 +224,6 @@ test "@abs unsigned int vectors" {...@@ -224,7 +224,6 @@ test "@abs unsigned int vectors" {
224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
226 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO226 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
227 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
228227
229 try comptime testAbsUnsignedIntVectors(1);228 try comptime testAbsUnsignedIntVectors(1);
230 try testAbsUnsignedIntVectors(1);229 try testAbsUnsignedIntVectors(1);
test/behavior/cast.zig-2
...@@ -605,7 +605,6 @@ test "@intCast on vector" {...@@ -605,7 +605,6 @@ test "@intCast on vector" {
605 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO605 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
608 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
609608
610 const S = struct {609 const S = struct {
611 fn doTheTest() !void {610 fn doTheTest() !void {
...@@ -2508,7 +2507,6 @@ test "@intCast vector of signed integer" {...@@ -2508,7 +2507,6 @@ test "@intCast vector of signed integer" {
2508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2509 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO2508 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2510 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2509 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2511 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
2512 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO2510 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2513 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO2511 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
25142512
test/behavior/shuffle.zig-3
...@@ -8,7 +8,6 @@ test "@shuffle int" {...@@ -8,7 +8,6 @@ test "@shuffle int" {
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1211
13 const S = struct {12 const S = struct {
14 fn doTheTest() !void {13 fn doTheTest() !void {
...@@ -54,7 +53,6 @@ test "@shuffle bool 1" {...@@ -54,7 +53,6 @@ test "@shuffle bool 1" {
54 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO53 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5856
59 const S = struct {57 const S = struct {
60 fn doTheTest() !void {58 fn doTheTest() !void {
...@@ -77,7 +75,6 @@ test "@shuffle bool 2" {...@@ -77,7 +75,6 @@ test "@shuffle bool 2" {
77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO75 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO76 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8178
82 if (builtin.zig_backend == .stage2_llvm) {79 if (builtin.zig_backend == .stage2_llvm) {
83 // https://github.com/ziglang/zig/issues/324680 // https://github.com/ziglang/zig/issues/3246
test/behavior/vector.zig-2
...@@ -910,7 +910,6 @@ test "mask parameter of @shuffle is comptime scope" {...@@ -910,7 +910,6 @@ test "mask parameter of @shuffle is comptime scope" {
910 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO910 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
911 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO911 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
912 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO912 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
913 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
914913
915 const __v4hi = @Vector(4, i16);914 const __v4hi = @Vector(4, i16);
916 var v4_a = __v4hi{ 0, 0, 0, 0 };915 var v4_a = __v4hi{ 0, 0, 0, 0 };
...@@ -1322,7 +1321,6 @@ test "array operands to shuffle are coerced to vectors" {...@@ -1322,7 +1321,6 @@ test "array operands to shuffle are coerced to vectors" {
1322 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1323 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1322 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1324 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1323 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1325 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13261324
1327 const mask = [5]i32{ -1, 0, 1, 2, 3 };1325 const mask = [5]i32{ -1, 0, 1, 2, 3 };
13281326