diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 21a3dab1bd..b372a38ddf 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1765,6 +1765,7 @@ pub const DeclGen = struct { .slice_elem_ptr => try self.airSliceElemPtr(inst), .slice_elem_val => try self.airSliceElemVal(inst), .ptr_elem_ptr => try self.airPtrElemPtr(inst), + .ptr_elem_val => try self.airPtrElemVal(inst), .struct_field_val => try self.airStructFieldVal(inst), @@ -2482,29 +2483,52 @@ pub const DeclGen = struct { return try self.load(slice_ty, elem_ptr); } + fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef { + // Construct new pointer type for the resulting pointer + const elem_ty = ptr_ty.elemType2(); // use elemType() so that we get T for *[N]T. + const elem_ty_ref = try self.resolveType(elem_ty, .direct); + const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()), 0); + if (ptr_ty.isSinglePointer()) { + // Pointer-to-array. In this case, the resulting pointer is not of the same type + // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. + return try self.accessChain(elem_ptr_ty_ref, ptr_id, &.{index_id}); + } else { + // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain + return try self.ptrAccessChain(elem_ptr_ty_ref, ptr_id, index_id, &.{}); + } + } + fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const ptr_ty = self.air.typeOf(bin_op.lhs); - const result_ty = self.air.typeOfIndex(inst); const elem_ty = ptr_ty.childType(); // TODO: Make this return a null ptr or something if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null; - const result_ty_ref = try self.resolveType(result_ty, .direct); - const base_ptr = try self.resolve(bin_op.lhs); - const rhs = try self.resolve(bin_op.rhs); + const ptr_id = try self.resolve(bin_op.lhs); + const index_id = try self.resolve(bin_op.rhs); + return try self.ptrElemPtr(ptr_ty, ptr_id, index_id); + } - if (ptr_ty.isSinglePointer()) { - // Pointer-to-array. In this case, the resulting pointer is not of the same type - // as the ptr_ty, and hence we need to use accessChain. - return try self.accessChain(result_ty_ref, base_ptr, &.{rhs}); - } else { - // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain - return try self.ptrAccessChain(result_ty_ref, base_ptr, rhs, &.{}); - } + fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const ptr_ty = self.air.typeOf(bin_op.lhs); + const ptr_id = try self.resolve(bin_op.lhs); + const index_id = try self.resolve(bin_op.rhs); + + const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id); + + // If we have a pointer-to-array, construct an element pointer to use with load() + // If we pass ptr_ty directly, it will attempt to load the entire array rather than + // just an element. + var elem_ptr_info = ptr_ty.ptrInfo(); + elem_ptr_info.data.size = .One; + const elem_ptr_ty = Type.initPayload(&elem_ptr_info.base); + + return try self.load(elem_ptr_ty, elem_ptr_id); } fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { diff --git a/test/behavior/align.zig b/test/behavior/align.zig index bc1091ace7..dd0ea31711 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -215,8 +215,6 @@ test "alignment and size of structs with 128-bit fields" { } test "@ptrCast preserves alignment of bigger source" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - var x: u32 align(16) = 1234; const ptr = @ptrCast(*u8, &x); try expect(@TypeOf(ptr) == *align(16) u8); diff --git a/test/behavior/call.zig b/test/behavior/call.zig index 76225d815d..c1bd1ae76d 100644 --- a/test/behavior/call.zig +++ b/test/behavior/call.zig @@ -385,8 +385,6 @@ test "generic function with generic function parameter" { } test "recursive inline call with comptime known argument" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - const S = struct { inline fn foo(x: i32) i32 { if (x <= 0) { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index f3a64b4b7c..594bf683e5 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -322,7 +322,6 @@ test "peer result null and comptime_int" { test "*const ?[*]const T to [*c]const [*c]const T" { 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; var array = [_]u8{ 'o', 'k' }; const opt_array_ptr: ?[*]const u8 = &array; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 89ce094010..618af87e10 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -22,7 +22,6 @@ test "error values" { } test "redefinition of error values allowed" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; shouldBeNotEqual(error.AnError, error.SecondError); } fn shouldBeNotEqual(a: anyerror, b: anyerror) void { diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index cd913dcc9a..68d43ef0b6 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -47,8 +47,6 @@ test "inline variable gets result of const if" { } test "static function evaluation" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - try expect(statically_added_number == 3); } const statically_added_number = staticAdd(1, 2); diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 97054b7083..9391aa9398 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -620,7 +620,6 @@ test "@floor" { 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; comptime try testFloor(); try testFloor(); diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 608b992eb3..4f05054522 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -12,8 +12,6 @@ fn testParamsAdd(a: i32, b: i32) i32 { } test "local variables" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - testLocVars(2); } fn testLocVars(b: i32) void { diff --git a/test/behavior/for.zig b/test/behavior/for.zig index c99ee2edeb..c41fccfc80 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -39,8 +39,6 @@ fn testBreakOuter() !void { } test "continue outer for loop" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - try testContinueOuter(); comptime try testContinueOuter(); } diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index eddca9e7b1..97257d75a3 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -19,7 +19,6 @@ fn checkSize(comptime T: type) usize { test "simple generic fn" { 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; try expect(max(i32, 3, -1) == 3); try expect(max(u8, 1, 100) == 100); diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index a813580a20..4a043c6a6e 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -421,7 +421,6 @@ test "optional of noreturn used with orelse" { } test "orelse on C pointer" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO https://github.com/ziglang/zig/issues/6597 const foo: [*c]const u8 = "hey"; diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 7406c22f46..0bd6390796 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -93,7 +93,6 @@ test "flags in packed structs" { test "consistent size of packed structs" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const TxData1 = packed struct { data: u8, _23: u23, full: bool = false }; const TxData2 = packed struct { data: u9, _22: u22, full: bool = false }; diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 5ab1b09c89..70bc6ad47e 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -19,7 +19,6 @@ fn testDerefPtr() !void { test "pointer arithmetic" { 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; var ptr: [*]const u8 = "abcd"; @@ -300,7 +299,6 @@ test "null terminated pointer" { test "allow any sentinel" { 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 { diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index 3f70f02fcb..e463e51753 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -154,7 +154,6 @@ test "@TypeOf() has no runtime side effects" { test "branching logic inside @TypeOf" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { var data: i32 = 0; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index dc27328e6d..79fde3482c 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -672,7 +672,6 @@ test "array mult of slice gives ptr to array" { test "slice bounds in comptime concatenation" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const bs = comptime blk: { const b = "........1........"; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index a4a24ef3b3..4553596c41 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -121,8 +121,6 @@ test "struct byval assign" { } test "call struct static method" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - const result = StructWithNoFields.add(3, 4); try expect(result == 7); } diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index dd096f89ed..3f6cd37298 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -348,8 +348,6 @@ fn returnsFalse() bool { } } test "switch on const enum with var" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - try expect(!returnsFalse()); } diff --git a/test/behavior/threadlocal.zig b/test/behavior/threadlocal.zig index 57740f75ce..763c87605c 100644 --- a/test/behavior/threadlocal.zig +++ b/test/behavior/threadlocal.zig @@ -46,7 +46,6 @@ test "reference a global threadlocal variable" { else => return error.SkipZigTest, }; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; _ = nrfx_uart_rx(&g_uart0); } diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 18b65b755e..2fdb112a72 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -512,7 +512,6 @@ test "type info for async frames" { test "Declarations are returned in declaration order" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { const a = 1; diff --git a/test/behavior/var_args.zig b/test/behavior/var_args.zig index 94e2a81a9a..a2a0e7b4c6 100644 --- a/test/behavior/var_args.zig +++ b/test/behavior/var_args.zig @@ -30,7 +30,6 @@ test "send void arg to var args" { test "pass args directly" { 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; try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234); diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 8d3e3a12da..a051a8fd3b 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -38,8 +38,6 @@ fn staticWhileLoop2() i32 { } test "while with continue expression" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - var sum: i32 = 0; { var i: i32 = 0;