authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-09-20 23:34:26+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-23 12:36:56-07:00
logd9a8c779d8d7e251bcb549c4b1627508c012ee8c
tree97dbd460de42664793762646e8d4cd4f52675332
parenta75300c8d8cfe21647db1d50f77a9a1ee8d62a0e

spirv: constant elem ptr


3 files changed, 33 insertions(+), 29 deletions(-)

src/codegen/spirv.zig+33-18
...@@ -694,24 +694,7 @@ pub const DeclGen = struct {...@@ -694,24 +694,7 @@ pub const DeclGen = struct {
694 .none => ty,694 .none => ty,
695 else => ty.slicePtrFieldType(mod),695 else => ty.slicePtrFieldType(mod),
696 };696 };
697 const ptr_id = switch (ptr.addr) {697 const ptr_id = try self.constantPtr(ptr_ty, val);
698 .decl => |decl| try self.constructDeclRef(ptr_ty, decl),
699 .mut_decl => |mut_decl| try self.constructDeclRef(ptr_ty, mut_decl.decl), // TODO
700 .int => |int| blk: {
701 const ptr_id = self.spv.allocId();
702 // TODO: This can probably be an OpSpecConstantOp Bitcast, but
703 // that is not implemented by Mesa yet. Therefore, just generate it
704 // as a runtime operation.
705 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
706 .id_result_type = try self.resolveTypeId(ptr_ty),
707 .id_result = ptr_id,
708 .integer_value = try self.constant(Type.usize, int.toValue(), .direct),
709 });
710 break :blk ptr_id;
711 },
712 .comptime_field => unreachable,
713 else => |tag| return self.todo("pointer value of type {s}", .{@tagName(tag)}),
714 };
715 if (ptr.len == .none) {698 if (ptr.len == .none) {
716 return ptr_id;699 return ptr_id;
717 }700 }
...@@ -818,6 +801,38 @@ pub const DeclGen = struct {...@@ -818,6 +801,38 @@ pub const DeclGen = struct {
818 }801 }
819 }802 }
820803
804 fn constantPtr(self: *DeclGen, ptr_ty: Type, ptr_val: Value) !IdRef {
805 const result_ty_ref = try self.resolveType(ptr_ty, .direct);
806 const mod = self.module;
807 switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
808 .decl => |decl| return try self.constructDeclRef(ptr_ty, decl),
809 .mut_decl => |decl_mut| return try self.constructDeclRef(ptr_ty, decl_mut.decl),
810 .int => |int| {
811 const ptr_id = self.spv.allocId();
812 // TODO: This can probably be an OpSpecConstantOp Bitcast, but
813 // that is not implemented by Mesa yet. Therefore, just generate it
814 // as a runtime operation.
815 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
816 .id_result_type = self.typeId(result_ty_ref),
817 .id_result = ptr_id,
818 .integer_value = try self.constant(Type.usize, int.toValue(), .direct),
819 });
820 return ptr_id;
821 },
822 .eu_payload => unreachable, // TODO
823 .opt_payload => unreachable, // TODO
824 .comptime_field => unreachable,
825 .elem => |elem_ptr| {
826 const elem_ptr_ty = mod.intern_pool.typeOf(elem_ptr.base).toType();
827 const parent_ptr_id = try self.constantPtr(elem_ptr_ty, elem_ptr.base.toValue());
828 const size_ty_ref = try self.sizeType();
829 const index_id = try self.constInt(size_ty_ref, elem_ptr.index);
830 return self.ptrAccessChain(result_ty_ref, parent_ptr_id, index_id, &.{});
831 },
832 .field => unreachable, // TODO
833 }
834 }
835
821 // Turn a Zig type's name into a cache reference.836 // Turn a Zig type's name into a cache reference.
822 fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString {837 fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString {
823 var name = std.ArrayList(u8).init(self.gpa);838 var name = std.ArrayList(u8).init(self.gpa);
test/behavior/pointers.zig-8
...@@ -141,7 +141,6 @@ test "peer type resolution with C pointers" {...@@ -141,7 +141,6 @@ test "peer type resolution with C pointers" {
141}141}
142142
143test "peer type resolution with C pointer and const pointer" {143test "peer type resolution with C pointer and const pointer" {
144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
145 var ptr_c: [*c]u8 = undefined;144 var ptr_c: [*c]u8 = undefined;
146 const ptr_const: u8 = undefined;145 const ptr_const: u8 = undefined;
147 try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8);146 try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8);
...@@ -314,7 +313,6 @@ test "allow any sentinel" {...@@ -314,7 +313,6 @@ test "allow any sentinel" {
314test "pointer sentinel with enums" {313test "pointer sentinel with enums" {
315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO315 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
317 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
318316
319 const S = struct {317 const S = struct {
320 const Number = enum {318 const Number = enum {
...@@ -336,7 +334,6 @@ test "pointer sentinel with optional element" {...@@ -336,7 +334,6 @@ test "pointer sentinel with optional element" {
336 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;334 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO335 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO336 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
340337
341 const S = struct {338 const S = struct {
342 fn doTheTest() !void {339 fn doTheTest() !void {
...@@ -353,7 +350,6 @@ test "pointer sentinel with +inf" {...@@ -353,7 +350,6 @@ test "pointer sentinel with +inf" {
353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO350 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
354 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO351 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
355 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO352 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
356 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
357353
358 const S = struct {354 const S = struct {
359 fn doTheTest() !void {355 fn doTheTest() !void {
...@@ -374,7 +370,6 @@ test "pointer to array at fixed address" {...@@ -374,7 +370,6 @@ test "pointer to array at fixed address" {
374}370}
375371
376test "pointer arithmetic affects the alignment" {372test "pointer arithmetic affects the alignment" {
377 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
378 {373 {
379 var ptr: [*]align(8) u32 = undefined;374 var ptr: [*]align(8) u32 = undefined;
380 var x: usize = 1;375 var x: usize = 1;
...@@ -430,7 +425,6 @@ test "indexing array with sentinel returns correct type" {...@@ -430,7 +425,6 @@ test "indexing array with sentinel returns correct type" {
430test "element pointer to slice" {425test "element pointer to slice" {
431 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
432 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
434428
435 const S = struct {429 const S = struct {
436 fn doTheTest() !void {430 fn doTheTest() !void {
...@@ -453,7 +447,6 @@ test "element pointer to slice" {...@@ -453,7 +447,6 @@ test "element pointer to slice" {
453test "element pointer arithmetic to slice" {447test "element pointer arithmetic to slice" {
454 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO448 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
455 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO449 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
456 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
457450
458 const S = struct {451 const S = struct {
459 fn doTheTest() !void {452 fn doTheTest() !void {
...@@ -478,7 +471,6 @@ test "element pointer arithmetic to slice" {...@@ -478,7 +471,6 @@ test "element pointer arithmetic to slice" {
478471
479test "array slicing to slice" {472test "array slicing to slice" {
480 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
481 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
482474
483 const S = struct {475 const S = struct {
484 fn doTheTest() !void {476 fn doTheTest() !void {
test/behavior/slice.zig-3
...@@ -121,7 +121,6 @@ test "slice of type" {...@@ -121,7 +121,6 @@ test "slice of type" {
121121
122test "generic malloc free" {122test "generic malloc free" {
123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
124 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
125124
126 const a = memAlloc(u8, 10) catch unreachable;125 const a = memAlloc(u8, 10) catch unreachable;
127 memFree(u8, a);126 memFree(u8, a);
...@@ -302,7 +301,6 @@ test "slice type with custom alignment" {...@@ -302,7 +301,6 @@ test "slice type with custom alignment" {
302301
303test "obtaining a null terminated slice" {302test "obtaining a null terminated slice" {
304 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
305 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
306304
307 // here we have a normal array305 // here we have a normal array
308 var buf: [50]u8 = undefined;306 var buf: [50]u8 = undefined;
...@@ -623,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {...@@ -623,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {
623 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
625 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO623 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
626 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
627624
628 const S = struct {625 const S = struct {
629 const U = union {626 const U = union {