| ... | @@ -780,21 +780,14 @@ const DeclGen = struct { | ... | @@ -780,21 +780,14 @@ const DeclGen = struct { |
| 780 | /// Result is in `direct` representation. | 780 | /// Result is in `direct` representation. |
| 781 | fn constructStruct(self: *DeclGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef { | 781 | fn constructStruct(self: *DeclGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef { |
| 782 | assert(types.len == constituents.len); | 782 | assert(types.len == constituents.len); |
| 783 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' | 783 | |
| 784 | // operands are not constant. | 784 | const result_id = self.spv.allocId(); |
| 785 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 | 785 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| 786 | // For now, just initialize the struct by setting the fields manually... | 786 | .id_result_type = try self.resolveType(ty, .direct), |
| 787 | // TODO: Make this OpCompositeConstruct when we can | 787 | .id_result = result_id, |
| 788 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); | 788 | .constituents = constituents, |
| 789 | for (constituents, types, 0..) |constitent_id, member_ty, index| { | 789 | }); |
| 790 | const ptr_member_ty_id = try self.ptrType(member_ty, .Function); | 790 | return result_id; |
| 791 | const ptr_id = try self.accessChain(ptr_member_ty_id, ptr_composite_id, &.{@as(u32, @intCast(index))}); | | |
| 792 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | | |
| 793 | .pointer = ptr_id, | | |
| 794 | .object = constitent_id, | | |
| 795 | }); | | |
| 796 | } | | |
| 797 | return try self.load(ty, ptr_composite_id, .{}); | | |
| 798 | } | 791 | } |
| 799 | | 792 | |
| 800 | /// Construct a vector at runtime. | 793 | /// Construct a vector at runtime. |
| ... | @@ -839,23 +832,13 @@ const DeclGen = struct { | ... | @@ -839,23 +832,13 @@ const DeclGen = struct { |
| 839 | /// Constituents should be in `indirect` representation (as the elements of an array should be). | 832 | /// Constituents should be in `indirect` representation (as the elements of an array should be). |
| 840 | /// Result is in `direct` representation. | 833 | /// Result is in `direct` representation. |
| 841 | fn constructArray(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | 834 | fn constructArray(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| 842 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' | 835 | const result_id = self.spv.allocId(); |
| 843 | // operands are not constant. | 836 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| 844 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 | 837 | .id_result_type = try self.resolveType(ty, .direct), |
| 845 | // For now, just initialize the struct by setting the fields manually... | 838 | .id_result = result_id, |
| 846 | // TODO: Make this OpCompositeConstruct when we can | 839 | .constituents = constituents, |
| 847 | const mod = self.module; | 840 | }); |
| 848 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); | 841 | return result_id; |
| 849 | const ptr_elem_ty_id = try self.ptrType(ty.elemType2(mod), .Function); | | |
| 850 | for (constituents, 0..) |constitent_id, index| { | | |
| 851 | const ptr_id = try self.accessChain(ptr_elem_ty_id, ptr_composite_id, &.{@as(u32, @intCast(index))}); | | |
| 852 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | | |
| 853 | .pointer = ptr_id, | | |
| 854 | .object = constitent_id, | | |
| 855 | }); | | |
| 856 | } | | |
| 857 | | | |
| 858 | return try self.load(ty, ptr_composite_id, .{}); | | |
| 859 | } | 842 | } |
| 860 | | 843 | |
| 861 | /// This function generates a load for a constant in direct (ie, non-memory) representation. | 844 | /// This function generates a load for a constant in direct (ie, non-memory) representation. |