Commit 5d844faf7c
src/codegen/spirv.zig
@@ -1694,6 +1694,7 @@ pub const DeclGen = struct {
.slice_elem_val => try self.airSliceElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
.ptr_elem_val => try self.airPtrElemVal(inst),
+ .array_elem_val => try self.airArrayElemVal(inst),
.set_union_tag => return try self.airSetUnionTag(inst),
.get_union_tag => try self.airGetUnionTag(inst),
@@ -2567,6 +2568,40 @@ pub const DeclGen = struct {
return try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
}
+ fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+ if (self.liveness.isUnused(inst)) return null;
+
+ const mod = self.module;
+ const bin_op = self.air.instructions.items(.data)[inst].bin_op;
+ const array_ty = self.typeOf(bin_op.lhs);
+ const array_ty_ref = try self.resolveType(array_ty, .direct);
+ const elem_ty = array_ty.childType(mod);
+ const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
+ const array_id = try self.resolve(bin_op.lhs);
+ const index_id = try self.resolve(bin_op.rhs);
+
+ // SPIR-V doesn't have an array indexing function for some damn reason.
+ // For now, just generate a temporary and use that.
+ // TODO: This backend probably also should use isByRef from llvm...
+
+ const array_ptr_ty_ref = try self.spv.ptrType(array_ty_ref, .Function);
+ const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, .Function);
+
+ const tmp_id = self.spv.allocId();
+ try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
+ .id_result_type = self.typeId(array_ptr_ty_ref),
+ .id_result = tmp_id,
+ .storage_class = .Function,
+ });
+ try self.func.body.emit(self.spv.gpa, .OpStore, .{
+ .pointer = tmp_id,
+ .object = array_id,
+ });
+
+ const elem_ptr_id = try self.accessChainId(elem_ptr_ty_ref, tmp_id, &.{index_id});
+ return try self.load(elem_ty, elem_ptr_id, false);
+ }
+
fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
test/behavior/array.zig
@@ -21,7 +21,6 @@ test "arrays" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
var array: [5]u32 = undefined;
@@ -141,7 +140,6 @@ test "array literal with specified size" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
var array = [2]u8{ 1, 2 };
try expect(array[0] == 1);
@@ -201,7 +199,6 @@ test "nested arrays of strings" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
for (array_of_strings, 0..) |s, i| {
@@ -288,7 +285,6 @@ test "anonymous list literal syntax" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) 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 {
@@ -479,7 +475,6 @@ test "anonymous literal in array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
const Foo = struct {
@@ -504,7 +499,6 @@ test "anonymous literal in array" {
test "access the null element of a null terminated array" {
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 {
@@ -522,7 +516,6 @@ test "type deduction for array subscript expression" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
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 {
@@ -620,7 +613,6 @@ test "type coercion of pointer to anon struct literal to pointer to array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
const U = union {
@@ -703,7 +695,6 @@ test "array of array agregate init" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
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;
var a = [1]u32{11} ** 10;
var b = [1][10]u32{a} ** 2;
@@ -763,8 +754,6 @@ test "slicing array of zero-sized values" {
}
test "array init with no result pointer sets field result types" {
- if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
-
const S = struct {
// A function parameter has a result type, but no result pointer.
fn f(arr: [1]u32) u32 {