| ... | @@ -721,75 +721,18 @@ const DeclGen = struct { | ... | @@ -721,75 +721,18 @@ const DeclGen = struct { |
| 721 | }; | 721 | }; |
| 722 | } | 722 | } |
| 723 | | 723 | |
| 724 | /// Construct a struct at runtime. | 724 | /// Construct a composite value at runtime. If the parameters are in direct |
| 725 | /// ty must be a struct type. | 725 | /// representation, then the result is also in direct representation. Otherwise, |
| 726 | /// Constituents should be in `indirect` representation (as the elements of a struct should be). | 726 | /// if the parameters are in indirect representation, then the result is too. |
| 727 | /// Result is in `direct` representation. | 727 | fn constructComposite(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| 728 | fn constructStruct(self: *DeclGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef { | 728 | const constituents_id = self.spv.allocId(); |
| 729 | assert(types.len == constituents.len); | 729 | const type_id = try self.resolveTypeId(ty); |
| 730 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' | 730 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| 731 | // operands are not constant. | 731 | .id_result_type = type_id, |
| 732 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 | 732 | .id_result = constituents_id, |
| 733 | // For now, just initialize the struct by setting the fields manually... | 733 | .constituents = constituents, |
| 734 | // TODO: Make this OpCompositeConstruct when we can | 734 | }); |
| 735 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); | 735 | return constituents_id; |
| 736 | for (constituents, types, 0..) |constitent_id, member_ty, index| { | | |
| 737 | const ptr_member_ty_ref = try self.ptrType(member_ty, .Function); | | |
| 738 | const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); | | |
| 739 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | | |
| 740 | .pointer = ptr_id, | | |
| 741 | .object = constitent_id, | | |
| 742 | }); | | |
| 743 | } | | |
| 744 | return try self.load(ty, ptr_composite_id, .{}); | | |
| 745 | } | | |
| 746 | | | |
| 747 | /// Construct a vector at runtime. | | |
| 748 | /// ty must be an vector type. | | |
| 749 | /// Constituents should be in `indirect` representation (as the elements of an vector should be). | | |
| 750 | /// Result is in `direct` representation. | | |
| 751 | fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | | |
| 752 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' | | |
| 753 | // operands are not constant. | | |
| 754 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 | | |
| 755 | // For now, just initialize the struct by setting the fields manually... | | |
| 756 | // TODO: Make this OpCompositeConstruct when we can | | |
| 757 | const mod = self.module; | | |
| 758 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); | | |
| 759 | const ptr_elem_ty_ref = try self.ptrType(ty.elemType2(mod), .Function); | | |
| 760 | for (constituents, 0..) |constitent_id, index| { | | |
| 761 | const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); | | |
| 762 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | | |
| 763 | .pointer = ptr_id, | | |
| 764 | .object = constitent_id, | | |
| 765 | }); | | |
| 766 | } | | |
| 767 | | | |
| 768 | return try self.load(ty, ptr_composite_id, .{}); | | |
| 769 | } | | |
| 770 | | | |
| 771 | /// Construct an array at runtime. | | |
| 772 | /// ty must be an array type. | | |
| 773 | /// Constituents should be in `indirect` representation (as the elements of an array should be). | | |
| 774 | /// Result is in `direct` representation. | | |
| 775 | fn constructArray(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | | |
| 776 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' | | |
| 777 | // operands are not constant. | | |
| 778 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 | | |
| 779 | // For now, just initialize the struct by setting the fields manually... | | |
| 780 | // TODO: Make this OpCompositeConstruct when we can | | |
| 781 | const mod = self.module; | | |
| 782 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); | | |
| 783 | const ptr_elem_ty_ref = try self.ptrType(ty.elemType2(mod), .Function); | | |
| 784 | for (constituents, 0..) |constitent_id, index| { | | |
| 785 | const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); | | |
| 786 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | | |
| 787 | .pointer = ptr_id, | | |
| 788 | .object = constitent_id, | | |
| 789 | }); | | |
| 790 | } | | |
| 791 | | | |
| 792 | return try self.load(ty, ptr_composite_id, .{}); | | |
| 793 | } | 736 | } |
| 794 | | 737 | |
| 795 | /// This function generates a load for a constant in direct (ie, non-memory) representation. | 738 | /// This function generates a load for a constant in direct (ie, non-memory) representation. |
| ... | @@ -897,18 +840,15 @@ const DeclGen = struct { | ... | @@ -897,18 +840,15 @@ const DeclGen = struct { |
| 897 | }); | 840 | }); |
| 898 | | 841 | |
| 899 | var constituents: [2]IdRef = undefined; | 842 | var constituents: [2]IdRef = undefined; |
| 900 | var types: [2]Type = undefined; | | |
| 901 | if (eu_layout.error_first) { | 843 | if (eu_layout.error_first) { |
| 902 | constituents[0] = try self.constant(err_ty, err_val, .indirect); | 844 | constituents[0] = try self.constant(err_ty, err_val, .indirect); |
| 903 | constituents[1] = try self.constant(payload_ty, payload_val, .indirect); | 845 | constituents[1] = try self.constant(payload_ty, payload_val, .indirect); |
| 904 | types = .{ err_ty, payload_ty }; | | |
| 905 | } else { | 846 | } else { |
| 906 | constituents[0] = try self.constant(payload_ty, payload_val, .indirect); | 847 | constituents[0] = try self.constant(payload_ty, payload_val, .indirect); |
| 907 | constituents[1] = try self.constant(err_ty, err_val, .indirect); | 848 | constituents[1] = try self.constant(err_ty, err_val, .indirect); |
| 908 | types = .{ payload_ty, err_ty }; | | |
| 909 | } | 849 | } |
| 910 | | 850 | |
| 911 | return try self.constructStruct(ty, &types, &constituents); | 851 | return try self.constructComposite(ty, &constituents); |
| 912 | }, | 852 | }, |
| 913 | .enum_tag => { | 853 | .enum_tag => { |
| 914 | const int_val = try val.intFromEnum(ty, mod); | 854 | const int_val = try val.intFromEnum(ty, mod); |
| ... | @@ -920,11 +860,7 @@ const DeclGen = struct { | ... | @@ -920,11 +860,7 @@ const DeclGen = struct { |
| 920 | const ptr_ty = ty.slicePtrFieldType(mod); | 860 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 921 | const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr)); | 861 | const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr)); |
| 922 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); | 862 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); |
| 923 | return self.constructStruct( | 863 | return self.constructComposite(ty, &.{ ptr_id, len_id }); |
| 924 | ty, | | |
| 925 | &.{ ptr_ty, Type.usize }, | | |
| 926 | &.{ ptr_id, len_id }, | | |
| 927 | ); | | |
| 928 | }, | 864 | }, |
| 929 | .opt => { | 865 | .opt => { |
| 930 | const payload_ty = ty.optionalChild(mod); | 866 | const payload_ty = ty.optionalChild(mod); |
| ... | @@ -951,11 +887,7 @@ const DeclGen = struct { | ... | @@ -951,11 +887,7 @@ const DeclGen = struct { |
| 951 | else | 887 | else |
| 952 | try self.spv.constUndef(try self.resolveType(payload_ty, .indirect)); | 888 | try self.spv.constUndef(try self.resolveType(payload_ty, .indirect)); |
| 953 | | 889 | |
| 954 | return try self.constructStruct( | 890 | return try self.constructComposite(ty, &.{ payload_id, has_pl_id }); |
| 955 | ty, | | |
| 956 | &.{ payload_ty, Type.bool }, | | |
| 957 | &.{ payload_id, has_pl_id }, | | |
| 958 | ); | | |
| 959 | }, | 891 | }, |
| 960 | .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) { | 892 | .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) { |
| 961 | inline .array_type, .vector_type => |array_type, tag| { | 893 | inline .array_type, .vector_type => |array_type, tag| { |
| ... | @@ -992,9 +924,9 @@ const DeclGen = struct { | ... | @@ -992,9 +924,9 @@ const DeclGen = struct { |
| 992 | const sentinel = Value.fromInterned(array_type.sentinel); | 924 | const sentinel = Value.fromInterned(array_type.sentinel); |
| 993 | constituents[constituents.len - 1] = try self.constant(elem_ty, sentinel, .indirect); | 925 | constituents[constituents.len - 1] = try self.constant(elem_ty, sentinel, .indirect); |
| 994 | } | 926 | } |
| 995 | return self.constructArray(ty, constituents); | 927 | return self.constructComposite(ty, constituents); |
| 996 | }, | 928 | }, |
| 997 | inline .vector_type => return self.constructVector(ty, constituents), | 929 | inline .vector_type => return self.constructComposite(ty, constituents), |
| 998 | else => unreachable, | 930 | else => unreachable, |
| 999 | } | 931 | } |
| 1000 | }, | 932 | }, |
| ... | @@ -1004,9 +936,6 @@ const DeclGen = struct { | ... | @@ -1004,9 +936,6 @@ const DeclGen = struct { |
| 1004 | return self.todo("packed struct constants", .{}); | 936 | return self.todo("packed struct constants", .{}); |
| 1005 | } | 937 | } |
| 1006 | | 938 | |
| 1007 | var types = std.ArrayList(Type).init(self.gpa); | | |
| 1008 | defer types.deinit(); | | |
| 1009 | | | |
| 1010 | var constituents = std.ArrayList(IdRef).init(self.gpa); | 939 | var constituents = std.ArrayList(IdRef).init(self.gpa); |
| 1011 | defer constituents.deinit(); | 940 | defer constituents.deinit(); |
| 1012 | | 941 | |
| ... | @@ -1022,11 +951,10 @@ const DeclGen = struct { | ... | @@ -1022,11 +951,10 @@ const DeclGen = struct { |
| 1022 | const field_val = try val.fieldValue(mod, field_index); | 951 | const field_val = try val.fieldValue(mod, field_index); |
| 1023 | const field_id = try self.constant(field_ty, field_val, .indirect); | 952 | const field_id = try self.constant(field_ty, field_val, .indirect); |
| 1024 | | 953 | |
| 1025 | try types.append(field_ty); | | |
| 1026 | try constituents.append(field_id); | 954 | try constituents.append(field_id); |
| 1027 | } | 955 | } |
| 1028 | | 956 | |
| 1029 | return try self.constructStruct(ty, types.items, constituents.items); | 957 | return try self.constructComposite(ty, constituents.items); |
| 1030 | }, | 958 | }, |
| 1031 | .anon_struct_type => unreachable, // TODO | 959 | .anon_struct_type => unreachable, // TODO |
| 1032 | else => unreachable, | 960 | else => unreachable, |
| ... | @@ -1870,7 +1798,7 @@ const DeclGen = struct { | ... | @@ -1870,7 +1798,7 @@ const DeclGen = struct { |
| 1870 | for (wip.results) |*result| { | 1798 | for (wip.results) |*result| { |
| 1871 | result.* = try wip.dg.convertToIndirect(wip.scalar_ty, result.*); | 1799 | result.* = try wip.dg.convertToIndirect(wip.scalar_ty, result.*); |
| 1872 | } | 1800 | } |
| 1873 | return try wip.dg.constructArray(wip.result_ty, wip.results); | 1801 | return try wip.dg.constructComposite(wip.result_ty, wip.results); |
| 1874 | } else { | 1802 | } else { |
| 1875 | return wip.results[0]; | 1803 | return wip.results[0]; |
| 1876 | } | 1804 | } |
| ... | @@ -2814,9 +2742,8 @@ const DeclGen = struct { | ... | @@ -2814,9 +2742,8 @@ const DeclGen = struct { |
| 2814 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); | 2742 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); |
| 2815 | } | 2743 | } |
| 2816 | | 2744 | |
| 2817 | return try self.constructStruct( | 2745 | return try self.constructComposite( |
| 2818 | result_ty, | 2746 | result_ty, |
| 2819 | &.{ operand_ty, ov_ty }, | | |
| 2820 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, | 2747 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, |
| 2821 | ); | 2748 | ); |
| 2822 | } | 2749 | } |
| ... | @@ -2905,9 +2832,8 @@ const DeclGen = struct { | ... | @@ -2905,9 +2832,8 @@ const DeclGen = struct { |
| 2905 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); | 2832 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); |
| 2906 | } | 2833 | } |
| 2907 | | 2834 | |
| 2908 | return try self.constructStruct( | 2835 | return try self.constructComposite( |
| 2909 | result_ty, | 2836 | result_ty, |
| 2910 | &.{ operand_ty, ov_ty }, | | |
| 2911 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, | 2837 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, |
| 2912 | ); | 2838 | ); |
| 2913 | } | 2839 | } |
| ... | @@ -3637,9 +3563,8 @@ const DeclGen = struct { | ... | @@ -3637,9 +3563,8 @@ const DeclGen = struct { |
| 3637 | // Convert the pointer-to-array to a pointer to the first element. | 3563 | // Convert the pointer-to-array to a pointer to the first element. |
| 3638 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); | 3564 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); |
| 3639 | | 3565 | |
| 3640 | return try self.constructStruct( | 3566 | return try self.constructComposite( |
| 3641 | slice_ty, | 3567 | slice_ty, |
| 3642 | &.{ elem_ptr_ty, Type.usize }, | | |
| 3643 | &.{ elem_ptr_id, len_id }, | 3568 | &.{ elem_ptr_id, len_id }, |
| 3644 | ); | 3569 | ); |
| 3645 | } | 3570 | } |
| ... | @@ -3651,14 +3576,12 @@ const DeclGen = struct { | ... | @@ -3651,14 +3576,12 @@ const DeclGen = struct { |
| 3651 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3576 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3652 | const ptr_id = try self.resolve(bin_op.lhs); | 3577 | const ptr_id = try self.resolve(bin_op.lhs); |
| 3653 | const len_id = try self.resolve(bin_op.rhs); | 3578 | const len_id = try self.resolve(bin_op.rhs); |
| 3654 | const ptr_ty = self.typeOf(bin_op.lhs); | | |
| 3655 | const slice_ty = self.typeOfIndex(inst); | 3579 | const slice_ty = self.typeOfIndex(inst); |
| 3656 | | 3580 | |
| 3657 | // Note: Types should not need to be converted to direct, these types | 3581 | // Note: Types should not need to be converted to direct, these types |
| 3658 | // dont need to be converted. | 3582 | // dont need to be converted. |
| 3659 | return try self.constructStruct( | 3583 | return try self.constructComposite( |
| 3660 | slice_ty, | 3584 | slice_ty, |
| 3661 | &.{ ptr_ty, Type.usize }, | | |
| 3662 | &.{ ptr_id, len_id }, | 3585 | &.{ ptr_id, len_id }, |
| 3663 | ); | 3586 | ); |
| 3664 | } | 3587 | } |
| ... | @@ -3680,8 +3603,6 @@ const DeclGen = struct { | ... | @@ -3680,8 +3603,6 @@ const DeclGen = struct { |
| 3680 | unreachable; // TODO | 3603 | unreachable; // TODO |
| 3681 | } | 3604 | } |
| 3682 | | 3605 | |
| 3683 | const types = try self.gpa.alloc(Type, elements.len); | | |
| 3684 | defer self.gpa.free(types); | | |
| 3685 | const constituents = try self.gpa.alloc(IdRef, elements.len); | 3606 | const constituents = try self.gpa.alloc(IdRef, elements.len); |
| 3686 | defer self.gpa.free(constituents); | 3607 | defer self.gpa.free(constituents); |
| 3687 | var index: usize = 0; | 3608 | var index: usize = 0; |
| ... | @@ -3693,7 +3614,6 @@ const DeclGen = struct { | ... | @@ -3693,7 +3614,6 @@ const DeclGen = struct { |
| 3693 | assert(Type.fromInterned(field_ty).hasRuntimeBits(mod)); | 3614 | assert(Type.fromInterned(field_ty).hasRuntimeBits(mod)); |
| 3694 | | 3615 | |
| 3695 | const id = try self.resolve(element); | 3616 | const id = try self.resolve(element); |
| 3696 | types[index] = Type.fromInterned(field_ty); | | |
| 3697 | constituents[index] = try self.convertToIndirect(Type.fromInterned(field_ty), id); | 3617 | constituents[index] = try self.convertToIndirect(Type.fromInterned(field_ty), id); |
| 3698 | index += 1; | 3618 | index += 1; |
| 3699 | } | 3619 | } |
| ... | @@ -3707,7 +3627,6 @@ const DeclGen = struct { | ... | @@ -3707,7 +3627,6 @@ const DeclGen = struct { |
| 3707 | assert(field_ty.hasRuntimeBitsIgnoreComptime(mod)); | 3627 | assert(field_ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 3708 | | 3628 | |
| 3709 | const id = try self.resolve(element); | 3629 | const id = try self.resolve(element); |
| 3710 | types[index] = field_ty; | | |
| 3711 | constituents[index] = try self.convertToIndirect(field_ty, id); | 3630 | constituents[index] = try self.convertToIndirect(field_ty, id); |
| 3712 | index += 1; | 3631 | index += 1; |
| 3713 | } | 3632 | } |
| ... | @@ -3715,11 +3634,7 @@ const DeclGen = struct { | ... | @@ -3715,11 +3634,7 @@ const DeclGen = struct { |
| 3715 | else => unreachable, | 3634 | else => unreachable, |
| 3716 | } | 3635 | } |
| 3717 | | 3636 | |
| 3718 | return try self.constructStruct( | 3637 | return try self.constructComposite(result_ty, constituents[0..index]); |
| 3719 | result_ty, | | |
| 3720 | types[0..index], | | |
| 3721 | constituents[0..index], | | |
| 3722 | ); | | |
| 3723 | }, | 3638 | }, |
| 3724 | .Vector => { | 3639 | .Vector => { |
| 3725 | const n_elems = result_ty.vectorLen(mod); | 3640 | const n_elems = result_ty.vectorLen(mod); |
| ... | @@ -3731,7 +3646,7 @@ const DeclGen = struct { | ... | @@ -3731,7 +3646,7 @@ const DeclGen = struct { |
| 3731 | elem_ids[i] = try self.convertToIndirect(result_ty.childType(mod), id); | 3646 | elem_ids[i] = try self.convertToIndirect(result_ty.childType(mod), id); |
| 3732 | } | 3647 | } |
| 3733 | | 3648 | |
| 3734 | return try self.constructVector(result_ty, elem_ids); | 3649 | return try self.constructComposite(result_ty, elem_ids); |
| 3735 | }, | 3650 | }, |
| 3736 | .Array => { | 3651 | .Array => { |
| 3737 | const array_info = result_ty.arrayInfo(mod); | 3652 | const array_info = result_ty.arrayInfo(mod); |
| ... | @@ -3748,7 +3663,7 @@ const DeclGen = struct { | ... | @@ -3748,7 +3663,7 @@ const DeclGen = struct { |
| 3748 | elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect); | 3663 | elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect); |
| 3749 | } | 3664 | } |
| 3750 | | 3665 | |
| 3751 | return try self.constructArray(result_ty, elem_ids); | 3666 | return try self.constructComposite(result_ty, elem_ids); |
| 3752 | }, | 3667 | }, |
| 3753 | else => unreachable, | 3668 | else => unreachable, |
| 3754 | } | 3669 | } |
| ... | @@ -4885,11 +4800,7 @@ const DeclGen = struct { | ... | @@ -4885,11 +4800,7 @@ const DeclGen = struct { |
| 4885 | members[eu_layout.errorFieldIndex()] = operand_id; | 4800 | members[eu_layout.errorFieldIndex()] = operand_id; |
| 4886 | members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref); | 4801 | members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref); |
| 4887 | | 4802 | |
| 4888 | var types: [2]Type = undefined; | 4803 | return try self.constructComposite(err_union_ty, &members); |
| 4889 | types[eu_layout.errorFieldIndex()] = Type.anyerror; | | |
| 4890 | types[eu_layout.payloadFieldIndex()] = payload_ty; | | |
| 4891 | | | |
| 4892 | return try self.constructStruct(err_union_ty, &types, &members); | | |
| 4893 | } | 4804 | } |
| 4894 | | 4805 | |
| 4895 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4806 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -4910,11 +4821,7 @@ const DeclGen = struct { | ... | @@ -4910,11 +4821,7 @@ const DeclGen = struct { |
| 4910 | members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0); | 4821 | members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0); |
| 4911 | members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id); | 4822 | members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id); |
| 4912 | | 4823 | |
| 4913 | var types: [2]Type = undefined; | 4824 | return try self.constructComposite(err_union_ty, &members); |
| 4914 | types[eu_layout.errorFieldIndex()] = Type.anyerror; | | |
| 4915 | types[eu_layout.payloadFieldIndex()] = payload_ty; | | |
| 4916 | | | |
| 4917 | return try self.constructStruct(err_union_ty, &types, &members); | | |
| 4918 | } | 4825 | } |
| 4919 | | 4826 | |
| 4920 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { | 4827 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { |
| ... | @@ -5091,8 +4998,7 @@ const DeclGen = struct { | ... | @@ -5091,8 +4998,7 @@ const DeclGen = struct { |
| 5091 | | 4998 | |
| 5092 | const payload_id = try self.convertToIndirect(payload_ty, operand_id); | 4999 | const payload_id = try self.convertToIndirect(payload_ty, operand_id); |
| 5093 | const members = [_]IdRef{ payload_id, try self.constBool(true, .indirect) }; | 5000 | const members = [_]IdRef{ payload_id, try self.constBool(true, .indirect) }; |
| 5094 | const types = [_]Type{ payload_ty, Type.bool }; | 5001 | return try self.constructComposite(optional_ty, &members); |
| 5095 | return try self.constructStruct(optional_ty, &types, &members); | | |
| 5096 | } | 5002 | } |
| 5097 | | 5003 | |
| 5098 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { | 5004 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { |