spirv: air array_elem_val using hack
SPIR-V doesn't support true element indexing, so we probably need to switch over to isByRef like in llvm for this to work properly. Currently a temporary is used, which at least seems to work.
This commit is contained in:
committed by
Andrew Kelley
parent
26c279cca2
commit
5d844faf7c
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user