diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-10-08 20:26:15 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-10-15 14:00:10 +0200 |
| commit | e2e4e1f8b4fa5d8394cb571d00b4b62eacea97df (patch) | |
| tree | f78cb2d4732bf0a59d791bd9d667e7ab6f6eb88e /src/codegen/spirv.zig | |
| parent | b1499df1b88b0fa25c4d7e4a16cb1715db452227 (diff) | |
| download | zig-e2e4e1f8b4fa5d8394cb571d00b4b62eacea97df.tar.gz zig-e2e4e1f8b4fa5d8394cb571d00b4b62eacea97df.zip | |
spirv: intcast, trunc for strange ints
Diffstat (limited to 'src/codegen/spirv.zig')
| -rw-r--r-- | src/codegen/spirv.zig | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index fab69da39b..6fff39f951 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -535,6 +535,7 @@ const DeclGen = struct { .composite_integer, }; }, + .Enum => return self.arithmeticTypeInfo(ty.intTagType(mod)), // As of yet, there is no vector support in the self-hosted compiler. .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), // TODO: For which types is this the case? @@ -2168,6 +2169,7 @@ const DeclGen = struct { /// non-zeros. /// For signed integers, the value is also sign extended. fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef { + assert(info.class != .composite_integer); // TODO if (info.bits == info.backing_bits) { return value_id; } @@ -2731,25 +2733,33 @@ const DeclGen = struct { const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand_id = try self.resolve(ty_op.operand); - const dest_ty = self.typeOfIndex(inst); - const dest_ty_id = try self.resolveTypeId(dest_ty); + const src_ty = self.typeOf(ty_op.operand); + const dst_ty = self.typeOfIndex(inst); + const src_ty_ref = try self.resolveType(src_ty, .direct); + const dst_ty_ref = try self.resolveType(dst_ty, .direct); - const mod = self.module; - const dest_info = dest_ty.intInfo(mod); + const src_info = try self.arithmeticTypeInfo(src_ty); + const dst_info = try self.arithmeticTypeInfo(dst_ty); + + // While intcast promises that the value already fits, the upper bits of a + // strange integer may contain garbage. Therefore, mask/sign extend it before. + const src_id = try self.normalizeInt(src_ty_ref, operand_id, src_info); - // TODO: Masking? + if (src_info.backing_bits == dst_info.backing_bits) { + return src_id; + } const result_id = self.spv.allocId(); - switch (dest_info.signedness) { + switch (dst_info.signedness) { .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{ - .id_result_type = dest_ty_id, + .id_result_type = self.typeId(dst_ty_ref), .id_result = result_id, - .signed_value = operand_id, + .signed_value = src_id, }), .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ - .id_result_type = dest_ty_id, + .id_result_type = self.typeId(dst_ty_ref), .id_result = result_id, - .unsigned_value = operand_id, + .unsigned_value = src_id, }), } return result_id; |
