authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-08 19:05:48+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:55+02:00
log979b4102588fbb0d066060a5a6b6e10f584158ac
tree6748c0fa79b9251eda4dc456b89efa8dab8c770f
parenta7563e453dce0cc256a0c40af434731f2cf7dcaf
signaturelock-open Commit is signed but in an unrecognized format.

spirv: Do not generate the Alignment attribute on pointers for now

It seems that some implementations may have problems with these right now, like Intel and Rusticl. In theory, these attributes should be superficial on the pointer type, as alignment guarantees are also added via the alignment option of the OpLoad and OpStore instructions. Therefore, get rid of them for now.

4 files changed, 20 insertions(+), 36 deletions(-)

src/codegen/spirv.zig+14-27
......@@ -825,6 +825,11 @@ pub const DeclGen = struct {
825825 // - Underaligned pointers. These need to be packed into the word array by using a mixture of
826826 // OpSpecConstantOp instructions such as OpConvertPtrToU, OpBitcast, OpShift, etc.
827827
828 // TODO: Implement alignment here.
829 // This is hoing to require some hacks because there is no real way to
830 // set an OpVariable's alignment.
831 _ = alignment;
832
828833 assert(storage_class != .Generic and storage_class != .Function);
829834
830835 log.debug("lowerIndirectConstant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtDebug() });
......@@ -832,7 +837,7 @@ pub const DeclGen = struct {
832837 const section = &self.spv.globals.section;
833838
834839 const ty_ref = try self.resolveType(ty, .indirect);
835 const ptr_ty_ref = try self.spv.ptrType(ty_ref, storage_class, alignment);
840 const ptr_ty_ref = try self.spv.ptrType(ty_ref, storage_class, 0);
836841
837842 // const target = self.getTarget();
838843
......@@ -874,7 +879,7 @@ pub const DeclGen = struct {
874879 try icl.flush();
875880
876881 const constant_struct_ty_ref = try self.spv.simpleStructType(icl.members.items);
877 const ptr_constant_struct_ty_ref = try self.spv.ptrType(constant_struct_ty_ref, storage_class, alignment);
882 const ptr_constant_struct_ty_ref = try self.spv.ptrType(constant_struct_ty_ref, storage_class, 0);
878883
879884 const constant_struct_id = self.spv.allocId();
880885 try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{
......@@ -909,7 +914,7 @@ pub const DeclGen = struct {
909914 });
910915
911916 if (cast_to_generic) {
912 const generic_ptr_ty_ref = try self.spv.ptrType(ty_ref, .Generic, alignment);
917 const generic_ptr_ty_ref = try self.spv.ptrType(ty_ref, .Generic, 0);
913918 try section.emitSpecConstantOp(self.spv.gpa, .OpPtrCastToGeneric, .{
914919 .id_result_type = self.typeId(generic_ptr_ty_ref),
915920 .id_result = result_id,
......@@ -1165,21 +1170,16 @@ pub const DeclGen = struct {
11651170 .Pointer => {
11661171 const ptr_info = ty.ptrInfo().data;
11671172
1168 const ptr_payload = try self.spv.arena.create(SpvType.Payload.Pointer);
1169 ptr_payload.* = .{
1170 .storage_class = spvStorageClass(ptr_info.@"addrspace"),
1171 .child_type = try self.resolveType(ptr_info.pointee_type, .indirect),
1172 // Note: only available in Kernels!
1173 .alignment = ty.ptrAlignment(target) * 8,
1174 };
1175 const ptr_ty_id = try self.spv.resolveType(SpvType.initPayload(&ptr_payload.base));
1173 const storage_class = spvStorageClass(ptr_info.@"addrspace");
1174 const child_ty_ref = try self.resolveType(ptr_info.pointee_type, .indirect);
1175 const ptr_ty_ref = try self.spv.ptrType(child_ty_ref, storage_class, 0);
11761176
11771177 if (ptr_info.size != .Slice) {
1178 return ptr_ty_id;
1178 return ptr_ty_ref;
11791179 }
11801180
11811181 return try self.spv.simpleStructType(&.{
1182 .{ .ty = ptr_ty_id, .name = "ptr" },
1182 .{ .ty = ptr_ty_ref, .name = "ptr" },
11831183 .{ .ty = try self.sizeType(), .name = "len" },
11841184 });
11851185 },
......@@ -1356,7 +1356,7 @@ pub const DeclGen = struct {
13561356 /// the name of an error in the text executor.
13571357 fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void {
13581358 const anyerror_ty_ref = try self.resolveType(Type.anyerror, .direct);
1359 const ptr_anyerror_ty_ref = try self.spv.ptrType(anyerror_ty_ref, .CrossWorkgroup, null);
1359 const ptr_anyerror_ty_ref = try self.spv.ptrType(anyerror_ty_ref, .CrossWorkgroup, 0);
13601360 const void_ty_ref = try self.resolveType(Type.void, .direct);
13611361
13621362 const kernel_proto_ty_ref = blk: {
......@@ -1497,19 +1497,6 @@ pub const DeclGen = struct {
14971497 final_storage_class == .Generic,
14981498 decl.@"align",
14991499 );
1500
1501 // if (storage_class == .Generic) {
1502 // const section = &self.spv.globals.section;
1503 // const ty_ref = try self.resolveType(decl.ty, .indirect);
1504 // const ptr_ty_ref = try self.spv.ptrType(ty_ref, storage_class, decl.@"align");
1505 // // TODO: Can we eliminate this cast?
1506 // // TODO: Const-wash pointer?
1507 // try section.emitSpecConstantOp(self.spv.gpa, .OpPtrCastToGeneric, .{
1508 // .id_result_type = self.typeId(ptr_ty_ref),
1509 // .id_result = global_result_id,
1510 // .pointer = casted_result_id,
1511 // });
1512 // }
15131500 }
15141501 }
15151502
src/codegen/spirv/Assembler.zig+1-4
......@@ -388,10 +388,7 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
388388 payload.* = .{
389389 .storage_class = @intToEnum(spec.StorageClass, operands[1].value),
390390 .child_type = try self.resolveTypeRef(operands[2].ref_id),
391 // TODO: Fetch these values from decorations.
392 .array_stride = 0,
393 .alignment = null,
394 .max_byte_offset = null,
391 // TODO: Fetch decorations
395392 };
396393 break :blk SpvType.initPayload(&payload.base);
397394 },
src/codegen/spirv/Module.zig+3-3
......@@ -573,8 +573,8 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
573573 if (info.array_stride != 0) {
574574 try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
575575 }
576 if (info.alignment) |alignment| {
577 try self.decorate(ref_id, .{ .Alignment = .{ .alignment = alignment } });
576 if (info.alignment != 0) {
577 try self.decorate(ref_id, .{ .Alignment = .{ .alignment = info.alignment } });
578578 }
579579 if (info.max_byte_offset) |max_byte_offset| {
580580 try self.decorate(ref_id, .{ .MaxByteOffset = .{ .max_byte_offset = max_byte_offset } });
......@@ -753,7 +753,7 @@ pub fn ptrType(
753753 self: *Module,
754754 child: Type.Ref,
755755 storage_class: spec.StorageClass,
756 alignment: ?u32,
756 alignment: u32,
757757) !Type.Ref {
758758 const ptr_payload = try self.arena.create(Type.Payload.Pointer);
759759 ptr_payload.* = .{
src/codegen/spirv/type.zig+2-2
......@@ -547,8 +547,8 @@ pub const Type = extern union {
547547 /// This is valid for pointers to elements of an array.
548548 /// If zero, no stride is present.
549549 array_stride: u32 = 0,
550 /// Type has the 'Alignment' decoration.
551 alignment: ?u32,
550 /// If nonzero, type has the 'Alignment' decoration.
551 alignment: u32 = 0,
552552 /// Type has the 'MaxByteOffset' decoration.
553553 max_byte_offset: ?u32 = null,
554554 };