| author | |
| committer | |
| log | ddcea2cad486684607039aab45634e0e30e7312a |
| tree | d7f2c3372321c27bc6111bdeb3430bcd3e1cc76f |
| parent | 919a3bae1c5f2024b09e127a15c752d9dc0aa9a6 |
| parent | 37b0aa600ad47872d3a03f9e9fb60316fc3587c5 |
| signature |
spirv: make rusticl the primary testing implementation15 files changed, 51 insertions(+), 139 deletions(-)
src/codegen/spirv.zig+29-123| ... | @@ -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 { |
src/codegen/spirv/Module.zig+6-7| ... | @@ -407,12 +407,12 @@ pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void { | ... | @@ -407,12 +407,12 @@ pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void { |
| 407 | var types_constants = try self.cache.materialize(self); | 407 | var types_constants = try self.cache.materialize(self); |
| 408 | defer types_constants.deinit(self.gpa); | 408 | defer types_constants.deinit(self.gpa); |
| 409 | 409 | ||
| 410 | // TODO: Vulkan doesn't support initializer kernel | 410 | // // TODO: Pass global variables as function parameters |
| 411 | var init_func = if (target.os.tag != .vulkan) | 411 | // var init_func = if (target.os.tag != .vulkan) |
| 412 | try self.initializer(&entry_points) | 412 | // try self.initializer(&entry_points) |
| 413 | else | 413 | // else |
| 414 | Section{}; | 414 | // Section{}; |
| 415 | defer init_func.deinit(self.gpa); | 415 | // defer init_func.deinit(self.gpa); |
| 416 | 416 | ||
| 417 | const header = [_]Word{ | 417 | const header = [_]Word{ |
| 418 | spec.magic_number, | 418 | spec.magic_number, |
| ... | @@ -458,7 +458,6 @@ pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void { | ... | @@ -458,7 +458,6 @@ pub fn flush(self: *Module, file: std.fs.File, target: std.Target) !void { |
| 458 | self.sections.types_globals_constants.toWords(), | 458 | self.sections.types_globals_constants.toWords(), |
| 459 | globals.toWords(), | 459 | globals.toWords(), |
| 460 | self.sections.functions.toWords(), | 460 | self.sections.functions.toWords(), |
| 461 | init_func.toWords(), | ||
| 462 | }; | 461 | }; |
| 463 | 462 | ||
| 464 | var iovc_buffers: [buffers.len]std.os.iovec_const = undefined; | 463 | var iovc_buffers: [buffers.len]std.os.iovec_const = undefined; |
src/link/SpirV.zig+1-1| ... | @@ -163,7 +163,7 @@ pub fn updateExports( | ... | @@ -163,7 +163,7 @@ pub fn updateExports( |
| 163 | .Vertex => spec.ExecutionModel.Vertex, | 163 | .Vertex => spec.ExecutionModel.Vertex, |
| 164 | .Fragment => spec.ExecutionModel.Fragment, | 164 | .Fragment => spec.ExecutionModel.Fragment, |
| 165 | .Kernel => spec.ExecutionModel.Kernel, | 165 | .Kernel => spec.ExecutionModel.Kernel, |
| 166 | else => unreachable, | 166 | else => return, |
| 167 | }; | 167 | }; |
| 168 | const is_vulkan = target.os.tag == .vulkan; | 168 | const is_vulkan = target.os.tag == .vulkan; |
| 169 | 169 |
test/behavior/basic.zig-2| ... | @@ -756,7 +756,6 @@ test "extern variable with non-pointer opaque type" { | ... | @@ -756,7 +756,6 @@ test "extern variable with non-pointer opaque type" { |
| 756 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 756 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 757 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 757 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 758 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 758 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 759 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 760 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 759 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 761 | 760 | ||
| 762 | @export(var_to_export, .{ .name = "opaque_extern_var" }); | 761 | @export(var_to_export, .{ .name = "opaque_extern_var" }); |
| ... | @@ -1195,7 +1194,6 @@ test "integer compare" { | ... | @@ -1195,7 +1194,6 @@ test "integer compare" { |
| 1195 | 1194 | ||
| 1196 | test "reference to inferred local variable works as expected" { | 1195 | test "reference to inferred local variable works as expected" { |
| 1197 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1196 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1198 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1199 | 1197 | ||
| 1200 | const Crasher = struct { | 1198 | const Crasher = struct { |
| 1201 | lets_crash: u64 = 0, | 1199 | lets_crash: u64 = 0, |
test/behavior/byval_arg_var.zig+1| ... | @@ -5,6 +5,7 @@ var result: []const u8 = "wrong"; | ... | @@ -5,6 +5,7 @@ var result: []const u8 = "wrong"; |
| 5 | 5 | ||
| 6 | test "pass string literal byvalue to a generic var param" { | 6 | test "pass string literal byvalue to a generic var param" { |
| 7 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 8 | 9 | ||
| 9 | start(); | 10 | start(); |
| 10 | blowUpStack(10); | 11 | blowUpStack(10); |
test/behavior/cast.zig+1| ... | @@ -1262,6 +1262,7 @@ test "implicit cast from *T to ?*anyopaque" { | ... | @@ -1262,6 +1262,7 @@ test "implicit cast from *T to ?*anyopaque" { |
| 1262 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1262 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1263 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1263 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1264 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1264 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1265 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1265 | 1266 | ||
| 1266 | var a: u8 = 1; | 1267 | var a: u8 = 1; |
| 1267 | incrementVoidPtrValue(&a); | 1268 | incrementVoidPtrValue(&a); |
test/behavior/error.zig+2| ... | @@ -124,6 +124,7 @@ test "debug info for optional error set" { | ... | @@ -124,6 +124,7 @@ test "debug info for optional error set" { |
| 124 | 124 | ||
| 125 | test "implicit cast to optional to error union to return result loc" { | 125 | test "implicit cast to optional to error union to return result loc" { |
| 126 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 126 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 127 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 127 | 128 | ||
| 128 | const S = struct { | 129 | const S = struct { |
| 129 | fn entry() !void { | 130 | fn entry() !void { |
| ... | @@ -950,6 +951,7 @@ test "returning an error union containing a type with no runtime bits" { | ... | @@ -950,6 +951,7 @@ test "returning an error union containing a type with no runtime bits" { |
| 950 | test "try used in recursive function with inferred error set" { | 951 | test "try used in recursive function with inferred error set" { |
| 951 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 952 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 952 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 953 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 954 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 953 | 955 | ||
| 954 | const Value = union(enum) { | 956 | const Value = union(enum) { |
| 955 | values: []const @This(), | 957 | values: []const @This(), |
test/behavior/floatop.zig+2| ... | @@ -127,6 +127,7 @@ test "cmp f16" { | ... | @@ -127,6 +127,7 @@ test "cmp f16" { |
| 127 | test "cmp f32/f64" { | 127 | test "cmp f32/f64" { |
| 128 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 128 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 129 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 129 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 130 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 130 | 131 | ||
| 131 | try testCmp(f32); | 132 | try testCmp(f32); |
| 132 | try comptime testCmp(f32); | 133 | try comptime testCmp(f32); |
| ... | @@ -978,6 +979,7 @@ test "@abs f32/f64" { | ... | @@ -978,6 +979,7 @@ test "@abs f32/f64" { |
| 978 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 979 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 979 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 980 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 980 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 981 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 982 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 981 | 983 | ||
| 982 | try testFabs(f32); | 984 | try testFabs(f32); |
| 983 | try comptime testFabs(f32); | 985 | try comptime testFabs(f32); |
test/behavior/globals.zig-1| ... | @@ -50,7 +50,6 @@ test "global loads can affect liveness" { | ... | @@ -50,7 +50,6 @@ test "global loads can affect liveness" { |
| 50 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 50 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 52 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 52 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 53 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 54 | 53 | ||
| 55 | const S = struct { | 54 | const S = struct { |
| 56 | const ByRef = struct { | 55 | const ByRef = struct { |
test/behavior/optional.zig+3| ... | @@ -28,6 +28,7 @@ pub const EmptyStruct = struct {}; | ... | @@ -28,6 +28,7 @@ pub const EmptyStruct = struct {}; |
| 28 | 28 | ||
| 29 | test "optional pointer to size zero struct" { | 29 | test "optional pointer to size zero struct" { |
| 30 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 30 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 31 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 31 | 32 | ||
| 32 | var e = EmptyStruct{}; | 33 | var e = EmptyStruct{}; |
| 33 | const o: ?*EmptyStruct = &e; | 34 | const o: ?*EmptyStruct = &e; |
| ... | @@ -35,6 +36,8 @@ test "optional pointer to size zero struct" { | ... | @@ -35,6 +36,8 @@ test "optional pointer to size zero struct" { |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | test "equality compare optional pointers" { | 38 | test "equality compare optional pointers" { |
| 39 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 40 | |||
| 38 | try testNullPtrsEql(); | 41 | try testNullPtrsEql(); |
| 39 | try comptime testNullPtrsEql(); | 42 | try comptime testNullPtrsEql(); |
| 40 | } | 43 | } |
test/behavior/pointers.zig+1| ... | @@ -216,6 +216,7 @@ test "assign null directly to C pointer and test null equality" { | ... | @@ -216,6 +216,7 @@ test "assign null directly to C pointer and test null equality" { |
| 216 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 216 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 217 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 217 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 218 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 218 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 219 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 219 | 220 | ||
| 220 | var x: [*c]i32 = null; | 221 | var x: [*c]i32 = null; |
| 221 | _ = &x; | 222 | _ = &x; |
test/behavior/typename.zig-5| ... | @@ -41,7 +41,6 @@ test "anon field init" { | ... | @@ -41,7 +41,6 @@ test "anon field init" { |
| 41 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 41 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 42 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 42 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 43 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 43 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 44 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 45 | 44 | ||
| 46 | const Foo = .{ | 45 | const Foo = .{ |
| 47 | .T1 = struct {}, | 46 | .T1 = struct {}, |
| ... | @@ -90,7 +89,6 @@ test "top level decl" { | ... | @@ -90,7 +89,6 @@ test "top level decl" { |
| 90 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 89 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 91 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 90 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 92 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 93 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 94 | 92 | ||
| 95 | try expectEqualStrings( | 93 | try expectEqualStrings( |
| 96 | "behavior.typename.A_Struct", | 94 | "behavior.typename.A_Struct", |
| ... | @@ -140,7 +138,6 @@ test "fn param" { | ... | @@ -140,7 +138,6 @@ test "fn param" { |
| 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 139 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 140 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 143 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 144 | 141 | ||
| 145 | // https://github.com/ziglang/zig/issues/675 | 142 | // https://github.com/ziglang/zig/issues/675 |
| 146 | try expectEqualStrings( | 143 | try expectEqualStrings( |
| ... | @@ -211,7 +208,6 @@ test "local variable" { | ... | @@ -211,7 +208,6 @@ test "local variable" { |
| 211 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 208 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 212 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 209 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 213 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 210 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 214 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 215 | 211 | ||
| 216 | const Foo = struct { a: u32 }; | 212 | const Foo = struct { a: u32 }; |
| 217 | const Bar = union { a: u32 }; | 213 | const Bar = union { a: u32 }; |
| ... | @@ -239,7 +235,6 @@ test "anon name strategy used in sub expression" { | ... | @@ -239,7 +235,6 @@ test "anon name strategy used in sub expression" { |
| 239 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 235 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 240 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 236 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 241 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 237 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 242 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 243 | 238 | ||
| 244 | const S = struct { | 239 | const S = struct { |
| 245 | fn getTheName() []const u8 { | 240 | fn getTheName() []const u8 { |
test/behavior/undefined.zig+1| ... | @@ -104,6 +104,7 @@ test "returned undef is 0xaa bytes when runtime safety is enabled" { | ... | @@ -104,6 +104,7 @@ test "returned undef is 0xaa bytes when runtime safety is enabled" { |
| 104 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 104 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 105 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 105 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 106 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 106 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 107 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 107 | 108 | ||
| 108 | const Rect = struct { | 109 | const Rect = struct { |
| 109 | x: f32, | 110 | x: f32, |
test/behavior/vector.zig+2| ... | @@ -372,6 +372,7 @@ test "load vector elements via comptime index" { | ... | @@ -372,6 +372,7 @@ test "load vector elements via comptime index" { |
| 372 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 372 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 373 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 373 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 374 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 374 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 375 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 375 | 376 | ||
| 376 | const S = struct { | 377 | const S = struct { |
| 377 | fn doTheTest() !void { | 378 | fn doTheTest() !void { |
| ... | @@ -393,6 +394,7 @@ test "store vector elements via comptime index" { | ... | @@ -393,6 +394,7 @@ test "store vector elements via comptime index" { |
| 393 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 394 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 394 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 395 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 395 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 396 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 397 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 396 | 398 | ||
| 397 | const S = struct { | 399 | const S = struct { |
| 398 | fn doTheTest() !void { | 400 | fn doTheTest() !void { |
test/behavior/while.zig+2| ... | @@ -38,6 +38,8 @@ fn staticWhileLoop2() i32 { | ... | @@ -38,6 +38,8 @@ fn staticWhileLoop2() i32 { |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | test "while with continue expression" { | 40 | test "while with continue expression" { |
| 41 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 42 | |||
| 41 | var sum: i32 = 0; | 43 | var sum: i32 = 0; |
| 42 | { | 44 | { |
| 43 | var i: i32 = 0; | 45 | var i: i32 = 0; |