authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-08 20:26:15+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-15 14:00:10+02:00
loge2e4e1f8b4fa5d8394cb571d00b4b62eacea97df
treef78cb2d4732bf0a59d791bd9d667e7ab6f6eb88e
parentb1499df1b88b0fa25c4d7e4a16cb1715db452227
signature Signed by SSH key SHA256:CQ99aPxq+RueiL9u7z0FEki5Fm7V6T8q4PrEGmINrA4

spirv: intcast, trunc for strange ints


1 files changed, 20 insertions(+), 10 deletions(-)

src/codegen/spirv.zig+20-10
......@@ -535,6 +535,7 @@ const DeclGen = struct {
535535 .composite_integer,
536536 };
537537 },
538 .Enum => return self.arithmeticTypeInfo(ty.intTagType(mod)),
538539 // As of yet, there is no vector support in the self-hosted compiler.
539540 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
540541 // TODO: For which types is this the case?
......@@ -2168,6 +2169,7 @@ const DeclGen = struct {
21682169 /// non-zeros.
21692170 /// For signed integers, the value is also sign extended.
21702171 fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef {
2172 assert(info.class != .composite_integer); // TODO
21712173 if (info.bits == info.backing_bits) {
21722174 return value_id;
21732175 }
......@@ -2731,25 +2733,33 @@ const DeclGen = struct {
27312733
27322734 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27332735 const operand_id = try self.resolve(ty_op.operand);
2734 const dest_ty = self.typeOfIndex(inst);
2735 const dest_ty_id = try self.resolveTypeId(dest_ty);
2736 const src_ty = self.typeOf(ty_op.operand);
2737 const dst_ty = self.typeOfIndex(inst);
2738 const src_ty_ref = try self.resolveType(src_ty, .direct);
2739 const dst_ty_ref = try self.resolveType(dst_ty, .direct);
27362740
2737 const mod = self.module;
2738 const dest_info = dest_ty.intInfo(mod);
2741 const src_info = try self.arithmeticTypeInfo(src_ty);
2742 const dst_info = try self.arithmeticTypeInfo(dst_ty);
2743
2744 // While intcast promises that the value already fits, the upper bits of a
2745 // strange integer may contain garbage. Therefore, mask/sign extend it before.
2746 const src_id = try self.normalizeInt(src_ty_ref, operand_id, src_info);
27392747
2740 // TODO: Masking?
2748 if (src_info.backing_bits == dst_info.backing_bits) {
2749 return src_id;
2750 }
27412751
27422752 const result_id = self.spv.allocId();
2743 switch (dest_info.signedness) {
2753 switch (dst_info.signedness) {
27442754 .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{
2745 .id_result_type = dest_ty_id,
2755 .id_result_type = self.typeId(dst_ty_ref),
27462756 .id_result = result_id,
2747 .signed_value = operand_id,
2757 .signed_value = src_id,
27482758 }),
27492759 .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{
2750 .id_result_type = dest_ty_id,
2760 .id_result_type = self.typeId(dst_ty_ref),
27512761 .id_result = result_id,
2752 .unsigned_value = operand_id,
2762 .unsigned_value = src_id,
27532763 }),
27542764 }
27552765 return result_id;