authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-01-19 01:12:56+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-02-04 19:09:27+01:00
log761594e2260eb780ab1861568e38a7066a7513df
treec5b5edf66d371f19708c65ccfb12d2ae36824ef6
parent2f815853dcae49bbfd109675cde1f4097b75c8cc
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: reduce, reduce_optimized


2 files changed, 74 insertions(+), 3 deletions(-)

src/codegen/spirv.zig+74-1
......@@ -2187,6 +2187,7 @@ const DeclGen = struct {
21872187 .sub_with_overflow => try self.airAddSubOverflow(inst, .OpISub, .OpUGreaterThan, .OpSGreaterThan),
21882188 .shl_with_overflow => try self.airShlOverflow(inst),
21892189
2190 .reduce, .reduce_optimized => try self.airReduce(inst),
21902191 .shuffle => try self.airShuffle(inst),
21912192
21922193 .ptr_add => try self.airPtrAdd(inst),
......@@ -2388,9 +2389,14 @@ const DeclGen = struct {
23882389 const lhs_id = try self.resolve(bin_op.lhs);
23892390 const rhs_id = try self.resolve(bin_op.rhs);
23902391 const result_ty = self.typeOfIndex(inst);
2391 const result_ty_ref = try self.resolveType(result_ty, .direct);
23922392
2393 return try self.minMax(result_ty, op, lhs_id, rhs_id);
2394 }
2395
2396 fn minMax(self: *DeclGen, result_ty: Type, op: std.math.CompareOperator, lhs_id: IdRef, rhs_id: IdRef) !IdRef {
2397 const result_ty_ref = try self.resolveType(result_ty, .direct);
23932398 const info = try self.arithmeticTypeInfo(result_ty);
2399
23942400 // TODO: Use fmin for OpenCL
23952401 const cmp_id = try self.cmp(op, Type.bool, result_ty, lhs_id, rhs_id);
23962402 const selection_id = switch (info.class) {
......@@ -2758,6 +2764,73 @@ const DeclGen = struct {
27582764 );
27592765 }
27602766
2767 fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2768 if (self.liveness.isUnused(inst)) return null;
2769 const mod = self.module;
2770 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
2771 const operand = try self.resolve(reduce.operand);
2772 const operand_ty = self.typeOf(reduce.operand);
2773 const scalar_ty = operand_ty.scalarType(mod);
2774 const scalar_ty_ref = try self.resolveType(scalar_ty, .direct);
2775 const scalar_ty_id = self.typeId(scalar_ty_ref);
2776
2777 const info = try self.arithmeticTypeInfo(operand_ty);
2778
2779 var result_id = try self.extractField(scalar_ty, operand, 0);
2780 const len = operand_ty.vectorLen(mod);
2781
2782 switch (reduce.operation) {
2783 .Min, .Max => |op| {
2784 const cmp_op: std.math.CompareOperator = if (op == .Max) .gt else .lt;
2785 for (1..len) |i| {
2786 const lhs = result_id;
2787 const rhs = try self.extractField(scalar_ty, operand, @intCast(i));
2788 result_id = try self.minMax(scalar_ty, cmp_op, lhs, rhs);
2789 }
2790
2791 return result_id;
2792 },
2793 else => {},
2794 }
2795
2796 const opcode: Opcode = switch (info.class) {
2797 .bool => switch (reduce.operation) {
2798 .And => .OpLogicalAnd,
2799 .Or => .OpLogicalOr,
2800 .Xor => .OpLogicalNotEqual,
2801 else => unreachable,
2802 },
2803 .strange_integer, .integer => switch (reduce.operation) {
2804 .And => .OpBitwiseAnd,
2805 .Or => .OpBitwiseOr,
2806 .Xor => .OpBitwiseXor,
2807 .Add => .OpIAdd,
2808 .Mul => .OpIMul,
2809 else => unreachable,
2810 },
2811 .float => switch (reduce.operation) {
2812 .Add => .OpFAdd,
2813 .Mul => .OpFMul,
2814 else => unreachable,
2815 },
2816 .composite_integer => unreachable, // TODO
2817 };
2818
2819 for (1..len) |i| {
2820 const lhs = result_id;
2821 const rhs = try self.extractField(scalar_ty, operand, @intCast(i));
2822 result_id = self.spv.allocId();
2823
2824 try self.func.body.emitRaw(self.spv.gpa, opcode, 4);
2825 self.func.body.writeOperand(spec.IdResultType, scalar_ty_id);
2826 self.func.body.writeOperand(spec.IdResult, result_id);
2827 self.func.body.writeOperand(spec.IdResultType, lhs);
2828 self.func.body.writeOperand(spec.IdResultType, rhs);
2829 }
2830
2831 return result_id;
2832 }
2833
27612834 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
27622835 const mod = self.module;
27632836 if (self.liveness.isUnused(inst)) return null;
test/behavior/vector.zig-2
......@@ -1231,7 +1231,6 @@ test "byte vector initialized in inline function" {
12311231 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12321232 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12331233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1234 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12351234
12361235 if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and
12371236 builtin.cpu.features.isEnabled(@intFromEnum(std.Target.x86.Feature.avx512f)))
......@@ -1301,7 +1300,6 @@ test "@intCast to u0" {
13011300 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13021301 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13031302 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1304 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13051303
13061304 var zeros = @Vector(2, u32){ 0, 0 };
13071305 _ = &zeros;