authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-01-15 21:58:13+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-02-04 19:08:59+01:00
log747f4ae3f5efc89df0b1b76787eb90eab90fc362
tree567e3c45295fbcc424dffd713a0bd04a252fe000
parent3ef5b80d2c359c94ec2fa14bde492a6c9774d536
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: sh[rl](_exact)?


2 files changed, 29 insertions(+), 19 deletions(-)

src/codegen/spirv.zig+29-14
......@@ -2111,7 +2111,8 @@ const DeclGen = struct {
21112111 .bool_and => try self.airBinOpSimple(inst, .OpLogicalAnd),
21122112 .bool_or => try self.airBinOpSimple(inst, .OpLogicalOr),
21132113
2114 .shl => try self.airShift(inst, .OpShiftLeftLogical),
2114 .shl, .shl_exact => try self.airShift(inst, .OpShiftLeftLogical, .OpShiftLeftLogical),
2115 .shr, .shr_exact => try self.airShift(inst, .OpShiftRightLogical, .OpShiftRightArithmetic),
21152116
21162117 .min => try self.airMinMax(inst, .lt),
21172118 .max => try self.airMinMax(inst, .gt),
......@@ -2254,28 +2255,42 @@ const DeclGen = struct {
22542255 return try self.binOpSimple(ty, lhs_id, rhs_id, opcode);
22552256 }
22562257
2257 fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef {
2258 fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime unsigned: Opcode, comptime signed: Opcode) !?IdRef {
22582259 if (self.liveness.isUnused(inst)) return null;
2260 const mod = self.module;
22592261 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
22602262 const lhs_id = try self.resolve(bin_op.lhs);
22612263 const rhs_id = try self.resolve(bin_op.rhs);
2262 const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
2263
2264 // the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int.
2265 const shift_id = self.spv.allocId();
2266 try self.func.body.emit(self.spv.gpa, .OpUConvert, .{
2267 .id_result_type = result_type_id,
2268 .id_result = shift_id,
2269 .unsigned_value = rhs_id,
2270 });
2264 const result_ty = self.typeOfIndex(inst);
2265 const result_ty_ref = try self.resolveType(result_ty, .direct);
22712266
22722267 const result_id = self.spv.allocId();
2273 try self.func.body.emit(self.spv.gpa, opcode, .{
2274 .id_result_type = result_type_id,
2268
2269 // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that,
2270 // so just manually upcast it if required.
2271 const shift_ty_ref = try self.resolveType(self.typeOf(bin_op.rhs), .direct);
2272 const shift_id = if (shift_ty_ref != result_ty_ref) blk: {
2273 const shift_id = self.spv.allocId();
2274 try self.func.body.emit(self.spv.gpa, .OpUConvert, .{
2275 .id_result_type = self.typeId(result_ty_ref),
2276 .id_result = shift_id,
2277 .unsigned_value = rhs_id,
2278 });
2279 break :blk shift_id;
2280 } else rhs_id;
2281
2282 const args = .{
2283 .id_result_type = self.typeId(result_ty_ref),
22752284 .id_result = result_id,
22762285 .base = lhs_id,
22772286 .shift = shift_id,
2278 });
2287 };
2288
2289 if (result_ty.isSignedInt(mod)) {
2290 try self.func.body.emit(self.spv.gpa, signed, args);
2291 } else {
2292 try self.func.body.emit(self.spv.gpa, unsigned, args);
2293 }
22792294 return result_id;
22802295 }
22812296
test/behavior/math.zig-5
......@@ -12,7 +12,6 @@ const math = std.math;
1212test "assignment operators" {
1313 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1414 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1615
1716 var i: u32 = 0;
1817 i += 5;
......@@ -649,8 +648,6 @@ test "bit shift a u1" {
649648}
650649
651650test "truncating shift right" {
652 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
653
654651 try testShrTrunc(maxInt(u16));
655652 try comptime testShrTrunc(maxInt(u16));
656653}
......@@ -1343,8 +1340,6 @@ fn testShlExact(x: u8) !void {
13431340}
13441341
13451342test "exact shift right" {
1346 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1347
13481343 try testShrExact(0b10110100);
13491344 try comptime testShrExact(0b10110100);
13501345}