From 2f28713bd7c8eefd90d59d69a0786ee3f12400e1 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Thu, 18 May 2023 22:39:28 +0200 Subject: [PATCH] spirv: pointer bitcasting --- src/codegen/spirv.zig | 39 ++++++++++++++++++++++++++++---------- test/behavior/pointers.zig | 3 --- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 9ed1dd0b1a..d25a346640 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1752,7 +1752,7 @@ pub const DeclGen = struct { .shl => try self.airShift(inst, .OpShiftLeftLogical), - .bitcast => try self.airBitcast(inst), + .bitcast => try self.airBitCast(inst), .intcast, .trunc => try self.airIntCast(inst), .ptrtoint => try self.airPtrToInt(inst), .int_to_float => try self.airIntToFloat(inst), @@ -2269,22 +2269,41 @@ pub const DeclGen = struct { return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id); } - fn bitcast(self: *DeclGen, target_type_id: IdResultType, value_id: IdRef) !IdRef { + fn bitCast( + self: *DeclGen, + dst_ty: Type, + src_ty: Type, + src_id: IdRef, + ) !IdRef { + const dst_ty_ref = try self.resolveType(dst_ty, .direct); const result_id = self.spv.allocId(); - try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ - .id_result_type = target_type_id, - .id_result = result_id, - .operand = value_id, - }); + + // TODO: Some more cases are missing here + // See fn bitCast in llvm.zig + + if (src_ty.zigTypeTag() == .Int and dst_ty.isPtrAtRuntime()) { + try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ + .id_result_type = self.typeId(dst_ty_ref), + .id_result = result_id, + .integer_value = src_id, + }); + } else { + try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ + .id_result_type = self.typeId(dst_ty_ref), + .id_result = result_id, + .operand = src_id, + }); + } return result_id; } - fn airBitcast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand_id = try self.resolve(ty_op.operand); - const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst)); - return try self.bitcast(result_type_id, operand_id); + const operand_ty = self.air.typeOf(ty_op.operand); + const result_ty = self.air.typeOfIndex(inst); + return try self.bitCast(result_ty, operand_ty, operand_id); } fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 26d841a1fd..bbfbd1feb7 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -5,7 +5,6 @@ const expect = testing.expect; const expectError = testing.expectError; test "dereference pointer" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; comptime try testDerefPtr(); try testDerefPtr(); } @@ -53,7 +52,6 @@ fn PtrOf(comptime T: type) type { test "implicit cast single item pointer to C pointer and back" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var y: u8 = 11; var x: [*c]u8 = &y; @@ -70,7 +68,6 @@ test "initialize const optional C pointer to null" { test "assigning integer to C pointer" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var x: i32 = 0; var y: i32 = 1;