authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-20 13:54:01-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-20 13:54:01-07:00
log7621e56938ed6d86827c11ee6272db722f350fed
treeaf79c9d211810cd7ea6d3a145fa0e4f08bc85b92
parent413ef3aa38899195d113fc51a5c035a7c15103eb
parentc92cc5798f0ea72ab1c77ae12c6124e5ab090730
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15753 from Snektron/spirv-more-tests

spirv: make more tests pass

44 files changed, 537 insertions(+), 437 deletions(-)

src/codegen/spirv.zig+511-307
...@@ -242,7 +242,7 @@ pub const DeclGen = struct {...@@ -242,7 +242,7 @@ pub const DeclGen = struct {
242 return self.spv.declPtr(spv_decl_index).result_id;242 return self.spv.declPtr(spv_decl_index).result_id;
243 }243 }
244244
245 return try self.constant(ty, val);245 return try self.constant(ty, val, .direct);
246 }246 }
247 const index = Air.refToIndex(inst).?;247 const index = Air.refToIndex(inst).?;
248 return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.248 return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.
...@@ -369,21 +369,11 @@ pub const DeclGen = struct {...@@ -369,21 +369,11 @@ pub const DeclGen = struct {
369 .composite_integer,369 .composite_integer,
370 };370 };
371 },371 },
372 .Enum => blk: {
373 var buffer: Type.Payload.Bits = undefined;
374 const int_ty = ty.intTagType(&buffer);
375 const int_info = int_ty.intInfo(target);
376 break :blk ArithmeticTypeInfo{
377 .bits = int_info.bits,
378 .is_vector = false,
379 .signedness = int_info.signedness,
380 .class = .integer,
381 };
382 },
383 // As of yet, there is no vector support in the self-hosted compiler.372 // As of yet, there is no vector support in the self-hosted compiler.
384 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),373 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
385 // TODO: For which types is this the case?374 // TODO: For which types is this the case?
386 else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmt(self.module)}),375 // else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmt(self.module)}),
376 else => unreachable,
387 };377 };
388 }378 }
389379
...@@ -452,6 +442,37 @@ pub const DeclGen = struct {...@@ -452,6 +442,37 @@ pub const DeclGen = struct {
452 }442 }
453 }443 }
454444
445 /// Construct a struct at runtime.
446 /// result_ty_ref must be a struct type.
447 fn constructStruct(self: *DeclGen, result_ty_ref: SpvType.Ref, constituents: []const IdRef) !IdRef {
448 // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
449 // operands are not constant.
450 // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349
451 // For now, just initialize the struct by setting the fields manually...
452 // TODO: Make this OpCompositeConstruct when we can
453 const ptr_composite_id = try self.alloc(result_ty_ref, null);
454 // Note: using 32-bit ints here because usize crashes the translator as well
455 const index_ty_ref = try self.intType(.unsigned, 32);
456 const spv_composite_ty = self.spv.typeRefType(result_ty_ref);
457 const members = spv_composite_ty.payload(.@"struct").members;
458 for (constituents, members, 0..) |constitent_id, member, index| {
459 const index_id = try self.constInt(index_ty_ref, index);
460 const ptr_member_ty_ref = try self.spv.ptrType(member.ty, .Generic, 0);
461 const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{index_id});
462 try self.func.body.emit(self.spv.gpa, .OpStore, .{
463 .pointer = ptr_id,
464 .object = constitent_id,
465 });
466 }
467 const result_id = self.spv.allocId();
468 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
469 .id_result_type = self.typeId(result_ty_ref),
470 .id_result = result_id,
471 .pointer = ptr_composite_id,
472 });
473 return result_id;
474 }
475
455 const IndirectConstantLowering = struct {476 const IndirectConstantLowering = struct {
456 const undef = 0xAA;477 const undef = 0xAA;
457478
...@@ -705,6 +726,10 @@ pub const DeclGen = struct {...@@ -705,6 +726,10 @@ pub const DeclGen = struct {
705 try self.lower(ptr_ty, slice.ptr);726 try self.lower(ptr_ty, slice.ptr);
706 try self.addInt(Type.usize, slice.len);727 try self.addInt(Type.usize, slice.len);
707 },728 },
729 .null_value, .zero => try self.addNullPtr(try dg.resolveType(ty, .indirect)),
730 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {
731 try self.addInt(Type.usize, val);
732 },
708 else => |tag| return dg.todo("pointer value of type {s}", .{@tagName(tag)}),733 else => |tag| return dg.todo("pointer value of type {s}", .{@tagName(tag)}),
709 },734 },
710 .Struct => {735 .Struct => {
...@@ -996,14 +1021,16 @@ pub const DeclGen = struct {...@@ -996,14 +1021,16 @@ pub const DeclGen = struct {
996 /// the constant is more complicated however, it needs to be lowered to an indirect constant, which1021 /// the constant is more complicated however, it needs to be lowered to an indirect constant, which
997 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.1022 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.
998 /// This function should only be called during function code generation.1023 /// This function should only be called during function code generation.
999 fn constant(self: *DeclGen, ty: Type, val: Value) !IdRef {1024 fn constant(self: *DeclGen, ty: Type, val: Value, repr: Repr) !IdRef {
1000 const target = self.getTarget();1025 const target = self.getTarget();
1001 const section = &self.spv.sections.types_globals_constants;1026 const section = &self.spv.sections.types_globals_constants;
1002 const result_ty_ref = try self.resolveType(ty, .direct);1027 const result_ty_ref = try self.resolveType(ty, repr);
1003 const result_ty_id = self.typeId(result_ty_ref);1028 const result_ty_id = self.typeId(result_ty_ref);
1004 const result_id = self.spv.allocId();1029
1030 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtValue(ty, self.module) });
10051031
1006 if (val.isUndef()) {1032 if (val.isUndef()) {
1033 const result_id = self.spv.allocId();
1007 try section.emit(self.spv.gpa, .OpUndef, .{1034 try section.emit(self.spv.gpa, .OpUndef, .{
1008 .id_result_type = result_ty_id,1035 .id_result_type = result_ty_id,
1009 .id_result = result_id,1036 .id_result = result_id,
...@@ -1014,24 +1041,76 @@ pub const DeclGen = struct {...@@ -1014,24 +1041,76 @@ pub const DeclGen = struct {
1014 switch (ty.zigTypeTag()) {1041 switch (ty.zigTypeTag()) {
1015 .Int => {1042 .Int => {
1016 if (ty.isSignedInt()) {1043 if (ty.isSignedInt()) {
1017 try self.genConstInt(result_ty_ref, result_id, val.toSignedInt(target));1044 return try self.constInt(result_ty_ref, val.toSignedInt(target));
1018 } else {1045 } else {
1019 try self.genConstInt(result_ty_ref, result_id, val.toUnsignedInt(target));1046 return try self.constInt(result_ty_ref, val.toUnsignedInt(target));
1020 }1047 }
1021 },1048 },
1022 .Bool => {1049 .Bool => switch (repr) {
1023 const operands = .{ .id_result_type = result_ty_id, .id_result = result_id };1050 .direct => {
1024 if (val.toBool()) {1051 const result_id = self.spv.allocId();
1025 try section.emit(self.spv.gpa, .OpConstantTrue, operands);1052 const operands = .{ .id_result_type = result_ty_id, .id_result = result_id };
1053 if (val.toBool()) {
1054 try section.emit(self.spv.gpa, .OpConstantTrue, operands);
1055 } else {
1056 try section.emit(self.spv.gpa, .OpConstantFalse, operands);
1057 }
1058 return result_id;
1059 },
1060 .indirect => return try self.constInt(result_ty_ref, @boolToInt(val.toBool())),
1061 },
1062 .Float => {
1063 const result_id = self.spv.allocId();
1064 switch (ty.floatBits(target)) {
1065 16 => try self.spv.emitConstant(result_ty_id, result_id, .{ .float32 = val.toFloat(f16) }),
1066 32 => try self.spv.emitConstant(result_ty_id, result_id, .{ .float32 = val.toFloat(f32) }),
1067 64 => try self.spv.emitConstant(result_ty_id, result_id, .{ .float64 = val.toFloat(f64) }),
1068 80, 128 => unreachable, // TODO
1069 else => unreachable,
1070 }
1071 return result_id;
1072 },
1073 .ErrorSet => {
1074 const value = switch (val.tag()) {
1075 .@"error" => blk: {
1076 const err_name = val.castTag(.@"error").?.data.name;
1077 const kv = try self.module.getErrorValue(err_name);
1078 break :blk @intCast(u16, kv.value);
1079 },
1080 .zero => 0,
1081 else => unreachable,
1082 };
1083
1084 return try self.constInt(result_ty_ref, value);
1085 },
1086 .ErrorUnion => {
1087 const payload_ty = ty.errorUnionPayload();
1088 const is_pl = val.errorUnionIsPayload();
1089 const error_val = if (!is_pl) val else Value.initTag(.zero);
1090
1091 const eu_layout = self.errorUnionLayout(payload_ty);
1092 if (!eu_layout.payload_has_bits) {
1093 return try self.constant(Type.anyerror, error_val, repr);
1094 }
1095
1096 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef);
1097
1098 var members: [2]IdRef = undefined;
1099 if (eu_layout.error_first) {
1100 members[0] = try self.constant(Type.anyerror, error_val, .indirect);
1101 members[1] = try self.constant(payload_ty, payload_val, .indirect);
1026 } else {1102 } else {
1027 try section.emit(self.spv.gpa, .OpConstantFalse, operands);1103 members[0] = try self.constant(payload_ty, payload_val, .indirect);
1104 members[1] = try self.constant(Type.anyerror, error_val, .indirect);
1028 }1105 }
1106 return try self.spv.constComposite(result_ty_ref, &members);
1029 },1107 },
1030 // TODO: We can handle most pointers here (decl refs etc), because now they emit an extra1108 // TODO: We can handle most pointers here (decl refs etc), because now they emit an extra
1031 // OpVariable that is not really required.1109 // OpVariable that is not really required.
1032 else => {1110 else => {
1033 // The value cannot be generated directly, so generate it as an indirect constant,1111 // The value cannot be generated directly, so generate it as an indirect constant,
1034 // and then perform an OpLoad.1112 // and then perform an OpLoad.
1113 const result_id = self.spv.allocId();
1035 const alignment = ty.abiAlignment(target);1114 const alignment = ty.abiAlignment(target);
1036 const spv_decl_index = try self.spv.allocDecl(.global);1115 const spv_decl_index = try self.spv.allocDecl(.global);
10371116
...@@ -1053,10 +1132,9 @@ pub const DeclGen = struct {...@@ -1053,10 +1132,9 @@ pub const DeclGen = struct {
1053 });1132 });
1054 // TODO: Convert bools? This logic should hook into `load`. It should be a dead1133 // TODO: Convert bools? This logic should hook into `load`. It should be a dead
1055 // path though considering .Bool is handled above.1134 // path though considering .Bool is handled above.
1135 return result_id;
1056 },1136 },
1057 }1137 }
1058
1059 return result_id;
1060 }1138 }
10611139
1062 /// Turn a Zig type into a SPIR-V Type, and return its type result-id.1140 /// Turn a Zig type into a SPIR-V Type, and return its type result-id.
...@@ -1592,10 +1670,23 @@ pub const DeclGen = struct {...@@ -1592,10 +1670,23 @@ pub const DeclGen = struct {
1592 }1670 }
1593 }1671 }
15941672
1673 fn boolToInt(self: *DeclGen, result_ty_ref: SpvType.Ref, condition_id: IdRef) !IdRef {
1674 const zero_id = try self.constInt(result_ty_ref, 0);
1675 const one_id = try self.constInt(result_ty_ref, 1);
1676 const result_id = self.spv.allocId();
1677 try self.func.body.emit(self.spv.gpa, .OpSelect, .{
1678 .id_result_type = self.typeId(result_ty_ref),
1679 .id_result = result_id,
1680 .condition = condition_id,
1681 .object_1 = one_id,
1682 .object_2 = zero_id,
1683 });
1684 return result_id;
1685 }
1686
1595 /// Convert representation from indirect (in memory) to direct (in 'register')1687 /// Convert representation from indirect (in memory) to direct (in 'register')
1596 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).1688 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).
1597 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {1689 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
1598 // const direct_ty_ref = try self.resolveType(ty, .direct);
1599 return switch (ty.zigTypeTag()) {1690 return switch (ty.zigTypeTag()) {
1600 .Bool => blk: {1691 .Bool => blk: {
1601 const direct_bool_ty_ref = try self.resolveType(ty, .direct);1692 const direct_bool_ty_ref = try self.resolveType(ty, .direct);
...@@ -1620,17 +1711,7 @@ pub const DeclGen = struct {...@@ -1620,17 +1711,7 @@ pub const DeclGen = struct {
1620 return switch (ty.zigTypeTag()) {1711 return switch (ty.zigTypeTag()) {
1621 .Bool => blk: {1712 .Bool => blk: {
1622 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);1713 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
1623 const zero_id = try self.constInt(indirect_bool_ty_ref, 0);1714 break :blk self.boolToInt(indirect_bool_ty_ref, operand_id);
1624 const one_id = try self.constInt(indirect_bool_ty_ref, 1);
1625 const result_id = self.spv.allocId();
1626 try self.func.body.emit(self.spv.gpa, .OpSelect, .{
1627 .id_result_type = self.typeId(indirect_bool_ty_ref),
1628 .id_result = result_id,
1629 .condition = operand_id,
1630 .object_1 = one_id,
1631 .object_2 = zero_id,
1632 });
1633 break :blk result_id;
1634 },1715 },
1635 else => operand_id,1716 else => operand_id,
1636 };1717 };
...@@ -1714,6 +1795,9 @@ pub const DeclGen = struct {...@@ -1714,6 +1795,9 @@ pub const DeclGen = struct {
17141795
1715 .shuffle => try self.airShuffle(inst),1796 .shuffle => try self.airShuffle(inst),
17161797
1798 .ptr_add => try self.airPtrAdd(inst),
1799 .ptr_sub => try self.airPtrSub(inst),
1800
1717 .bit_and => try self.airBinOpSimple(inst, .OpBitwiseAnd),1801 .bit_and => try self.airBinOpSimple(inst, .OpBitwiseAnd),
1718 .bit_or => try self.airBinOpSimple(inst, .OpBitwiseOr),1802 .bit_or => try self.airBinOpSimple(inst, .OpBitwiseOr),
1719 .xor => try self.airBinOpSimple(inst, .OpBitwiseXor),1803 .xor => try self.airBinOpSimple(inst, .OpBitwiseXor),
...@@ -1722,8 +1806,8 @@ pub const DeclGen = struct {...@@ -1722,8 +1806,8 @@ pub const DeclGen = struct {
17221806
1723 .shl => try self.airShift(inst, .OpShiftLeftLogical),1807 .shl => try self.airShift(inst, .OpShiftLeftLogical),
17241808
1725 .bitcast => try self.airBitcast(inst),1809 .bitcast => try self.airBitCast(inst),
1726 .intcast, .trunc => try self.airIntcast(inst),1810 .intcast, .trunc => try self.airIntCast(inst),
1727 .ptrtoint => try self.airPtrToInt(inst),1811 .ptrtoint => try self.airPtrToInt(inst),
1728 .int_to_float => try self.airIntToFloat(inst),1812 .int_to_float => try self.airIntToFloat(inst),
1729 .float_to_int => try self.airFloatToInt(inst),1813 .float_to_int => try self.airFloatToInt(inst),
...@@ -1734,6 +1818,7 @@ pub const DeclGen = struct {...@@ -1734,6 +1818,7 @@ pub const DeclGen = struct {
1734 .slice_elem_ptr => try self.airSliceElemPtr(inst),1818 .slice_elem_ptr => try self.airSliceElemPtr(inst),
1735 .slice_elem_val => try self.airSliceElemVal(inst),1819 .slice_elem_val => try self.airSliceElemVal(inst),
1736 .ptr_elem_ptr => try self.airPtrElemPtr(inst),1820 .ptr_elem_ptr => try self.airPtrElemPtr(inst),
1821 .ptr_elem_val => try self.airPtrElemVal(inst),
17371822
1738 .get_union_tag => try self.airGetUnionTag(inst),1823 .get_union_tag => try self.airGetUnionTag(inst),
1739 .struct_field_val => try self.airStructFieldVal(inst),1824 .struct_field_val => try self.airStructFieldVal(inst),
...@@ -1743,12 +1828,12 @@ pub const DeclGen = struct {...@@ -1743,12 +1828,12 @@ pub const DeclGen = struct {
1743 .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2),1828 .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2),
1744 .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3),1829 .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3),
17451830
1746 .cmp_eq => try self.airCmp(inst, .OpFOrdEqual, .OpLogicalEqual, .OpIEqual),1831 .cmp_eq => try self.airCmp(inst, .eq),
1747 .cmp_neq => try self.airCmp(inst, .OpFOrdNotEqual, .OpLogicalNotEqual, .OpINotEqual),1832 .cmp_neq => try self.airCmp(inst, .neq),
1748 .cmp_gt => try self.airCmp(inst, .OpFOrdGreaterThan, .OpSGreaterThan, .OpUGreaterThan),1833 .cmp_gt => try self.airCmp(inst, .gt),
1749 .cmp_gte => try self.airCmp(inst, .OpFOrdGreaterThanEqual, .OpSGreaterThanEqual, .OpUGreaterThanEqual),1834 .cmp_gte => try self.airCmp(inst, .gte),
1750 .cmp_lt => try self.airCmp(inst, .OpFOrdLessThan, .OpSLessThan, .OpULessThan),1835 .cmp_lt => try self.airCmp(inst, .lt),
1751 .cmp_lte => try self.airCmp(inst, .OpFOrdLessThanEqual, .OpSLessThanEqual, .OpULessThanEqual),1836 .cmp_lte => try self.airCmp(inst, .lte),
17521837
1753 .arg => self.airArg(),1838 .arg => self.airArg(),
1754 .alloc => try self.airAlloc(inst),1839 .alloc => try self.airAlloc(inst),
...@@ -1944,64 +2029,83 @@ pub const DeclGen = struct {...@@ -1944,64 +2029,83 @@ pub const DeclGen = struct {
1944 .float, .bool => unreachable,2029 .float, .bool => unreachable,
1945 }2030 }
19462031
1947 // The operand type must be the same as the result type in SPIR-V.2032 // The operand type must be the same as the result type in SPIR-V, which
2033 // is the same as in Zig.
1948 const operand_ty_ref = try self.resolveType(operand_ty, .direct);2034 const operand_ty_ref = try self.resolveType(operand_ty, .direct);
1949 const operand_ty_id = self.typeId(operand_ty_ref);2035 const operand_ty_id = self.typeId(operand_ty_ref);
19502036
1951 const op_result_id = blk: {2037 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
1952 // Construct the SPIR-V result type.
1953 // It is almost the same as the zig one, except that the fields must be the same type
1954 // and they must be unsigned.
1955 const overflow_result_ty_ref = try self.spv.simpleStructType(&.{
1956 .{ .ty = operand_ty_ref, .name = "res" },
1957 .{ .ty = operand_ty_ref, .name = "ov" },
1958 });
1959 const result_id = self.spv.allocId();
1960 try self.func.body.emit(self.spv.gpa, .OpIAddCarry, .{
1961 .id_result_type = self.typeId(overflow_result_ty_ref),
1962 .id_result = result_id,
1963 .operand_1 = lhs,
1964 .operand_2 = rhs,
1965 });
1966 break :blk result_id;
1967 };
1968
1969 // Now convert the SPIR-V flavor result into a Zig-flavor result.
1970 // First, extract the two fields.
1971 const unsigned_result = try self.extractField(operand_ty, op_result_id, 0);
1972 const overflow = try self.extractField(operand_ty, op_result_id, 1);
1973
1974 // We need to convert the results to the types that Zig expects here.
1975 // The `result` is the same type except unsigned, so we can just bitcast that.
1976 // TODO: This can be removed in Kernels as there are only unsigned ints. Maybe for
1977 // shaders as well?
1978 const result = try self.bitcast(operand_ty_id, unsigned_result);
1979
1980 // The overflow needs to be converted into whatever is used to represent it in Zig.
1981 const casted_overflow = blk: {
1982 const ov_ty = result_ty.tupleFields().types[1];
1983 const ov_ty_id = try self.resolveTypeId(ov_ty);
1984 const result_id = self.spv.allocId();
1985 try self.func.body.emit(self.spv.gpa, .OpUConvert, .{
1986 .id_result_type = ov_ty_id,
1987 .id_result = result_id,
1988 .unsigned_value = overflow,
1989 });
1990 break :blk result_id;
1991 };
19922038
1993 // TODO: If copying this function for borrow, make sure to convert -1 to 1 as appropriate.2039 const ov_ty = result_ty.tupleFields().types[1];
2040 // Note: result is stored in a struct, so indirect representation.
2041 const ov_ty_ref = try self.resolveType(ov_ty, .indirect);
19942042
1995 // Finally, construct the Zig type.2043 // TODO: Operations other than addition.
1996 // Layout is result, overflow.2044 const value_id = self.spv.allocId();
1997 const result_id = self.spv.allocId();2045 try self.func.body.emit(self.spv.gpa, .OpIAdd, .{
1998 const constituents = [_]IdRef{ result, casted_overflow };
1999 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
2000 .id_result_type = operand_ty_id,2046 .id_result_type = operand_ty_id,
2001 .id_result = result_id,2047 .id_result = value_id,
2002 .constituents = &constituents,2048 .operand_1 = lhs,
2049 .operand_2 = rhs,
2050 });
2051
2052 const overflowed_id = switch (info.signedness) {
2053 .unsigned => blk: {
2054 // Overflow happened if the result is smaller than either of the operands. It doesn't matter which.
2055 const overflowed_id = self.spv.allocId();
2056 try self.func.body.emit(self.spv.gpa, .OpULessThan, .{
2057 .id_result_type = self.typeId(bool_ty_ref),
2058 .id_result = overflowed_id,
2059 .operand_1 = value_id,
2060 .operand_2 = lhs,
2061 });
2062 break :blk overflowed_id;
2063 },
2064 .signed => blk: {
2065 // Overflow happened if:
2066 // - rhs is negative and value > lhs
2067 // - rhs is positive and value < lhs
2068 // This can be shortened to:
2069 // (rhs < 0 && value > lhs) || (rhs >= 0 && value <= lhs)
2070 // = (rhs < 0) == (value > lhs)
2071 // Note that signed overflow is also wrapping in spir-v.
2072
2073 const rhs_lt_zero_id = self.spv.allocId();
2074 const zero_id = try self.constInt(operand_ty_ref, 0);
2075 try self.func.body.emit(self.spv.gpa, .OpSLessThan, .{
2076 .id_result_type = self.typeId(bool_ty_ref),
2077 .id_result = rhs_lt_zero_id,
2078 .operand_1 = rhs,
2079 .operand_2 = zero_id,
2080 });
2081
2082 const value_gt_lhs_id = self.spv.allocId();
2083 try self.func.body.emit(self.spv.gpa, .OpSGreaterThan, .{
2084 .id_result_type = self.typeId(bool_ty_ref),
2085 .id_result = value_gt_lhs_id,
2086 .operand_1 = value_id,
2087 .operand_2 = lhs,
2088 });
2089
2090 const overflowed_id = self.spv.allocId();
2091 try self.func.body.emit(self.spv.gpa, .OpLogicalEqual, .{
2092 .id_result_type = self.typeId(bool_ty_ref),
2093 .id_result = overflowed_id,
2094 .operand_1 = rhs_lt_zero_id,
2095 .operand_2 = value_gt_lhs_id,
2096 });
2097 break :blk overflowed_id;
2098 },
2099 };
2100
2101 // Construct the struct that Zig wants as result.
2102 // The value should already be the correct type.
2103 const ov_id = try self.boolToInt(ov_ty_ref, overflowed_id);
2104 const result_ty_ref = try self.resolveType(result_ty, .direct);
2105 return try self.constructStruct(result_ty_ref, &.{
2106 value_id,
2107 ov_id,
2003 });2108 });
2004 return result_id;
2005 }2109 }
20062110
2007 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2111 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -2040,85 +2144,262 @@ pub const DeclGen = struct {...@@ -2040,85 +2144,262 @@ pub const DeclGen = struct {
2040 return result_id;2144 return result_id;
2041 }2145 }
20422146
2043 fn airCmp(self: *DeclGen, inst: Air.Inst.Index, comptime fop: Opcode, comptime sop: Opcode, comptime uop: Opcode) !?IdRef {2147 /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective
2044 if (self.liveness.isUnused(inst)) return null;2148 /// difference lies in whether the resulting type of the first dereference will be the
2045 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2149 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain
2046 var lhs_id = try self.resolve(bin_op.lhs);2150 /// is the latter and PtrAccessChain is the former.
2047 var rhs_id = try self.resolve(bin_op.rhs);2151 fn accessChain(
2152 self: *DeclGen,
2153 result_ty_ref: SpvType.Ref,
2154 base: IdRef,
2155 indexes: []const IdRef,
2156 ) !IdRef {
2048 const result_id = self.spv.allocId();2157 const result_id = self.spv.allocId();
2049 const result_type_id = try self.resolveTypeId(Type.bool);2158 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2050 const op_ty = self.air.typeOf(bin_op.lhs);2159 .id_result_type = self.typeId(result_ty_ref),
2051 assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.module));2160 .id_result = result_id,
2161 .base = base,
2162 .indexes = indexes,
2163 });
2164 return result_id;
2165 }
20522166
2053 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,2167 fn ptrAccessChain(
2054 // but int and float versions of operations require different opcodes.2168 self: *DeclGen,
2055 const info = try self.arithmeticTypeInfo(op_ty);2169 result_ty_ref: SpvType.Ref,
2170 base: IdRef,
2171 element: IdRef,
2172 indexes: []const IdRef,
2173 ) !IdRef {
2174 const result_id = self.spv.allocId();
2175 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2176 .id_result_type = self.typeId(result_ty_ref),
2177 .id_result = result_id,
2178 .base = base,
2179 .element = element,
2180 .indexes = indexes,
2181 });
2182 return result_id;
2183 }
20562184
2057 const opcode_index: usize = switch (info.class) {2185 fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {
2058 .composite_integer => {2186 const result_ty_ref = try self.resolveType(result_ty, .direct);
2059 return self.todo("binary operations for composite integers", .{});2187
2188 switch (ptr_ty.ptrSize()) {
2189 .One => {
2190 // Pointer to array
2191 // TODO: Is this correct?
2192 return try self.accessChain(result_ty_ref, ptr_id, &.{offset_id});
2060 },2193 },
2061 .float => 0,2194 .C, .Many => {
2062 .bool => 1,2195 return try self.ptrAccessChain(result_ty_ref, ptr_id, offset_id, &.{});
2063 .strange_integer => blk: {
2064 const op_ty_ref = try self.resolveType(op_ty, .direct);
2065 lhs_id = try self.maskStrangeInt(op_ty_ref, lhs_id, info.bits);
2066 rhs_id = try self.maskStrangeInt(op_ty_ref, rhs_id, info.bits);
2067 break :blk switch (info.signedness) {
2068 .signed => @as(usize, 1),
2069 .unsigned => @as(usize, 2),
2070 };
2071 },2196 },
2072 .integer => switch (info.signedness) {2197 .Slice => {
2073 .signed => @as(usize, 1),2198 // TODO: This is probably incorrect. A slice should be returned here, though this is what llvm does.
2074 .unsigned => @as(usize, 2),2199 const slice_ptr_id = try self.extractField(result_ty, ptr_id, 0);
2200 return try self.ptrAccessChain(result_ty_ref, slice_ptr_id, offset_id, &.{});
2075 },2201 },
2076 };2202 }
2203 }
20772204
2078 const operands = .{2205 fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2079 .id_result_type = result_type_id,2206 if (self.liveness.isUnused(inst)) return null;
2080 .id_result = result_id,2207 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2081 .operand_1 = lhs_id,2208 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2082 .operand_2 = rhs_id,2209 const ptr_id = try self.resolve(bin_op.lhs);
2083 };2210 const offset_id = try self.resolve(bin_op.rhs);
2211 const ptr_ty = self.air.typeOf(bin_op.lhs);
2212 const result_ty = self.air.typeOfIndex(inst);
20842213
2085 switch (opcode_index) {2214 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
2086 0 => try self.func.body.emit(self.spv.gpa, fop, operands),2215 }
2087 1 => try self.func.body.emit(self.spv.gpa, sop, operands),2216
2088 2 => try self.func.body.emit(self.spv.gpa, uop, operands),2217 fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2089 else => unreachable,2218 if (self.liveness.isUnused(inst)) return null;
2090 }2219 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2220 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2221 const ptr_id = try self.resolve(bin_op.lhs);
2222 const ptr_ty = self.air.typeOf(bin_op.lhs);
2223 const offset_id = try self.resolve(bin_op.rhs);
2224 const offset_ty = self.air.typeOf(bin_op.rhs);
2225 const offset_ty_ref = try self.resolveType(offset_ty, .direct);
2226 const result_ty = self.air.typeOfIndex(inst);
2227
2228 const negative_offset_id = self.spv.allocId();
2229 try self.func.body.emit(self.spv.gpa, .OpSNegate, .{
2230 .id_result_type = self.typeId(offset_ty_ref),
2231 .id_result = negative_offset_id,
2232 .operand = offset_id,
2233 });
2234 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, negative_offset_id);
2235 }
2236
2237 fn cmp(
2238 self: *DeclGen,
2239 comptime op: std.math.CompareOperator,
2240 bool_ty_id: IdRef,
2241 ty: Type,
2242 lhs_id: IdRef,
2243 rhs_id: IdRef,
2244 ) !IdRef {
2245 var cmp_lhs_id = lhs_id;
2246 var cmp_rhs_id = rhs_id;
2247 const opcode: Opcode = opcode: {
2248 var int_buffer: Type.Payload.Bits = undefined;
2249 const op_ty = switch (ty.zigTypeTag()) {
2250 .Int, .Bool, .Float => ty,
2251 .Enum => ty.intTagType(&int_buffer),
2252 .ErrorSet => Type.u16,
2253 .Pointer => blk: {
2254 // Note that while SPIR-V offers OpPtrEqual and OpPtrNotEqual, they are
2255 // currently not implemented in the SPIR-V LLVM translator. Thus, we emit these using
2256 // OpConvertPtrToU...
2257 cmp_lhs_id = self.spv.allocId();
2258 cmp_rhs_id = self.spv.allocId();
2259
2260 const usize_ty_id = self.typeId(try self.sizeType());
2261
2262 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
2263 .id_result_type = usize_ty_id,
2264 .id_result = cmp_lhs_id,
2265 .pointer = lhs_id,
2266 });
2267
2268 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
2269 .id_result_type = usize_ty_id,
2270 .id_result = cmp_rhs_id,
2271 .pointer = rhs_id,
2272 });
20912273
2274 break :blk Type.usize;
2275 },
2276 .Optional => unreachable, // TODO
2277 else => unreachable,
2278 };
2279
2280 const info = try self.arithmeticTypeInfo(op_ty);
2281 const signedness = switch (info.class) {
2282 .composite_integer => {
2283 return self.todo("binary operations for composite integers", .{});
2284 },
2285 .float => break :opcode switch (op) {
2286 .eq => .OpFOrdEqual,
2287 .neq => .OpFOrdNotEqual,
2288 .lt => .OpFOrdLessThan,
2289 .lte => .OpFOrdLessThanEqual,
2290 .gt => .OpFOrdGreaterThan,
2291 .gte => .OpFOrdGreaterThanEqual,
2292 },
2293 .bool => break :opcode switch (op) {
2294 .eq => .OpIEqual,
2295 .neq => .OpINotEqual,
2296 else => unreachable,
2297 },
2298 .strange_integer => sign: {
2299 const op_ty_ref = try self.resolveType(op_ty, .direct);
2300 // Mask operands before performing comparison.
2301 cmp_lhs_id = try self.maskStrangeInt(op_ty_ref, cmp_lhs_id, info.bits);
2302 cmp_rhs_id = try self.maskStrangeInt(op_ty_ref, cmp_rhs_id, info.bits);
2303 break :sign info.signedness;
2304 },
2305 .integer => info.signedness,
2306 };
2307
2308 break :opcode switch (signedness) {
2309 .unsigned => switch (op) {
2310 .eq => .OpIEqual,
2311 .neq => .OpINotEqual,
2312 .lt => .OpULessThan,
2313 .lte => .OpULessThanEqual,
2314 .gt => .OpUGreaterThan,
2315 .gte => .OpUGreaterThanEqual,
2316 },
2317 .signed => switch (op) {
2318 .eq => .OpIEqual,
2319 .neq => .OpINotEqual,
2320 .lt => .OpSLessThan,
2321 .lte => .OpSLessThanEqual,
2322 .gt => .OpSGreaterThan,
2323 .gte => .OpSGreaterThanEqual,
2324 },
2325 };
2326 };
2327
2328 const result_id = self.spv.allocId();
2329 try self.func.body.emitRaw(self.spv.gpa, opcode, 4);
2330 self.func.body.writeOperand(spec.IdResultType, bool_ty_id);
2331 self.func.body.writeOperand(spec.IdResult, result_id);
2332 self.func.body.writeOperand(spec.IdResultType, cmp_lhs_id);
2333 self.func.body.writeOperand(spec.IdResultType, cmp_rhs_id);
2092 return result_id;2334 return result_id;
2093 }2335 }
20942336
2095 fn bitcast(self: *DeclGen, target_type_id: IdResultType, value_id: IdRef) !IdRef {2337 fn airCmp(
2338 self: *DeclGen,
2339 inst: Air.Inst.Index,
2340 comptime op: std.math.CompareOperator,
2341 ) !?IdRef {
2342 if (self.liveness.isUnused(inst)) return null;
2343 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2344 const lhs_id = try self.resolve(bin_op.lhs);
2345 const rhs_id = try self.resolve(bin_op.rhs);
2346 const bool_ty_id = try self.resolveTypeId(Type.bool);
2347 const ty = self.air.typeOf(bin_op.lhs);
2348 assert(ty.eql(self.air.typeOf(bin_op.rhs), self.module));
2349
2350 return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);
2351 }
2352
2353 fn bitCast(
2354 self: *DeclGen,
2355 dst_ty: Type,
2356 src_ty: Type,
2357 src_id: IdRef,
2358 ) !IdRef {
2359 const dst_ty_ref = try self.resolveType(dst_ty, .direct);
2096 const result_id = self.spv.allocId();2360 const result_id = self.spv.allocId();
2097 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{2361
2098 .id_result_type = target_type_id,2362 // TODO: Some more cases are missing here
2099 .id_result = result_id,2363 // See fn bitCast in llvm.zig
2100 .operand = value_id,2364
2101 });2365 if (src_ty.zigTypeTag() == .Int and dst_ty.isPtrAtRuntime()) {
2366 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
2367 .id_result_type = self.typeId(dst_ty_ref),
2368 .id_result = result_id,
2369 .integer_value = src_id,
2370 });
2371 } else {
2372 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
2373 .id_result_type = self.typeId(dst_ty_ref),
2374 .id_result = result_id,
2375 .operand = src_id,
2376 });
2377 }
2102 return result_id;2378 return result_id;
2103 }2379 }
21042380
2105 fn airBitcast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2381 fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2106 if (self.liveness.isUnused(inst)) return null;2382 if (self.liveness.isUnused(inst)) return null;
2107 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2383 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2108 const operand_id = try self.resolve(ty_op.operand);2384 const operand_id = try self.resolve(ty_op.operand);
2109 const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));2385 const operand_ty = self.air.typeOf(ty_op.operand);
2110 return try self.bitcast(result_type_id, operand_id);2386 const result_ty = self.air.typeOfIndex(inst);
2387 return try self.bitCast(result_ty, operand_ty, operand_id);
2111 }2388 }
21122389
2113 fn airIntcast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2390 fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2114 if (self.liveness.isUnused(inst)) return null;2391 if (self.liveness.isUnused(inst)) return null;
21152392
2116 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2393 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2117 const operand_id = try self.resolve(ty_op.operand);2394 const operand_id = try self.resolve(ty_op.operand);
2118 const dest_ty = self.air.typeOfIndex(inst);2395 const dest_ty = self.air.typeOfIndex(inst);
2119 const dest_info = try self.arithmeticTypeInfo(dest_ty);
2120 const dest_ty_id = try self.resolveTypeId(dest_ty);2396 const dest_ty_id = try self.resolveTypeId(dest_ty);
21212397
2398 const target = self.getTarget();
2399 const dest_info = dest_ty.intInfo(target);
2400
2401 // TODO: Masking?
2402
2122 const result_id = self.spv.allocId();2403 const result_id = self.spv.allocId();
2123 switch (dest_info.signedness) {2404 switch (dest_info.signedness) {
2124 .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{2405 .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{
...@@ -2221,11 +2502,7 @@ pub const DeclGen = struct {...@@ -2221,11 +2502,7 @@ pub const DeclGen = struct {
2221 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2502 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2222 const field_ty = self.air.typeOfIndex(inst);2503 const field_ty = self.air.typeOfIndex(inst);
2223 const operand_id = try self.resolve(ty_op.operand);2504 const operand_id = try self.resolve(ty_op.operand);
2224 return try self.extractField(2505 return try self.extractField(field_ty, operand_id, field);
2225 field_ty,
2226 operand_id,
2227 field,
2228 );
2229 }2506 }
22302507
2231 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2508 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -2233,30 +2510,14 @@ pub const DeclGen = struct {...@@ -2233,30 +2510,14 @@ pub const DeclGen = struct {
2233 const slice_ty = self.air.typeOf(bin_op.lhs);2510 const slice_ty = self.air.typeOf(bin_op.lhs);
2234 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;2511 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
22352512
2236 const slice = try self.resolve(bin_op.lhs);2513 const slice_id = try self.resolve(bin_op.lhs);
2237 const index = try self.resolve(bin_op.rhs);2514 const index_id = try self.resolve(bin_op.rhs);
2238
2239 const spv_ptr_ty = try self.resolveTypeId(self.air.typeOfIndex(inst));
22402515
2241 const slice_ptr = blk: {2516 const ptr_ty = self.air.typeOfIndex(inst);
2242 const result_id = self.spv.allocId();2517 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
2243 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
2244 .id_result_type = spv_ptr_ty,
2245 .id_result = result_id,
2246 .composite = slice,
2247 .indexes = &.{0},
2248 });
2249 break :blk result_id;
2250 };
22512518
2252 const result_id = self.spv.allocId();2519 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
2253 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{2520 return try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index_id, &.{});
2254 .id_result_type = spv_ptr_ty,
2255 .id_result = result_id,
2256 .base = slice_ptr,
2257 .element = index,
2258 });
2259 return result_id;
2260 }2521 }
22612522
2262 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2523 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -2264,61 +2525,64 @@ pub const DeclGen = struct {...@@ -2264,61 +2525,64 @@ pub const DeclGen = struct {
2264 const slice_ty = self.air.typeOf(bin_op.lhs);2525 const slice_ty = self.air.typeOf(bin_op.lhs);
2265 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;2526 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
22662527
2267 const slice = try self.resolve(bin_op.lhs);2528 const slice_id = try self.resolve(bin_op.lhs);
2268 const index = try self.resolve(bin_op.rhs);2529 const index_id = try self.resolve(bin_op.rhs);
22692530
2270 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;2531 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2271 const ptr_ty_id = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf));2532 const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf);
22722533 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
2273 const slice_ptr = blk: {
2274 const result_id = self.spv.allocId();
2275 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
2276 .id_result_type = ptr_ty_id,
2277 .id_result = result_id,
2278 .composite = slice,
2279 .indexes = &.{0},
2280 });
2281 break :blk result_id;
2282 };
2283
2284 const elem_ptr = blk: {
2285 const result_id = self.spv.allocId();
2286 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2287 .id_result_type = ptr_ty_id,
2288 .id_result = result_id,
2289 .base = slice_ptr,
2290 .element = index,
2291 });
2292 break :blk result_id;
2293 };
22942534
2535 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
2536 const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index_id, &.{});
2295 return try self.load(slice_ty, elem_ptr);2537 return try self.load(slice_ty, elem_ptr);
2296 }2538 }
22972539
2540 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
2541 // Construct new pointer type for the resulting pointer
2542 const elem_ty = ptr_ty.elemType2(); // use elemType() so that we get T for *[N]T.
2543 const elem_ty_ref = try self.resolveType(elem_ty, .direct);
2544 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()), 0);
2545 if (ptr_ty.isSinglePointer()) {
2546 // Pointer-to-array. In this case, the resulting pointer is not of the same type
2547 // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain.
2548 return try self.accessChain(elem_ptr_ty_ref, ptr_id, &.{index_id});
2549 } else {
2550 // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain
2551 return try self.ptrAccessChain(elem_ptr_ty_ref, ptr_id, index_id, &.{});
2552 }
2553 }
2554
2298 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2555 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2299 if (self.liveness.isUnused(inst)) return null;2556 if (self.liveness.isUnused(inst)) return null;
23002557
2301 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2558 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2302 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2559 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2303 const ptr_ty = self.air.typeOf(bin_op.lhs);2560 const ptr_ty = self.air.typeOf(bin_op.lhs);
2304 const result_ty = self.air.typeOfIndex(inst);
2305 const elem_ty = ptr_ty.childType();2561 const elem_ty = ptr_ty.childType();
2306 // TODO: Make this return a null ptr or something2562 // TODO: Make this return a null ptr or something
2307 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null;2563 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null;
23082564
2309 const result_type_id = try self.resolveTypeId(result_ty);2565 const ptr_id = try self.resolve(bin_op.lhs);
2310 const base_ptr = try self.resolve(bin_op.lhs);2566 const index_id = try self.resolve(bin_op.rhs);
2311 const rhs = try self.resolve(bin_op.rhs);2567 return try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
2568 }
23122569
2313 const result_id = self.spv.allocId();2570 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2314 const indexes = [_]IdRef{rhs};2571 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2315 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{2572 const ptr_ty = self.air.typeOf(bin_op.lhs);
2316 .id_result_type = result_type_id,2573 const ptr_id = try self.resolve(bin_op.lhs);
2317 .id_result = result_id,2574 const index_id = try self.resolve(bin_op.rhs);
2318 .base = base_ptr,2575
2319 .indexes = &indexes,2576 const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
2320 });2577
2321 return result_id;2578 // If we have a pointer-to-array, construct an element pointer to use with load()
2579 // If we pass ptr_ty directly, it will attempt to load the entire array rather than
2580 // just an element.
2581 var elem_ptr_info = ptr_ty.ptrInfo();
2582 elem_ptr_info.data.size = .One;
2583 const elem_ptr_ty = Type.initPayload(&elem_ptr_info.base);
2584
2585 return try self.load(elem_ptr_ty, elem_ptr_id);
2322 }2586 }
23232587
2324 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2588 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -2344,24 +2608,15 @@ pub const DeclGen = struct {...@@ -2344,24 +2608,15 @@ pub const DeclGen = struct {
2344 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2608 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
23452609
2346 const struct_ty = self.air.typeOf(struct_field.struct_operand);2610 const struct_ty = self.air.typeOf(struct_field.struct_operand);
2347 const object = try self.resolve(struct_field.struct_operand);2611 const object_id = try self.resolve(struct_field.struct_operand);
2348 const field_index = struct_field.field_index;2612 const field_index = struct_field.field_index;
2349 const field_ty = struct_ty.structFieldType(field_index);2613 const field_ty = struct_ty.structFieldType(field_index);
2350 const field_ty_id = try self.resolveTypeId(field_ty);
23512614
2352 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return null;2615 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return null;
23532616
2354 assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.2617 assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.
23552618
2356 const result_id = self.spv.allocId();2619 return try self.extractField(field_ty, object_id, field_index);
2357 const indexes = [_]u32{field_index};
2358 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
2359 .id_result_type = field_ty_id,
2360 .id_result = result_id,
2361 .composite = object,
2362 .indexes = &indexes,
2363 });
2364 return result_id;
2365 }2620 }
23662621
2367 fn structFieldPtr(2622 fn structFieldPtr(
...@@ -2379,16 +2634,8 @@ pub const DeclGen = struct {...@@ -2379,16 +2634,8 @@ pub const DeclGen = struct {
2379 const u32_ty_id = self.typeId(try self.intType(.unsigned, 32));2634 const u32_ty_id = self.typeId(try self.intType(.unsigned, 32));
2380 const field_index_id = self.spv.allocId();2635 const field_index_id = self.spv.allocId();
2381 try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index });2636 try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index });
2382 const result_id = self.spv.allocId();2637 const result_ty_ref = try self.resolveType(result_ptr_ty, .direct);
2383 const result_type_id = try self.resolveTypeId(result_ptr_ty);2638 return try self.accessChain(result_ty_ref, object_ptr, &.{field_index_id});
2384 const indexes = [_]IdRef{field_index_id};
2385 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2386 .id_result_type = result_type_id,
2387 .id_result = result_id,
2388 .base = object_ptr,
2389 .indexes = &indexes,
2390 });
2391 return result_id;
2392 },2639 },
2393 },2640 },
2394 else => unreachable, // TODO2641 else => unreachable, // TODO
...@@ -2422,76 +2669,45 @@ pub const DeclGen = struct {...@@ -2422,76 +2669,45 @@ pub const DeclGen = struct {
2422 return result_id;2669 return result_id;
2423 }2670 }
24242671
2425 fn variable(2672 // Allocate a function-local variable, with possible initializer.
2673 // This function returns a pointer to a variable of type `ty_ref`,
2674 // which is in the Generic address space. The variable is actually
2675 // placed in the Function address space.
2676 fn alloc(
2426 self: *DeclGen,2677 self: *DeclGen,
2427 comptime context: enum { function, global },2678 ty_ref: SpvType.Ref,
2428 result_id: IdRef,
2429 ptr_ty_ref: SpvType.Ref,
2430 initializer: ?IdRef,2679 initializer: ?IdRef,
2431 ) !void {2680 ) !IdRef {
2432 const storage_class = self.spv.typeRefType(ptr_ty_ref).payload(.pointer).storage_class;2681 const fn_ptr_ty_ref = try self.spv.ptrType(ty_ref, .Function, 0);
2433 const actual_storage_class = switch (storage_class) {2682 const general_ptr_ty_ref = try self.spv.ptrType(ty_ref, .Generic, 0);
2434 .Generic => switch (context) {
2435 .function => .Function,
2436 .global => .CrossWorkgroup,
2437 },
2438 else => storage_class,
2439 };
2440 const actual_ptr_ty_ref = switch (storage_class) {
2441 .Generic => try self.spv.changePtrStorageClass(ptr_ty_ref, actual_storage_class),
2442 else => ptr_ty_ref,
2443 };
2444 const alloc_result_id = switch (storage_class) {
2445 .Generic => self.spv.allocId(),
2446 else => result_id,
2447 };
24482683
2449 const section = switch (actual_storage_class) {2684 // SPIR-V requires that OpVariable declarations for locals go into the first block, so we are just going to
2450 .Generic => unreachable,2685 // directly generate them into func.prologue instead of the body.
2451 // SPIR-V requires that OpVariable declarations for locals go into the first block, so we are just going to2686 const var_id = self.spv.allocId();
2452 // directly generate them into func.prologue instead of the body.2687 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
2453 .Function => &self.func.prologue,2688 .id_result_type = self.typeId(fn_ptr_ty_ref),
2454 else => &self.spv.sections.types_globals_constants,2689 .id_result = var_id,
2455 };2690 .storage_class = .Function,
2456 try section.emit(self.spv.gpa, .OpVariable, .{
2457 .id_result_type = self.typeId(actual_ptr_ty_ref),
2458 .id_result = alloc_result_id,
2459 .storage_class = actual_storage_class,
2460 .initializer = initializer,2691 .initializer = initializer,
2461 });2692 });
24622693
2463 if (storage_class != .Generic) {2694 // Convert to a generic pointer
2464 return;2695 const result_id = self.spv.allocId();
2465 }2696 try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{
24662697 .id_result_type = self.typeId(general_ptr_ty_ref),
2467 // Now we need to convert the pointer.2698 .id_result = result_id,
2468 // If this is a function local, we need to perform the conversion at runtime. Otherwise, we can do2699 .pointer = var_id,
2469 // it ahead of time using OpSpecConstantOp.2700 });
2470 switch (actual_storage_class) {2701 return result_id;
2471 .Function => try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{
2472 .id_result_type = self.typeId(ptr_ty_ref),
2473 .id_result = result_id,
2474 .pointer = alloc_result_id,
2475 }),
2476 // TODO: Can we do without this cast or move it to runtime?
2477 else => {
2478 const const_ptr_id = try self.makePointerConstant(section, actual_ptr_ty_ref, alloc_result_id);
2479 try section.emitSpecConstantOp(self.spv.gpa, .OpPtrCastToGeneric, .{
2480 .id_result_type = self.typeId(ptr_ty_ref),
2481 .id_result = result_id,
2482 .pointer = const_ptr_id,
2483 });
2484 },
2485 }
2486 }2702 }
24872703
2488 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2704 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2489 if (self.liveness.isUnused(inst)) return null;2705 if (self.liveness.isUnused(inst)) return null;
2490 const ty = self.air.typeOfIndex(inst);2706 const ptr_ty = self.air.typeOfIndex(inst);
2491 const result_ty_ref = try self.resolveType(ty, .direct);2707 assert(ptr_ty.ptrAddressSpace() == .generic);
2492 const result_id = self.spv.allocId();2708 const child_ty = ptr_ty.childType();
2493 try self.variable(.function, result_id, result_ty_ref, null);2709 const child_ty_ref = try self.resolveType(child_ty, .indirect);
2494 return result_id;2710 return try self.alloc(child_ty_ref, null);
2495 }2711 }
24962712
2497 fn airArg(self: *DeclGen) IdRef {2713 fn airArg(self: *DeclGen) IdRef {
...@@ -2778,13 +2994,7 @@ pub const DeclGen = struct {...@@ -2778,13 +2994,7 @@ pub const DeclGen = struct {
2778 }2994 }
27792995
2780 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);2996 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
2781 const result_id = self.spv.allocId();2997 return try self.constructStruct(err_union_ty_ref, members.slice());
2782 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
2783 .id_result_type = self.typeId(err_union_ty_ref),
2784 .id_result = result_id,
2785 .constituents = members.slice(),
2786 });
2787 return result_id;
2788 }2998 }
27892999
2790 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {3000 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
...@@ -2884,14 +3094,8 @@ pub const DeclGen = struct {...@@ -2884,14 +3094,8 @@ pub const DeclGen = struct {
2884 }3094 }
28853095
2886 const optional_ty_ref = try self.resolveType(optional_ty, .direct);3096 const optional_ty_ref = try self.resolveType(optional_ty, .direct);
2887 const result_id = self.spv.allocId();
2888 const members = [_]IdRef{ operand_id, try self.constBool(true, .indirect) };3097 const members = [_]IdRef{ operand_id, try self.constBool(true, .indirect) };
2889 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{3098 return try self.constructStruct(optional_ty_ref, &members);
2890 .id_result_type = self.typeId(optional_ty_ref),
2891 .id_result = result_id,
2892 .constituents = &members,
2893 });
2894 return result_id;
2895 }3099 }
28963100
2897 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {3101 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
src/codegen/spirv/Module.zig+10
...@@ -774,6 +774,16 @@ pub fn changePtrStorageClass(self: *Module, ptr_ty_ref: Type.Ref, new_storage_cl...@@ -774,6 +774,16 @@ pub fn changePtrStorageClass(self: *Module, ptr_ty_ref: Type.Ref, new_storage_cl
774 return try self.resolveType(Type.initPayload(&payload.base));774 return try self.resolveType(Type.initPayload(&payload.base));
775}775}
776776
777pub fn constComposite(self: *Module, ty_ref: Type.Ref, members: []const IdRef) !IdRef {
778 const result_id = self.allocId();
779 try self.sections.types_globals_constants.emit(self.gpa, .OpSpecConstantComposite, .{
780 .id_result_type = self.typeId(ty_ref),
781 .id_result = result_id,
782 .constituents = members,
783 });
784 return result_id;
785}
786
777pub fn emitConstant(787pub fn emitConstant(
778 self: *Module,788 self: *Module,
779 ty_id: IdRef,789 ty_id: IdRef,
test/behavior/align.zig-6
...@@ -33,8 +33,6 @@ test "default alignment allows unspecified in type syntax" {...@@ -33,8 +33,6 @@ test "default alignment allows unspecified in type syntax" {
33}33}
3434
35test "implicitly decreasing pointer alignment" {35test "implicitly decreasing pointer alignment" {
36 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
37
38 const a: u32 align(4) = 3;36 const a: u32 align(4) = 3;
39 const b: u32 align(8) = 4;37 const b: u32 align(8) = 4;
40 try expect(addUnaligned(&a, &b) == 7);38 try expect(addUnaligned(&a, &b) == 7);
...@@ -45,8 +43,6 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {...@@ -45,8 +43,6 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
45}43}
4644
47test "@alignCast pointers" {45test "@alignCast pointers" {
48 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
49
50 var x: u32 align(4) = 1;46 var x: u32 align(4) = 1;
51 expectsOnly1(&x);47 expectsOnly1(&x);
52 try expect(x == 2);48 try expect(x == 2);
...@@ -219,8 +215,6 @@ test "alignment and size of structs with 128-bit fields" {...@@ -219,8 +215,6 @@ test "alignment and size of structs with 128-bit fields" {
219}215}
220216
221test "@ptrCast preserves alignment of bigger source" {217test "@ptrCast preserves alignment of bigger source" {
222 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
223
224 var x: u32 align(16) = 1234;218 var x: u32 align(16) = 1234;
225 const ptr = @ptrCast(*u8, &x);219 const ptr = @ptrCast(*u8, &x);
226 try expect(@TypeOf(ptr) == *align(16) u8);220 try expect(@TypeOf(ptr) == *align(16) u8);
test/behavior/array.zig-2
...@@ -347,7 +347,6 @@ test "read/write through global variable array of struct fields initialized via...@@ -347,7 +347,6 @@ test "read/write through global variable array of struct fields initialized via
347test "implicit cast single-item pointer" {347test "implicit cast single-item pointer" {
348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
349 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO349 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
351350
352 try testImplicitCastSingleItemPtr();351 try testImplicitCastSingleItemPtr();
353 comptime try testImplicitCastSingleItemPtr();352 comptime try testImplicitCastSingleItemPtr();
...@@ -542,7 +541,6 @@ test "sentinel element count towards the ABI size calculation" {...@@ -542,7 +541,6 @@ test "sentinel element count towards the ABI size calculation" {
542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO541 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
543 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO542 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
544 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO543 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
545 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
546544
547 const S = struct {545 const S = struct {
548 fn doTheTest() !void {546 fn doTheTest() !void {
test/behavior/asm.zig+4-1
...@@ -15,6 +15,10 @@ comptime {...@@ -15,6 +15,10 @@ comptime {
15 \\.type this_is_my_alias, @function;15 \\.type this_is_my_alias, @function;
16 \\.set this_is_my_alias, derp;16 \\.set this_is_my_alias, derp;
17 );17 );
18 } else if (builtin.zig_backend == .stage2_spirv64) {
19 asm (
20 \\%a = OpString "hello there"
21 );
18 }22 }
19}23}
2024
...@@ -24,7 +28,6 @@ test "module level assembly" {...@@ -24,7 +28,6 @@ test "module level assembly" {
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO28 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO29 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO30 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2831
29 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly32 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
3033
test/behavior/atomics.zig-2
...@@ -120,7 +120,6 @@ test "128-bit cmpxchg" {...@@ -120,7 +120,6 @@ test "128-bit cmpxchg" {
120 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO120 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
121 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO121 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
124123
125 try test_u128_cmpxchg();124 try test_u128_cmpxchg();
126 comptime try test_u128_cmpxchg();125 comptime try test_u128_cmpxchg();
...@@ -313,7 +312,6 @@ test "atomicrmw with 128-bit ints" {...@@ -313,7 +312,6 @@ test "atomicrmw with 128-bit ints" {
313312
314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
315 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO314 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
316 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
317315
318 // TODO "ld.lld: undefined symbol: __sync_lock_test_and_set_16" on -mcpu x86_64316 // TODO "ld.lld: undefined symbol: __sync_lock_test_and_set_16" on -mcpu x86_64
319 if (builtin.cpu.arch == .x86_64 and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;317 if (builtin.cpu.arch == .x86_64 and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
test/behavior/basic.zig+1-26
...@@ -82,8 +82,6 @@ test "type equality" {...@@ -82,8 +82,6 @@ test "type equality" {
82}82}
8383
84test "pointer dereferencing" {84test "pointer dereferencing" {
85 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
86
87 var x = @as(i32, 3);85 var x = @as(i32, 3);
88 const y = &x;86 const y = &x;
8987
...@@ -134,21 +132,18 @@ fn first4KeysOfHomeRow() []const u8 {...@@ -134,21 +132,18 @@ fn first4KeysOfHomeRow() []const u8 {
134132
135test "return string from function" {133test "return string from function" {
136 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO134 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
138135
139 try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));136 try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
140}137}
141138
142test "hex escape" {139test "hex escape" {
143 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
145141
146 try expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));142 try expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
147}143}
148144
149test "multiline string" {145test "multiline string" {
150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO146 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
151 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
152147
153 const s1 =148 const s1 =
154 \\one149 \\one
...@@ -161,7 +156,6 @@ test "multiline string" {...@@ -161,7 +156,6 @@ test "multiline string" {
161156
162test "multiline string comments at start" {157test "multiline string comments at start" {
163 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO158 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
165159
166 const s1 =160 const s1 =
167 //\\one161 //\\one
...@@ -174,7 +168,6 @@ test "multiline string comments at start" {...@@ -174,7 +168,6 @@ test "multiline string comments at start" {
174168
175test "multiline string comments at end" {169test "multiline string comments at end" {
176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
177 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
178171
179 const s1 =172 const s1 =
180 \\one173 \\one
...@@ -187,7 +180,6 @@ test "multiline string comments at end" {...@@ -187,7 +180,6 @@ test "multiline string comments at end" {
187180
188test "multiline string comments in middle" {181test "multiline string comments in middle" {
189 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO182 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
190 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
191183
192 const s1 =184 const s1 =
193 \\one185 \\one
...@@ -200,7 +192,6 @@ test "multiline string comments in middle" {...@@ -200,7 +192,6 @@ test "multiline string comments in middle" {
200192
201test "multiline string comments at multiple places" {193test "multiline string comments at multiple places" {
202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
204195
205 const s1 =196 const s1 =
206 \\one197 \\one
...@@ -214,14 +205,11 @@ test "multiline string comments at multiple places" {...@@ -214,14 +205,11 @@ test "multiline string comments at multiple places" {
214}205}
215206
216test "string concatenation simple" {207test "string concatenation simple" {
217 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
218
219 try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));208 try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
220}209}
221210
222test "array mult operator" {211test "array mult operator" {
223 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
224 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
225213
226 try expect(mem.eql(u8, "ab" ** 5, "ababababab"));214 try expect(mem.eql(u8, "ab" ** 5, "ababababab"));
227}215}
...@@ -303,8 +291,6 @@ test "function closes over local const" {...@@ -303,8 +291,6 @@ test "function closes over local const" {
303}291}
304292
305test "volatile load and store" {293test "volatile load and store" {
306 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
307
308 var number: i32 = 1234;294 var number: i32 = 1234;
309 const ptr = @as(*volatile i32, &number);295 const ptr = @as(*volatile i32, &number);
310 ptr.* += 1;296 ptr.* += 1;
...@@ -387,7 +373,6 @@ test "take address of parameter" {...@@ -387,7 +373,6 @@ test "take address of parameter" {
387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;373 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;374 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
389 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO375 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
390 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
391376
392 try testTakeAddressOfParameter(12.34);377 try testTakeAddressOfParameter(12.34);
393}378}
...@@ -477,7 +462,6 @@ fn nine() u8 {...@@ -477,7 +462,6 @@ fn nine() u8 {
477test "struct inside function" {462test "struct inside function" {
478 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;463 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
479 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO464 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
480 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
481465
482 try testStructInFn();466 try testStructInFn();
483 comptime try testStructInFn();467 comptime try testStructInFn();
...@@ -599,7 +583,7 @@ test "comptime cast fn to ptr" {...@@ -599,7 +583,7 @@ test "comptime cast fn to ptr" {
599}583}
600584
601test "equality compare fn ptrs" {585test "equality compare fn ptrs" {
602 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;586 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // Test passes but should not
603587
604 var a = &emptyFn;588 var a = &emptyFn;
605 try expect(a == a);589 try expect(a == a);
...@@ -690,8 +674,6 @@ test "explicit cast optional pointers" {...@@ -690,8 +674,6 @@ test "explicit cast optional pointers" {
690}674}
691675
692test "pointer comparison" {676test "pointer comparison" {
693 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
694
695 const a = @as([]const u8, "a");677 const a = @as([]const u8, "a");
696 const b = &a;678 const b = &a;
697 try expect(ptrEql(b, b));679 try expect(ptrEql(b, b));
...@@ -704,7 +686,6 @@ test "string concatenation" {...@@ -704,7 +686,6 @@ test "string concatenation" {
704 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;686 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
705 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;687 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
706 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO688 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
707 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
708689
709 const a = "OK" ++ " IT " ++ "WORKED";690 const a = "OK" ++ " IT " ++ "WORKED";
710 const b = "OK IT WORKED";691 const b = "OK IT WORKED";
...@@ -770,7 +751,6 @@ fn maybe(x: bool) anyerror!?u32 {...@@ -770,7 +751,6 @@ fn maybe(x: bool) anyerror!?u32 {
770test "auto created variables have correct alignment" {751test "auto created variables have correct alignment" {
771 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO752 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
772 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO753 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
773 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
774754
775 const S = struct {755 const S = struct {
776 fn foo(str: [*]const u8) u32 {756 fn foo(str: [*]const u8) u32 {
...@@ -892,8 +872,6 @@ test "catch in block has correct result location" {...@@ -892,8 +872,6 @@ test "catch in block has correct result location" {
892}872}
893873
894test "labeled block with runtime branch forwards its result location type to break statements" {874test "labeled block with runtime branch forwards its result location type to break statements" {
895 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
896
897 const E = enum { a, b };875 const E = enum { a, b };
898 var a = false;876 var a = false;
899 const e: E = blk: {877 const e: E = blk: {
...@@ -1062,8 +1040,6 @@ test "switch inside @as gets correct type" {...@@ -1062,8 +1040,6 @@ test "switch inside @as gets correct type" {
1062}1040}
10631041
1064test "inline call of function with a switch inside the return statement" {1042test "inline call of function with a switch inside the return statement" {
1065 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1066
1067 const S = struct {1043 const S = struct {
1068 inline fn foo(x: anytype) @TypeOf(x) {1044 inline fn foo(x: anytype) @TypeOf(x) {
1069 return switch (x) {1045 return switch (x) {
...@@ -1147,7 +1123,6 @@ test "returning an opaque type from a function" {...@@ -1147,7 +1123,6 @@ test "returning an opaque type from a function" {
1147test "orelse coercion as function argument" {1123test "orelse coercion as function argument" {
1148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1124 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1125 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1150 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11511126
1152 const Loc = struct { start: i32 = -1 };1127 const Loc = struct { start: i32 = -1 };
1153 const Container = struct {1128 const Container = struct {
test/behavior/bitcast.zig-1
...@@ -9,7 +9,6 @@ const native_endian = builtin.target.cpu.arch.endian();...@@ -9,7 +9,6 @@ const native_endian = builtin.target.cpu.arch.endian();
99
10test "@bitCast iX -> uX (32, 64)" {10test "@bitCast iX -> uX (32, 64)" {
11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1312
14 const bit_values = [_]usize{ 32, 64 };13 const bit_values = [_]usize{ 32, 64 };
1514
test/behavior/bitreverse.zig-1
...@@ -5,7 +5,6 @@ const minInt = std.math.minInt;...@@ -5,7 +5,6 @@ const minInt = std.math.minInt;
55
6test "@bitReverse large exotic integer" {6test "@bitReverse large exotic integer" {
7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
98
10 try expect(@bitReverse(@as(u95, 0x123456789abcdef111213141)) == 0x4146424447bd9eac8f351624);9 try expect(@bitReverse(@as(u95, 0x123456789abcdef111213141)) == 0x4146424447bd9eac8f351624);
11}10}
test/behavior/call.zig-5
...@@ -109,7 +109,6 @@ test "result location of function call argument through runtime condition and st...@@ -109,7 +109,6 @@ test "result location of function call argument through runtime condition and st
109109
110test "function call with 40 arguments" {110test "function call with 40 arguments" {
111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
113112
114 const S = struct {113 const S = struct {
115 fn doTheTest(thirty_nine: i32) !void {114 fn doTheTest(thirty_nine: i32) !void {
...@@ -374,8 +373,6 @@ test "Enum constructed by @Type passed as generic argument" {...@@ -374,8 +373,6 @@ test "Enum constructed by @Type passed as generic argument" {
374}373}
375374
376test "generic function with generic function parameter" {375test "generic function with generic function parameter" {
377 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
378
379 const S = struct {376 const S = struct {
380 fn f(comptime a: fn (anytype) anyerror!void, b: anytype) anyerror!void {377 fn f(comptime a: fn (anytype) anyerror!void, b: anytype) anyerror!void {
381 try a(b);378 try a(b);
...@@ -388,8 +385,6 @@ test "generic function with generic function parameter" {...@@ -388,8 +385,6 @@ test "generic function with generic function parameter" {
388}385}
389386
390test "recursive inline call with comptime known argument" {387test "recursive inline call with comptime known argument" {
391 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
392
393 const S = struct {388 const S = struct {
394 inline fn foo(x: i32) i32 {389 inline fn foo(x: i32) i32 {
395 if (x <= 0) {390 if (x <= 0) {
test/behavior/cast.zig-3
...@@ -322,7 +322,6 @@ test "peer result null and comptime_int" {...@@ -322,7 +322,6 @@ test "peer result null and comptime_int" {
322test "*const ?[*]const T to [*c]const [*c]const T" {322test "*const ?[*]const T to [*c]const [*c]const T" {
323 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;323 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
324 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO324 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
325 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
326325
327 var array = [_]u8{ 'o', 'k' };326 var array = [_]u8{ 'o', 'k' };
328 const opt_array_ptr: ?[*]const u8 = &array;327 const opt_array_ptr: ?[*]const u8 = &array;
...@@ -366,7 +365,6 @@ test "return u8 coercing into ?u32 return type" {...@@ -366,7 +365,6 @@ test "return u8 coercing into ?u32 return type" {
366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;365 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
367 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;366 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
368 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
369 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
370368
371 const S = struct {369 const S = struct {
372 fn doTheTest() !void {370 fn doTheTest() !void {
...@@ -428,7 +426,6 @@ test "peer resolve array and const slice" {...@@ -428,7 +426,6 @@ test "peer resolve array and const slice" {
428 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO427 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO428 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
431 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
432429
433 try testPeerResolveArrayConstSlice(true);430 try testPeerResolveArrayConstSlice(true);
434 comptime try testPeerResolveArrayConstSlice(true);431 comptime try testPeerResolveArrayConstSlice(true);
test/behavior/decltest.zig-2
...@@ -5,7 +5,5 @@ pub fn the_add_function(a: u32, b: u32) u32 {...@@ -5,7 +5,5 @@ pub fn the_add_function(a: u32, b: u32) u32 {
5}5}
66
7test the_add_function {7test the_add_function {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9
10 if (the_add_function(1, 2) != 3) unreachable;8 if (the_add_function(1, 2) != 3) unreachable;
11}9}
test/behavior/defer.zig-3
...@@ -23,8 +23,6 @@ fn testBreakContInDefer(x: usize) void {...@@ -23,8 +23,6 @@ fn testBreakContInDefer(x: usize) void {
23}23}
2424
25test "defer and labeled break" {25test "defer and labeled break" {
26 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
27
28 var i = @as(usize, 0);26 var i = @as(usize, 0);
2927
30 blk: {28 blk: {
...@@ -58,7 +56,6 @@ test "return variable while defer expression in scope to modify it" {...@@ -58,7 +56,6 @@ test "return variable while defer expression in scope to modify it" {
58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;56 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;57 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO58 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6259
63 const S = struct {60 const S = struct {
64 fn doTheTest() !void {61 fn doTheTest() !void {
test/behavior/duplicated_test_names.zig-2
...@@ -15,7 +15,5 @@ comptime {...@@ -15,7 +15,5 @@ comptime {
15test "thingy" {}15test "thingy" {}
1616
17test thingy {17test thingy {
18 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19
20 if (thingy(1, 2) != 3) unreachable;18 if (thingy(1, 2) != 3) unreachable;
21}19}
test/behavior/enum.zig-1
...@@ -1045,7 +1045,6 @@ test "tag name with assigned enum values" {...@@ -1045,7 +1045,6 @@ test "tag name with assigned enum values" {
1045test "@tagName on enum literals" {1045test "@tagName on enum literals" {
1046 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1046 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1047 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1047 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1048 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10491048
1050 try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));1049 try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
1051 comptime try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));1050 comptime try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
test/behavior/error.zig-2
...@@ -16,14 +16,12 @@ fn expectError(expected_err: anyerror, observed_err_union: anytype) !void {...@@ -16,14 +16,12 @@ fn expectError(expected_err: anyerror, observed_err_union: anytype) !void {
16}16}
1717
18test "error values" {18test "error values" {
19 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
20 const a = @errorToInt(error.err1);19 const a = @errorToInt(error.err1);
21 const b = @errorToInt(error.err2);20 const b = @errorToInt(error.err2);
22 try expect(a != b);21 try expect(a != b);
23}22}
2423
25test "redefinition of error values allowed" {24test "redefinition of error values allowed" {
26 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
27 shouldBeNotEqual(error.AnError, error.SecondError);25 shouldBeNotEqual(error.AnError, error.SecondError);
28}26}
29fn shouldBeNotEqual(a: anyerror, b: anyerror) void {27fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
test/behavior/eval.zig-3
...@@ -23,7 +23,6 @@ test "static add one" {...@@ -23,7 +23,6 @@ test "static add one" {
23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2726
28 try expect(should_be_1235 == 1235);27 try expect(should_be_1235 == 1235);
29}28}
...@@ -48,8 +47,6 @@ test "inline variable gets result of const if" {...@@ -48,8 +47,6 @@ test "inline variable gets result of const if" {
48}47}
4948
50test "static function evaluation" {49test "static function evaluation" {
51 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
52
53 try expect(statically_added_number == 3);50 try expect(statically_added_number == 3);
54}51}
55const statically_added_number = staticAdd(1, 2);52const statically_added_number = staticAdd(1, 2);
test/behavior/floatop.zig-2
...@@ -506,7 +506,6 @@ test "@fabs" {...@@ -506,7 +506,6 @@ test "@fabs" {
506 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO506 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO508 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
510509
511 comptime try testFabs();510 comptime try testFabs();
512 try testFabs();511 try testFabs();
...@@ -621,7 +620,6 @@ test "@floor" {...@@ -621,7 +620,6 @@ test "@floor" {
621 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO620 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
622 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
623 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO622 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
625623
626 comptime try testFloor();624 comptime try testFloor();
627 try testFloor();625 try testFloor();
test/behavior/fn.zig-4
...@@ -5,8 +5,6 @@ const expect = testing.expect;...@@ -5,8 +5,6 @@ const expect = testing.expect;
5const expectEqual = testing.expectEqual;5const expectEqual = testing.expectEqual;
66
7test "params" {7test "params" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9
10 try expect(testParamsAdd(22, 11) == 33);8 try expect(testParamsAdd(22, 11) == 33);
11}9}
12fn testParamsAdd(a: i32, b: i32) i32 {10fn testParamsAdd(a: i32, b: i32) i32 {
...@@ -14,8 +12,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {...@@ -14,8 +12,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {
14}12}
1513
16test "local variables" {14test "local variables" {
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18
19 testLocVars(2);15 testLocVars(2);
20}16}
21fn testLocVars(b: i32) void {17fn testLocVars(b: i32) void {
test/behavior/fn_delegation.zig-1
...@@ -34,7 +34,6 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 {...@@ -34,7 +34,6 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 {
34test "fn delegation" {34test "fn delegation" {
35 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO35 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO36 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3837
39 const foo = Foo{};38 const foo = Foo{};
40 try expect(foo.one() == 11);39 try expect(foo.one() == 11);
test/behavior/fn_in_struct_in_comptime.zig-2
...@@ -13,8 +13,6 @@ fn get_foo() fn (*u8) usize {...@@ -13,8 +13,6 @@ fn get_foo() fn (*u8) usize {
13}13}
1414
15test "define a function in an anonymous struct in comptime" {15test "define a function in an anonymous struct in comptime" {
16 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
17
18 const foo = get_foo();16 const foo = get_foo();
19 try expect(foo(@intToPtr(*u8, 12345)) == 12345);17 try expect(foo(@intToPtr(*u8, 12345)) == 12345);
20}18}
test/behavior/for.zig-4
...@@ -22,8 +22,6 @@ test "continue in for loop" {...@@ -22,8 +22,6 @@ test "continue in for loop" {
22}22}
2323
24test "break from outer for loop" {24test "break from outer for loop" {
25 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
26
27 try testBreakOuter();25 try testBreakOuter();
28 comptime try testBreakOuter();26 comptime try testBreakOuter();
29}27}
...@@ -41,8 +39,6 @@ fn testBreakOuter() !void {...@@ -41,8 +39,6 @@ fn testBreakOuter() !void {
41}39}
4240
43test "continue outer for loop" {41test "continue outer for loop" {
44 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
45
46 try testContinueOuter();42 try testContinueOuter();
47 comptime try testContinueOuter();43 comptime try testContinueOuter();
48}44}
test/behavior/generics.zig-3
...@@ -5,8 +5,6 @@ const expect = testing.expect;...@@ -5,8 +5,6 @@ const expect = testing.expect;
5const expectEqual = testing.expectEqual;5const expectEqual = testing.expectEqual;
66
7test "one param, explicit comptime" {7test "one param, explicit comptime" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9
10 var x: usize = 0;8 var x: usize = 0;
11 x += checkSize(i32);9 x += checkSize(i32);
12 x += checkSize(bool);10 x += checkSize(bool);
...@@ -21,7 +19,6 @@ fn checkSize(comptime T: type) usize {...@@ -21,7 +19,6 @@ fn checkSize(comptime T: type) usize {
21test "simple generic fn" {19test "simple generic fn" {
22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO21 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2522
26 try expect(max(i32, 3, -1) == 3);23 try expect(max(i32, 3, -1) == 3);
27 try expect(max(u8, 1, 100) == 100);24 try expect(max(u8, 1, 100) == 100);
test/behavior/if.zig-2
...@@ -71,8 +71,6 @@ test "labeled break inside comptime if inside runtime if" {...@@ -71,8 +71,6 @@ test "labeled break inside comptime if inside runtime if" {
71}71}
7272
73test "const result loc, runtime if cond, else unreachable" {73test "const result loc, runtime if cond, else unreachable" {
74 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
75
76 const Num = enum { One, Two };74 const Num = enum { One, Two };
7775
78 var t = true;76 var t = true;
test/behavior/inttoptr.zig-1
...@@ -14,7 +14,6 @@ test "mutate through ptr initialized with constant intToPtr value" {...@@ -14,7 +14,6 @@ test "mutate through ptr initialized with constant intToPtr value" {
14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1817
19 forceCompilerAnalyzeBranchHardCodedPtrDereference(false);18 forceCompilerAnalyzeBranchHardCodedPtrDereference(false);
20}19}
test/behavior/math.zig-2
...@@ -208,7 +208,6 @@ test "float equality" {...@@ -208,7 +208,6 @@ test "float equality" {
208 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO208 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
209 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO209 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
210 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO210 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
211 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
212211
213 const x: f64 = 0.012;212 const x: f64 = 0.012;
214 const y: f64 = x + 1.0;213 const y: f64 = x + 1.0;
...@@ -684,7 +683,6 @@ test "@addWithOverflow" {...@@ -684,7 +683,6 @@ test "@addWithOverflow" {
684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO683 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
685 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO684 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
686 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
687 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
688686
689 {687 {
690 var a: u8 = 250;688 var a: u8 = 250;
test/behavior/maximum_minimum.zig-2
...@@ -129,8 +129,6 @@ test "@min/max for floats" {...@@ -129,8 +129,6 @@ test "@min/max for floats" {
129}129}
130130
131test "@min/@max on lazy values" {131test "@min/@max on lazy values" {
132 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
133
134 const A = extern struct { u8_4: [4]u8 };132 const A = extern struct { u8_4: [4]u8 };
135 const B = extern struct { u8_16: [16]u8 };133 const B = extern struct { u8_16: [16]u8 };
136 const size = @max(@sizeOf(A), @sizeOf(B));134 const size = @max(@sizeOf(A), @sizeOf(B));
test/behavior/memcpy.zig+11-9
...@@ -67,14 +67,16 @@ fn testMemcpyDestManyPtr() !void {...@@ -67,14 +67,16 @@ fn testMemcpyDestManyPtr() !void {
67}67}
6868
69comptime {69comptime {
70 const S = struct {70 if (builtin.zig_backend != .stage2_spirv64) {
71 buffer: [8]u8 = undefined,71 const S = struct {
72 fn set(self: *@This(), items: []const u8) void {72 buffer: [8]u8 = undefined,
73 @memcpy(self.buffer[0..items.len], items);73 fn set(self: *@This(), items: []const u8) void {
74 }74 @memcpy(self.buffer[0..items.len], items);
75 };75 }
76 };
7677
77 var s = S{};78 var s = S{};
78 s.set("hello");79 s.set("hello");
79 if (!std.mem.eql(u8, s.buffer[0..5], "hello")) @compileError("bad");80 if (!std.mem.eql(u8, s.buffer[0..5], "hello")) @compileError("bad");
81 }
80}82}
test/behavior/optional.zig-2
...@@ -8,7 +8,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;...@@ -8,7 +8,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;
8test "passing an optional integer as a parameter" {8test "passing an optional integer as a parameter" {
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1211
13 const S = struct {12 const S = struct {
14 fn entry() bool {13 fn entry() bool {
...@@ -422,7 +421,6 @@ test "optional of noreturn used with orelse" {...@@ -422,7 +421,6 @@ test "optional of noreturn used with orelse" {
422}421}
423422
424test "orelse on C pointer" {423test "orelse on C pointer" {
425 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
426424
427 // TODO https://github.com/ziglang/zig/issues/6597425 // TODO https://github.com/ziglang/zig/issues/6597
428 const foo: [*c]const u8 = "hey";426 const foo: [*c]const u8 = "hey";
test/behavior/packed-struct.zig-2
...@@ -7,7 +7,6 @@ const native_endian = builtin.cpu.arch.endian();...@@ -7,7 +7,6 @@ const native_endian = builtin.cpu.arch.endian();
77
8test "flags in packed structs" {8test "flags in packed structs" {
9 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1110
12 const Flags1 = packed struct {11 const Flags1 = packed struct {
13 // first 8 bits12 // first 8 bits
...@@ -94,7 +93,6 @@ test "flags in packed structs" {...@@ -94,7 +93,6 @@ test "flags in packed structs" {
9493
95test "consistent size of packed structs" {94test "consistent size of packed structs" {
96 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO95 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9896
99 const TxData1 = packed struct { data: u8, _23: u23, full: bool = false };97 const TxData1 = packed struct { data: u8, _23: u23, full: bool = false };
100 const TxData2 = packed struct { data: u9, _22: u22, full: bool = false };98 const TxData2 = packed struct { data: u9, _22: u22, full: bool = false };
test/behavior/pointers.zig-6
...@@ -5,7 +5,6 @@ const expect = testing.expect;...@@ -5,7 +5,6 @@ const expect = testing.expect;
5const expectError = testing.expectError;5const expectError = testing.expectError;
66
7test "dereference pointer" {7test "dereference pointer" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9 comptime try testDerefPtr();8 comptime try testDerefPtr();
10 try testDerefPtr();9 try testDerefPtr();
11}10}
...@@ -20,7 +19,6 @@ fn testDerefPtr() !void {...@@ -20,7 +19,6 @@ fn testDerefPtr() !void {
20test "pointer arithmetic" {19test "pointer arithmetic" {
21 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO21 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2422
25 var ptr: [*]const u8 = "abcd";23 var ptr: [*]const u8 = "abcd";
2624
...@@ -53,7 +51,6 @@ fn PtrOf(comptime T: type) type {...@@ -53,7 +51,6 @@ fn PtrOf(comptime T: type) type {
5351
54test "implicit cast single item pointer to C pointer and back" {52test "implicit cast single item pointer to C pointer and back" {
55 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO53 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5754
58 var y: u8 = 11;55 var y: u8 = 11;
59 var x: [*c]u8 = &y;56 var x: [*c]u8 = &y;
...@@ -70,7 +67,6 @@ test "initialize const optional C pointer to null" {...@@ -70,7 +67,6 @@ test "initialize const optional C pointer to null" {
7067
71test "assigning integer to C pointer" {68test "assigning integer to C pointer" {
72 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7470
75 var x: i32 = 0;71 var x: i32 = 0;
76 var y: i32 = 1;72 var y: i32 = 1;
...@@ -87,7 +83,6 @@ test "assigning integer to C pointer" {...@@ -87,7 +83,6 @@ test "assigning integer to C pointer" {
8783
88test "C pointer comparison and arithmetic" {84test "C pointer comparison and arithmetic" {
89 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO85 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
90 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9186
92 const S = struct {87 const S = struct {
93 fn doTheTest() !void {88 fn doTheTest() !void {
...@@ -304,7 +299,6 @@ test "null terminated pointer" {...@@ -304,7 +299,6 @@ test "null terminated pointer" {
304test "allow any sentinel" {299test "allow any sentinel" {
305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;300 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO301 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
308302
309 const S = struct {303 const S = struct {
310 fn doTheTest() !void {304 fn doTheTest() !void {
test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig-1
...@@ -8,7 +8,6 @@ test "reference a variable in an if after an if in the 2nd switch prong" {...@@ -8,7 +8,6 @@ test "reference a variable in an if after an if in the 2nd switch prong" {
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1211
13 try foo(true, Num.Two, false, "aoeu");12 try foo(true, Num.Two, false, "aoeu");
14 try expect(!ok);13 try expect(!ok);
test/behavior/reflection.zig-1
...@@ -28,7 +28,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 {...@@ -28,7 +28,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 {
28test "reflection: @field" {28test "reflection: @field" {
29 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;29 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
30 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO30 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
31 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3231
33 var f = Foo{32 var f = Foo{
34 .one = 42,33 .one = 42,
test/behavior/sizeof_and_typeof.zig-3
...@@ -140,8 +140,6 @@ test "@sizeOf(T) == 0 doesn't force resolving struct size" {...@@ -140,8 +140,6 @@ test "@sizeOf(T) == 0 doesn't force resolving struct size" {
140}140}
141141
142test "@TypeOf() has no runtime side effects" {142test "@TypeOf() has no runtime side effects" {
143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
144
145 const S = struct {143 const S = struct {
146 fn foo(comptime T: type, ptr: *T) T {144 fn foo(comptime T: type, ptr: *T) T {
147 ptr.* += 1;145 ptr.* += 1;
...@@ -156,7 +154,6 @@ test "@TypeOf() has no runtime side effects" {...@@ -156,7 +154,6 @@ test "@TypeOf() has no runtime side effects" {
156154
157test "branching logic inside @TypeOf" {155test "branching logic inside @TypeOf" {
158 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
159 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
160157
161 const S = struct {158 const S = struct {
162 var data: i32 = 0;159 var data: i32 = 0;
test/behavior/slice.zig-3
...@@ -200,8 +200,6 @@ test "slicing pointer by length" {...@@ -200,8 +200,6 @@ test "slicing pointer by length" {
200const x = @intToPtr([*]i32, 0x1000)[0..0x500];200const x = @intToPtr([*]i32, 0x1000)[0..0x500];
201const y = x[0x100..];201const y = x[0x100..];
202test "compile time slice of pointer to hard coded address" {202test "compile time slice of pointer to hard coded address" {
203 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
204
205 try expect(@ptrToInt(x) == 0x1000);203 try expect(@ptrToInt(x) == 0x1000);
206 try expect(x.len == 0x500);204 try expect(x.len == 0x500);
207205
...@@ -673,7 +671,6 @@ test "array mult of slice gives ptr to array" {...@@ -673,7 +671,6 @@ test "array mult of slice gives ptr to array" {
673671
674test "slice bounds in comptime concatenation" {672test "slice bounds in comptime concatenation" {
675 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO673 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
676 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
677674
678 const bs = comptime blk: {675 const bs = comptime blk: {
679 const b = "........1........";676 const b = "........1........";
test/behavior/struct.zig-3
...@@ -11,7 +11,6 @@ top_level_field: i32,...@@ -11,7 +11,6 @@ top_level_field: i32,
11test "top level fields" {11test "top level fields" {
12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1514
16 var instance = @This(){15 var instance = @This(){
17 .top_level_field = 1234,16 .top_level_field = 1234,
...@@ -122,8 +121,6 @@ test "struct byval assign" {...@@ -122,8 +121,6 @@ test "struct byval assign" {
122}121}
123122
124test "call struct static method" {123test "call struct static method" {
125 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
126
127 const result = StructWithNoFields.add(3, 4);124 const result = StructWithNoFields.add(3, 4);
128 try expect(result == 7);125 try expect(result == 7);
129}126}
test/behavior/switch.zig-3
...@@ -215,7 +215,6 @@ fn poll() void {...@@ -215,7 +215,6 @@ fn poll() void {
215215
216test "switch on global mutable var isn't constant-folded" {216test "switch on global mutable var isn't constant-folded" {
217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
218 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
219218
220 while (state < 2) {219 while (state < 2) {
221 poll();220 poll();
...@@ -349,8 +348,6 @@ fn returnsFalse() bool {...@@ -349,8 +348,6 @@ fn returnsFalse() bool {
349 }348 }
350}349}
351test "switch on const enum with var" {350test "switch on const enum with var" {
352 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
353
354 try expect(!returnsFalse());351 try expect(!returnsFalse());
355}352}
356353
test/behavior/this.zig-2
...@@ -21,8 +21,6 @@ fn add(x: i32, y: i32) i32 {...@@ -21,8 +21,6 @@ fn add(x: i32, y: i32) i32 {
21}21}
2222
23test "this refer to module call private fn" {23test "this refer to module call private fn" {
24 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
25
26 try expect(module.add(1, 2) == 3);24 try expect(module.add(1, 2) == 3);
27}25}
2826
test/behavior/threadlocal.zig-2
...@@ -11,7 +11,6 @@ test "thread local variable" {...@@ -11,7 +11,6 @@ test "thread local variable" {
11 else => return error.SkipZigTest,11 else => return error.SkipZigTest,
12 }; // TODO12 }; // TODO
13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1514
16 const S = struct {15 const S = struct {
17 threadlocal var t: i32 = 1234;16 threadlocal var t: i32 = 1234;
...@@ -47,7 +46,6 @@ test "reference a global threadlocal variable" {...@@ -47,7 +46,6 @@ test "reference a global threadlocal variable" {
47 else => return error.SkipZigTest,46 else => return error.SkipZigTest,
48 }; // TODO47 }; // TODO
49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5149
52 _ = nrfx_uart_rx(&g_uart0);50 _ = nrfx_uart_rx(&g_uart0);
53}51}
test/behavior/type.zig-1
...@@ -491,7 +491,6 @@ test "Type.Fn" {...@@ -491,7 +491,6 @@ test "Type.Fn" {
491 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO491 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
492 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO492 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
493 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO493 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
494 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
495494
496 const some_opaque = opaque {};495 const some_opaque = opaque {};
497 const some_ptr = *some_opaque;496 const some_ptr = *some_opaque;
test/behavior/type_info.zig-2
...@@ -285,7 +285,6 @@ fn testUnion() !void {...@@ -285,7 +285,6 @@ fn testUnion() !void {
285285
286test "type info: struct info" {286test "type info: struct info" {
287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
288 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
289288
290 try testStruct();289 try testStruct();
291 comptime try testStruct();290 comptime try testStruct();
...@@ -513,7 +512,6 @@ test "type info for async frames" {...@@ -513,7 +512,6 @@ test "type info for async frames" {
513512
514test "Declarations are returned in declaration order" {513test "Declarations are returned in declaration order" {
515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
516 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
517515
518 const S = struct {516 const S = struct {
519 const a = 1;517 const a = 1;
test/behavior/undefined.zig-1
...@@ -81,7 +81,6 @@ test "assign undefined to struct with method" {...@@ -81,7 +81,6 @@ test "assign undefined to struct with method" {
8181
82test "type name of undefined" {82test "type name of undefined" {
83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO83 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8584
86 const x = undefined;85 const x = undefined;
87 try expect(mem.eql(u8, @typeName(@TypeOf(x)), "@TypeOf(undefined)"));86 try expect(mem.eql(u8, @typeName(@TypeOf(x)), "@TypeOf(undefined)"));
test/behavior/var_args.zig-3
...@@ -14,8 +14,6 @@ fn add(args: anytype) i32 {...@@ -14,8 +14,6 @@ fn add(args: anytype) i32 {
14}14}
1515
16test "add arbitrary args" {16test "add arbitrary args" {
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18
19 try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);17 try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
20 try expect(add(.{@as(i32, 1234)}) == 1234);18 try expect(add(.{@as(i32, 1234)}) == 1234);
21 try expect(add(.{}) == 0);19 try expect(add(.{}) == 0);
...@@ -32,7 +30,6 @@ test "send void arg to var args" {...@@ -32,7 +30,6 @@ test "send void arg to var args" {
32test "pass args directly" {30test "pass args directly" {
33 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
34 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3633
37 try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);34 try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
38 try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);35 try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
test/behavior/while.zig-3
...@@ -5,7 +5,6 @@ const assert = std.debug.assert;...@@ -5,7 +5,6 @@ const assert = std.debug.assert;
55
6test "while loop" {6test "while loop" {
7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
98
10 var i: i32 = 0;9 var i: i32 = 0;
11 while (i < 4) {10 while (i < 4) {
...@@ -39,8 +38,6 @@ fn staticWhileLoop2() i32 {...@@ -39,8 +38,6 @@ fn staticWhileLoop2() i32 {
39}38}
4039
41test "while with continue expression" {40test "while with continue expression" {
42 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
43
44 var sum: i32 = 0;41 var sum: i32 = 0;
45 {42 {
46 var i: i32 = 0;43 var i: i32 = 0;