diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 3ee9cb181e..962310f28a 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1681,6 +1681,8 @@ pub const DeclGen = struct { .int_from_float => try self.airIntFromFloat(inst), .not => try self.airNot(inst), + .array_to_slice => try self.airArrayToSlice(inst), + .slice_ptr => try self.airSliceField(inst, 0), .slice_len => try self.airSliceField(inst, 1), .slice_elem_ptr => try self.airSliceElemPtr(inst), @@ -2427,6 +2429,30 @@ pub const DeclGen = struct { return result_id; } + fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const mod = self.module; + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const array_ptr_ty = self.typeOf(ty_op.operand); + const array_ty = array_ptr_ty.childType(mod); + const elem_ty = array_ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. + const elem_ty_ref = try self.resolveType(elem_ty, .indirect); + const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(array_ptr_ty.ptrAddressSpace(mod))); + const slice_ty = self.typeOfIndex(inst); + const slice_ty_ref = try self.resolveType(slice_ty, .direct); + const size_ty_ref = try self.sizeType(); + + const array_ptr_id = try self.resolve(ty_op.operand); + const len_id = try self.constInt(size_ty_ref, array_ty.arrayLen(mod)); + + if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { + unreachable; // TODO + } + + // Convert the pointer-to-array to a pointer to the first element. + const elem_ptr_id = try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); + return try self.constructStruct(slice_ty_ref, &.{ elem_ptr_id, len_id }); + } + fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { if (self.liveness.isUnused(inst)) return null; const ty_op = self.air.instructions.items(.data)[inst].ty_op; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 4316aca34f..c04c018017 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -29,7 +29,6 @@ comptime { test "slicing" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var array: [20]i32 = undefined; @@ -346,7 +345,6 @@ test "empty array to slice" { test "@ptrCast slice to pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -572,7 +570,6 @@ test "slice syntax resulting in pointer-to-array" { test "slice pointer-to-array null terminated" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; comptime { var array = [5:0]u8{ 1, 2, 3, 4, 5 }; @@ -714,7 +711,6 @@ test "slice sentinel access at comptime" { test "slicing array with sentinel as end index" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { fn do() !void { @@ -733,7 +729,6 @@ test "slicing array with sentinel as end index" { test "slicing slice with sentinel as end index" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { fn do() !void { @@ -762,7 +757,6 @@ test "slice len modification at comptime" { } test "slice field ptr const" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const const_slice: []const u8 = "string"; @@ -777,7 +771,6 @@ test "slice field ptr const" { test "slice field ptr var" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var var_slice: []const u8 = "string";