authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-23 12:37:48-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-09-23 12:37:48-07:00
logb00287175c044682ea025805de05a6ac26a42771
tree1c6ef32977a615238c231c79c020c16a8b98da5d
parent865b2e259bf78dbf1d4c1051b5fff68b90bca65f
parentcff8ab88f5ffe24771aa9c6e839eef03bc22f3d2
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17174 from Snektron/spirv-stuffies

spirv gaming

71 files changed, 1301 insertions(+), 1158 deletions(-)

src/codegen/spirv.zig+1137-811
...@@ -12,6 +12,7 @@ const LazySrcLoc = Module.LazySrcLoc;...@@ -12,6 +12,7 @@ const LazySrcLoc = Module.LazySrcLoc;
12const Air = @import("../Air.zig");12const Air = @import("../Air.zig");
13const Zir = @import("../Zir.zig");13const Zir = @import("../Zir.zig");
14const Liveness = @import("../Liveness.zig");14const Liveness = @import("../Liveness.zig");
15const InternPool = @import("../InternPool.zig");
1516
16const spec = @import("spirv/spec.zig");17const spec = @import("spirv/spec.zig");
17const Opcode = spec.Opcode;18const Opcode = spec.Opcode;
...@@ -30,15 +31,26 @@ const SpvAssembler = @import("spirv/Assembler.zig");...@@ -30,15 +31,26 @@ const SpvAssembler = @import("spirv/Assembler.zig");
3031
31const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);32const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);
3233
34/// We want to store some extra facts about types as mapped from Zig to SPIR-V.
35/// This structure is used to keep that extra information, as well as
36/// the cached reference to the type.
37const SpvTypeInfo = struct {
38 ty_ref: CacheRef,
39};
40
41const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, SpvTypeInfo);
42
33const IncomingBlock = struct {43const IncomingBlock = struct {
34 src_label_id: IdRef,44 src_label_id: IdRef,
35 break_value_id: IdRef,45 break_value_id: IdRef,
36};46};
3747
38const BlockMap = std.AutoHashMapUnmanaged(Air.Inst.Index, struct {48const Block = struct {
39 label_id: IdRef,49 label_id: ?IdRef,
40 incoming_blocks: *std.ArrayListUnmanaged(IncomingBlock),50 incoming_blocks: std.ArrayListUnmanaged(IncomingBlock),
41});51};
52
53const BlockMap = std.AutoHashMapUnmanaged(Air.Inst.Index, *Block);
4254
43/// Maps Zig decl indices to linking SPIR-V linking information.55/// Maps Zig decl indices to linking SPIR-V linking information.
44pub const DeclLinkMap = std.AutoHashMap(Module.Decl.Index, SpvModule.Decl.Index);56pub const DeclLinkMap = std.AutoHashMap(Module.Decl.Index, SpvModule.Decl.Index);
...@@ -78,6 +90,15 @@ pub const DeclGen = struct {...@@ -78,6 +90,15 @@ pub const DeclGen = struct {
78 /// A map keeping track of which instruction generated which result-id.90 /// A map keeping track of which instruction generated which result-id.
79 inst_results: InstMap = .{},91 inst_results: InstMap = .{},
8092
93 /// A map that maps AIR intern pool indices to SPIR-V cache references (which
94 /// is basically the same thing except for SPIR-V).
95 /// This map is typically only used for structures that are deemed heavy enough
96 /// that it is worth to store them here. The SPIR-V module also interns types,
97 /// and so the main purpose of this map is to avoid recomputation and to
98 /// cache extra information about the type rather than to aid in validity
99 /// of the SPIR-V module.
100 type_map: TypeMap = .{},
101
81 /// We need to keep track of result ids for block labels, as well as the 'incoming'102 /// We need to keep track of result ids for block labels, as well as the 'incoming'
82 /// blocks for a block.103 /// blocks for a block.
83 blocks: BlockMap = .{},104 blocks: BlockMap = .{},
...@@ -88,6 +109,10 @@ pub const DeclGen = struct {...@@ -88,6 +109,10 @@ pub const DeclGen = struct {
88 /// The code (prologue and body) for the function we are currently generating code for.109 /// The code (prologue and body) for the function we are currently generating code for.
89 func: SpvModule.Fn = .{},110 func: SpvModule.Fn = .{},
90111
112 /// Stack of the base offsets of the current decl, which is what `dbg_stmt` is relative to.
113 /// This is a stack to keep track of inline functions.
114 base_line_stack: std.ArrayListUnmanaged(u32) = .{},
115
91 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.116 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.
92 /// Memory is owned by `module.gpa`.117 /// Memory is owned by `module.gpa`.
93 error_msg: ?*Module.ErrorMsg,118 error_msg: ?*Module.ErrorMsg,
...@@ -186,6 +211,7 @@ pub const DeclGen = struct {...@@ -186,6 +211,7 @@ pub const DeclGen = struct {
186 self.blocks.clearRetainingCapacity();211 self.blocks.clearRetainingCapacity();
187 self.current_block_label_id = undefined;212 self.current_block_label_id = undefined;
188 self.func.reset();213 self.func.reset();
214 self.base_line_stack.items.len = 0;
189 self.error_msg = null;215 self.error_msg = null;
190216
191 self.genDecl() catch |err| switch (err) {217 self.genDecl() catch |err| switch (err) {
...@@ -207,8 +233,10 @@ pub const DeclGen = struct {...@@ -207,8 +233,10 @@ pub const DeclGen = struct {
207 pub fn deinit(self: *DeclGen) void {233 pub fn deinit(self: *DeclGen) void {
208 self.args.deinit(self.gpa);234 self.args.deinit(self.gpa);
209 self.inst_results.deinit(self.gpa);235 self.inst_results.deinit(self.gpa);
236 self.type_map.deinit(self.gpa);
210 self.blocks.deinit(self.gpa);237 self.blocks.deinit(self.gpa);
211 self.func.deinit(self.gpa);238 self.func.deinit(self.gpa);
239 self.base_line_stack.deinit(self.gpa);
212 }240 }
213241
214 /// Return the target which we are currently compiling for.242 /// Return the target which we are currently compiling for.
...@@ -388,7 +416,7 @@ pub const DeclGen = struct {...@@ -388,7 +416,7 @@ pub const DeclGen = struct {
388 switch (repr) {416 switch (repr) {
389 .indirect => {417 .indirect => {
390 const int_ty_ref = try self.intType(.unsigned, 1);418 const int_ty_ref = try self.intType(.unsigned, 1);
391 return self.spv.constInt(int_ty_ref, @intFromBool(value));419 return self.constInt(int_ty_ref, @intFromBool(value));
392 },420 },
393 .direct => {421 .direct => {
394 const bool_ty_ref = try self.resolveType(Type.bool, .direct);422 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
...@@ -397,25 +425,49 @@ pub const DeclGen = struct {...@@ -397,25 +425,49 @@ pub const DeclGen = struct {
397 }425 }
398 }426 }
399427
428 /// Emits an integer constant.
429 /// This function, unlike SpvModule.constInt, takes care to bitcast
430 /// the value to an unsigned int first for Kernels.
431 fn constInt(self: *DeclGen, ty_ref: CacheRef, value: anytype) !IdRef {
432 if (value < 0) {
433 const ty = self.spv.cache.lookup(ty_ref).int_type;
434 // Manually truncate the value so that the resulting value
435 // fits within the unsigned type.
436 const bits: u64 = @bitCast(@as(i64, @intCast(value)));
437 const truncated_bits = if (ty.bits == 64)
438 bits
439 else
440 bits & (@as(u64, 1) << @intCast(ty.bits)) - 1;
441 return try self.spv.constInt(ty_ref, truncated_bits);
442 } else {
443 return try self.spv.constInt(ty_ref, value);
444 }
445 }
446
400 /// Construct a struct at runtime.447 /// Construct a struct at runtime.
401 /// result_ty_ref must be a struct type.448 /// result_ty_ref must be a struct type.
449 /// Constituents should be in `indirect` representation (as the elements of a struct should be).
450 /// Result is in `direct` representation.
402 fn constructStruct(self: *DeclGen, result_ty_ref: CacheRef, constituents: []const IdRef) !IdRef {451 fn constructStruct(self: *DeclGen, result_ty_ref: CacheRef, constituents: []const IdRef) !IdRef {
403 // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'452 // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
404 // operands are not constant.453 // operands are not constant.
405 // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349454 // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349
406 // For now, just initialize the struct by setting the fields manually...455 // For now, just initialize the struct by setting the fields manually...
407 // TODO: Make this OpCompositeConstruct when we can456 // TODO: Make this OpCompositeConstruct when we can
408 const ptr_composite_id = try self.alloc(result_ty_ref, null);457 const ptr_ty_ref = try self.spv.ptrType(result_ty_ref, .Function);
409 // Note: using 32-bit ints here because usize crashes the translator as well458 const ptr_composite_id = self.spv.allocId();
410 const index_ty_ref = try self.intType(.unsigned, 32);459 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
460 .id_result_type = self.typeId(ptr_ty_ref),
461 .id_result = ptr_composite_id,
462 .storage_class = .Function,
463 });
411464
412 const spv_composite_ty = self.spv.cache.lookup(result_ty_ref).struct_type;465 const spv_composite_ty = self.spv.cache.lookup(result_ty_ref).struct_type;
413 const member_types = spv_composite_ty.member_types;466 const member_types = spv_composite_ty.member_types;
414467
415 for (constituents, member_types, 0..) |constitent_id, member_ty_ref, index| {468 for (constituents, member_types, 0..) |constitent_id, member_ty_ref, index| {
416 const index_id = try self.spv.constInt(index_ty_ref, index);469 const ptr_member_ty_ref = try self.spv.ptrType(member_ty_ref, .Function);
417 const ptr_member_ty_ref = try self.spv.ptrType(member_ty_ref, .Generic);470 const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))});
418 const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{index_id});
419 try self.func.body.emit(self.spv.gpa, .OpStore, .{471 try self.func.body.emit(self.spv.gpa, .OpStore, .{
420 .pointer = ptr_id,472 .pointer = ptr_id,
421 .object = constitent_id,473 .object = constitent_id,
...@@ -430,598 +482,122 @@ pub const DeclGen = struct {...@@ -430,598 +482,122 @@ pub const DeclGen = struct {
430 return result_id;482 return result_id;
431 }483 }
432484
433 const IndirectConstantLowering = struct {485 /// Construct a struct at runtime.
434 const undef = 0xAA;486 /// result_ty_ref must be an array type.
435487 /// Constituents should be in `indirect` representation (as the elements of an array should be).
436 dg: *DeclGen,488 /// Result is in `direct` representation.
437 /// Cached reference of the u32 type.489 fn constructArray(self: *DeclGen, result_ty_ref: CacheRef, constituents: []const IdRef) !IdRef {
438 u32_ty_ref: CacheRef,490 // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
439 /// The members of the resulting structure type491 // operands are not constant.
440 members: std.ArrayList(CacheRef),492 // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349
441 /// The initializers of each of the members.493 // For now, just initialize the struct by setting the fields manually...
442 initializers: std.ArrayList(IdRef),494 // TODO: Make this OpCompositeConstruct when we can
443 /// The current size of the structure. Includes495 // TODO: Make this Function storage type
444 /// the bytes in partial_word.496 const ptr_ty_ref = try self.spv.ptrType(result_ty_ref, .Function);
445 size: u32 = 0,497 const ptr_composite_id = self.spv.allocId();
446 /// The partially filled last constant.498 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
447 /// If full, its flushed.499 .id_result_type = self.typeId(ptr_ty_ref),
448 partial_word: std.BoundedArray(u8, @sizeOf(Word)) = .{},500 .id_result = ptr_composite_id,
449 /// The declaration dependencies of the constant we are lowering.501 .storage_class = .Function,
450 decl_deps: std.AutoArrayHashMap(SpvModule.Decl.Index, void),502 });
451
452 /// Utility function to get the section that instructions should be lowered to.
453 fn section(self: *@This()) *SpvSection {
454 return &self.dg.spv.globals.section;
455 }
456
457 /// Flush the partial_word to the members. If the partial_word is not
458 /// filled, this adds padding bytes (which are undefined).
459 fn flush(self: *@This()) !void {
460 if (self.partial_word.len == 0) {
461 // No need to add it there.
462 return;
463 }
464
465 for (self.partial_word.unusedCapacitySlice()) |*unused| {
466 // TODO: Perhaps we should generate OpUndef for these bytes?
467 unused.* = undef;
468 }
469
470 const word = @as(Word, @bitCast(self.partial_word.buffer));
471 const result_id = try self.dg.spv.constInt(self.u32_ty_ref, word);
472 try self.members.append(self.u32_ty_ref);
473 try self.initializers.append(result_id);
474
475 self.partial_word.len = 0;
476 self.size = std.mem.alignForward(u32, self.size, @sizeOf(Word));
477 }
478
479 /// Fill the buffer with undefined values until the size is aligned to `align`.
480 fn fillToAlign(self: *@This(), alignment: u32) !void {
481 const target_size = std.mem.alignForward(u32, self.size, alignment);
482 try self.addUndef(target_size - self.size);
483 }
484
485 fn addUndef(self: *@This(), amt: u64) !void {
486 for (0..@as(usize, @intCast(amt))) |_| {
487 try self.addByte(undef);
488 }
489 }
490
491 /// Add a single byte of data to the constant.
492 fn addByte(self: *@This(), data: u8) !void {
493 self.partial_word.append(data) catch {
494 try self.flush();
495 self.partial_word.append(data) catch unreachable;
496 };
497 self.size += 1;
498 }
499
500 /// Add many bytes of data to the constnat.
501 fn addBytes(self: *@This(), data: []const u8) !void {
502 // TODO: Improve performance by adding in bulk, or something?
503 for (data) |byte| {
504 try self.addByte(byte);
505 }
506 }
507
508 fn addPtr(self: *@This(), ptr_ty_ref: CacheRef, ptr_id: IdRef) !void {
509 // TODO: Double check pointer sizes here.
510 // shared pointers might be u32...
511 const target = self.dg.getTarget();
512 const width = @divExact(target.ptrBitWidth(), 8);
513 if (self.size % width != 0) {
514 return self.dg.todo("misaligned pointer constants", .{});
515 }
516 try self.members.append(ptr_ty_ref);
517 try self.initializers.append(ptr_id);
518 self.size += width;
519 }
520
521 fn addNullPtr(self: *@This(), ptr_ty_ref: CacheRef) !void {
522 const result_id = try self.dg.spv.constNull(ptr_ty_ref);
523 try self.addPtr(ptr_ty_ref, result_id);
524 }
525
526 fn addConstInt(self: *@This(), comptime T: type, value: T) !void {
527 if (@bitSizeOf(T) % 8 != 0) {
528 @compileError("todo: non byte aligned int constants");
529 }
530
531 // TODO: Swap endianness if the compiler is big endian.
532 try self.addBytes(std.mem.asBytes(&value));
533 }
534
535 fn addConstBool(self: *@This(), value: bool) !void {
536 try self.addByte(@intFromBool(value)); // TODO: Keep in sync with something?
537 }
538
539 fn addInt(self: *@This(), ty: Type, val: Value) !void {
540 const mod = self.dg.module;
541 const len = ty.abiSize(mod);
542 if (val.isUndef(mod)) {
543 try self.addUndef(len);
544 return;
545 }
546
547 const int_info = ty.intInfo(mod);
548 const int_bits = switch (int_info.signedness) {
549 .signed => @as(u64, @bitCast(val.toSignedInt(mod))),
550 .unsigned => val.toUnsignedInt(mod),
551 };
552
553 // TODO: Swap endianess if the compiler is big endian.
554 try self.addBytes(std.mem.asBytes(&int_bits)[0..@as(usize, @intCast(len))]);
555 }
556503
557 fn addFloat(self: *@This(), ty: Type, val: Value) !void {504 const spv_composite_ty = self.spv.cache.lookup(result_ty_ref).array_type;
558 const mod = self.dg.module;505 const elem_ty_ref = spv_composite_ty.element_type;
559 const target = self.dg.getTarget();506 const ptr_elem_ty_ref = try self.spv.ptrType(elem_ty_ref, .Function);
560 const len = ty.abiSize(mod);
561507
562 // TODO: Swap endianess if the compiler is big endian.508 for (constituents, 0..) |constitent_id, index| {
563 switch (ty.floatBits(target)) {509 const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))});
564 16 => {510 try self.func.body.emit(self.spv.gpa, .OpStore, .{
565 const float_bits = val.toFloat(f16, mod);511 .pointer = ptr_id,
566 try self.addBytes(std.mem.asBytes(&float_bits)[0..@as(usize, @intCast(len))]);512 .object = constitent_id,
567 },513 });
568 32 => {
569 const float_bits = val.toFloat(f32, mod);
570 try self.addBytes(std.mem.asBytes(&float_bits)[0..@as(usize, @intCast(len))]);
571 },
572 64 => {
573 const float_bits = val.toFloat(f64, mod);
574 try self.addBytes(std.mem.asBytes(&float_bits)[0..@as(usize, @intCast(len))]);
575 },
576 else => unreachable,
577 }
578 }514 }
515 const result_id = self.spv.allocId();
516 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
517 .id_result_type = self.typeId(result_ty_ref),
518 .id_result = result_id,
519 .pointer = ptr_composite_id,
520 });
521 return result_id;
522 }
579523
580 fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void {524 fn constructDeclRef(self: *DeclGen, ty: Type, decl_index: Decl.Index) !IdRef {
581 const dg = self.dg;525 const mod = self.module;
582 const mod = dg.module;526 const ty_ref = try self.resolveType(ty, .direct);
583527 const ty_id = self.typeId(ty_ref);
584 const ty_ref = try self.dg.resolveType(ty, .indirect);528 const decl = mod.declPtr(decl_index);
585 const ty_id = dg.typeId(ty_ref);529 const spv_decl_index = try self.resolveDecl(decl_index);
586530 switch (mod.intern_pool.indexToKey(decl.val.ip_index)) {
587 const decl = dg.module.declPtr(decl_index);531 .func => {
588 const spv_decl_index = try dg.resolveDecl(decl_index);532 // TODO: Properly lower function pointers. For now we are going to hack around it and
589533 // just generate an empty pointer. Function pointers are represented by a pointer to usize.
590 switch (mod.intern_pool.indexToKey(decl.val.ip_index)) {534 // TODO: Add dependency
591 .func => {535 return try self.spv.constNull(ty_ref);
592 // TODO: Properly lower function pointers. For now we are going to hack around it and536 },
593 // just generate an empty pointer. Function pointers are represented by usize for now,537 .extern_func => unreachable, // TODO
594 // though.538 else => {
595 try self.addInt(Type.usize, Value.zero_usize);539 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
596 // TODO: Add dependency540 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});
597 return;
598 },
599 .extern_func => unreachable, // TODO
600 else => {
601 const result_id = dg.spv.allocId();
602541
603 try self.decl_deps.put(spv_decl_index, {});542 const final_storage_class = spvStorageClass(decl.@"addrspace");
543
544 const decl_ty_ref = try self.resolveType(decl.ty, .indirect);
545 const decl_ptr_ty_ref = try self.spv.ptrType(decl_ty_ref, final_storage_class);
546
547 const ptr_id = switch (final_storage_class) {
548 .Generic => blk: {
549 // Pointer should be Generic, but is actually placed in CrossWorkgroup.
550 const result_id = self.spv.allocId();
551 try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{
552 .id_result_type = self.typeId(decl_ptr_ty_ref),
553 .id_result = result_id,
554 .pointer = decl_id,
555 });
556 break :blk result_id;
557 },
558 else => decl_id,
559 };
604560
605 const decl_id = dg.spv.declPtr(spv_decl_index).result_id;561 if (decl_ptr_ty_ref != ty_ref) {
606 // TODO: Do we need a storage class cast here?562 // Differing pointer types, insert a cast.
607 // TODO: We can probably eliminate these casts563 const casted_ptr_id = self.spv.allocId();
608 try dg.spv.globals.section.emitSpecConstantOp(dg.spv.gpa, .OpBitcast, .{564 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
609 .id_result_type = ty_id,565 .id_result_type = ty_id,
610 .id_result = result_id,566 .id_result = casted_ptr_id,
611 .operand = decl_id,567 .operand = ptr_id,
612 });568 });
613569 return casted_ptr_id;
614 try self.addPtr(ty_ref, result_id);570 } else {
615 },571 return ptr_id;
616 }572 }
617 }573 },
618
619 fn lower(self: *@This(), ty: Type, arg_val: Value) !void {
620 const dg = self.dg;
621 const mod = dg.module;
622 const ip = &mod.intern_pool;
623
624 var val = arg_val;
625 switch (ip.indexToKey(val.toIntern())) {
626 .runtime_value => |rt| val = rt.val.toValue(),
627 else => {},
628 }
629
630 if (val.isUndefDeep(mod)) {
631 const size = ty.abiSize(mod);
632 return try self.addUndef(size);
633 }
634
635 switch (ip.indexToKey(val.toIntern())) {
636 .int_type,
637 .ptr_type,
638 .array_type,
639 .vector_type,
640 .opt_type,
641 .anyframe_type,
642 .error_union_type,
643 .simple_type,
644 .struct_type,
645 .anon_struct_type,
646 .union_type,
647 .opaque_type,
648 .enum_type,
649 .func_type,
650 .error_set_type,
651 .inferred_error_set_type,
652 => unreachable, // types, not values
653
654 .undef, .runtime_value => unreachable, // handled above
655 .simple_value => |simple_value| switch (simple_value) {
656 .undefined,
657 .void,
658 .null,
659 .empty_struct,
660 .@"unreachable",
661 .generic_poison,
662 => unreachable, // non-runtime values
663 .false, .true => try self.addConstBool(val.toBool()),
664 },
665 .variable,
666 .extern_func,
667 .func,
668 .enum_literal,
669 .empty_enum_value,
670 => unreachable, // non-runtime values
671 .int => try self.addInt(ty, val),
672 .err => |err| {
673 const int = try mod.getErrorValue(err.name);
674 try self.addConstInt(u16, @as(u16, @intCast(int)));
675 },
676 .error_union => |error_union| {
677 const err_ty = switch (error_union.val) {
678 .err_name => ty.errorUnionSet(mod),
679 .payload => Type.err_int,
680 };
681 const err_val = switch (error_union.val) {
682 .err_name => |err_name| (try mod.intern(.{ .err = .{
683 .ty = ty.errorUnionSet(mod).toIntern(),
684 .name = err_name,
685 } })).toValue(),
686 .payload => try mod.intValue(Type.err_int, 0),
687 };
688 const payload_ty = ty.errorUnionPayload(mod);
689 const eu_layout = dg.errorUnionLayout(payload_ty);
690 if (!eu_layout.payload_has_bits) {
691 // We use the error type directly as the type.
692 try self.lower(err_ty, err_val);
693 return;
694 }
695
696 const payload_size = payload_ty.abiSize(mod);
697 const error_size = err_ty.abiSize(mod);
698 const ty_size = ty.abiSize(mod);
699 const padding = ty_size - payload_size - error_size;
700
701 const payload_val = switch (error_union.val) {
702 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),
703 .payload => |payload| payload,
704 }.toValue();
705
706 if (eu_layout.error_first) {
707 try self.lower(err_ty, err_val);
708 try self.lower(payload_ty, payload_val);
709 } else {
710 try self.lower(payload_ty, payload_val);
711 try self.lower(err_ty, err_val);
712 }
713
714 try self.addUndef(padding);
715 },
716 .enum_tag => {
717 const int_val = try val.intFromEnum(ty, mod);
718
719 const int_ty = ty.intTagType(mod);
720
721 try self.lower(int_ty, int_val);
722 },
723 .float => try self.addFloat(ty, val),
724 .ptr => |ptr| {
725 const ptr_ty = switch (ptr.len) {
726 .none => ty,
727 else => ty.slicePtrFieldType(mod),
728 };
729 switch (ptr.addr) {
730 .decl => |decl| try self.addDeclRef(ptr_ty, decl),
731 .mut_decl => |mut_decl| try self.addDeclRef(ptr_ty, mut_decl.decl),
732 .int => |int| try self.addInt(Type.usize, int.toValue()),
733 else => |tag| return dg.todo("pointer value of type {s}", .{@tagName(tag)}),
734 }
735 if (ptr.len != .none) {
736 try self.addInt(Type.usize, ptr.len.toValue());
737 }
738 },
739 .opt => {
740 const payload_ty = ty.optionalChild(mod);
741 const payload_val = val.optionalValue(mod);
742 const abi_size = ty.abiSize(mod);
743
744 if (!payload_ty.hasRuntimeBits(mod)) {
745 try self.addConstBool(payload_val != null);
746 return;
747 } else if (ty.optionalReprIsPayload(mod)) {
748 // Optional representation is a nullable pointer or slice.
749 if (payload_val) |pl_val| {
750 try self.lower(payload_ty, pl_val);
751 } else {
752 const ptr_ty_ref = try dg.resolveType(ty, .indirect);
753 try self.addNullPtr(ptr_ty_ref);
754 }
755 return;
756 }
757
758 // Optional representation is a structure.
759 // { Payload, Bool }
760
761 // Subtract 1 for @sizeOf(bool).
762 // TODO: Make this not hardcoded.
763 const payload_size = payload_ty.abiSize(mod);
764 const padding = abi_size - payload_size - 1;
765
766 if (payload_val) |pl_val| {
767 try self.lower(payload_ty, pl_val);
768 } else {
769 try self.addUndef(payload_size);
770 }
771 try self.addConstBool(payload_val != null);
772 try self.addUndef(padding);
773 },
774 .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) {
775 .array_type => |array_type| {
776 const elem_ty = array_type.child.toType();
777 switch (aggregate.storage) {
778 .bytes => |bytes| try self.addBytes(bytes),
779 .elems, .repeated_elem => {
780 for (0..@as(usize, @intCast(array_type.len))) |i| {
781 try self.lower(elem_ty, switch (aggregate.storage) {
782 .bytes => unreachable,
783 .elems => |elem_vals| elem_vals[@as(usize, @intCast(i))].toValue(),
784 .repeated_elem => |elem_val| elem_val.toValue(),
785 });
786 }
787 },
788 }
789 if (array_type.sentinel != .none) {
790 try self.lower(elem_ty, array_type.sentinel.toValue());
791 }
792 },
793 .vector_type => return dg.todo("indirect constant of type {}", .{ty.fmt(mod)}),
794 .struct_type => {
795 const struct_type = mod.typeToStruct(ty).?;
796 if (struct_type.layout == .Packed) {
797 return dg.todo("packed struct constants", .{});
798 }
799
800 // TODO iterate with runtime order instead so that struct field
801 // reordering can be enabled for this backend.
802 const struct_begin = self.size;
803 for (struct_type.field_types.get(ip), 0..) |field_ty, i_usize| {
804 const i: u32 = @intCast(i_usize);
805 if (struct_type.fieldIsComptime(ip, i)) continue;
806 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
807
808 const field_val = switch (aggregate.storage) {
809 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
810 .ty = field_ty,
811 .storage = .{ .u64 = bytes[i] },
812 } }),
813 .elems => |elems| elems[i],
814 .repeated_elem => |elem| elem,
815 };
816 try self.lower(field_ty.toType(), field_val.toValue());
817
818 // Add padding if required.
819 // TODO: Add to type generation as well?
820 const unpadded_field_end = self.size - struct_begin;
821 const padded_field_end = ty.structFieldOffset(i + 1, mod);
822 const padding = padded_field_end - unpadded_field_end;
823 try self.addUndef(padding);
824 }
825 },
826 .anon_struct_type => unreachable, // TODO
827 else => unreachable,
828 },
829 .un => |un| {
830 const layout = ty.unionGetLayout(mod);
831
832 if (layout.payload_size == 0) {
833 return try self.lower(ty.unionTagTypeSafety(mod).?, un.tag.toValue());
834 }
835
836 const union_obj = mod.typeToUnion(ty).?;
837 if (union_obj.getLayout(ip) == .Packed) {
838 return dg.todo("packed union constants", .{});
839 }
840
841 const active_field = ty.unionTagFieldIndex(un.tag.toValue(), dg.module).?;
842 const active_field_ty = union_obj.field_types.get(ip)[active_field].toType();
843
844 const has_tag = layout.tag_size != 0;
845 const tag_first = layout.tag_align.compare(.gte, layout.payload_align);
846
847 if (has_tag and tag_first) {
848 try self.lower(ty.unionTagTypeSafety(mod).?, un.tag.toValue());
849 }
850
851 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod)) blk: {
852 try self.lower(active_field_ty, un.val.toValue());
853 break :blk active_field_ty.abiSize(mod);
854 } else 0;
855
856 const payload_padding_len = layout.payload_size - active_field_size;
857 try self.addUndef(payload_padding_len);
858
859 if (has_tag and !tag_first) {
860 try self.lower(ty.unionTagTypeSafety(mod).?, un.tag.toValue());
861 }
862
863 try self.addUndef(layout.padding);
864 },
865 .memoized_call => unreachable,
866 }
867 }
868 };
869
870 /// Returns a pointer to `val`. The value is placed directly
871 /// into the storage class `storage_class`, and this is also where the resulting
872 /// pointer points to. Note: result is not necessarily an OpVariable instruction!
873 fn lowerIndirectConstant(
874 self: *DeclGen,
875 spv_decl_index: SpvModule.Decl.Index,
876 ty: Type,
877 val: Value,
878 storage_class: StorageClass,
879 cast_to_generic: bool,
880 alignment: u32,
881 ) Error!void {
882 // To simplify constant generation, we're going to generate constants as a word-array, and
883 // pointer cast the result to the right type.
884 // This means that the final constant will be generated as follows:
885 // %T = OpTypeStruct %members...
886 // %P = OpTypePointer %T
887 // %U = OpTypePointer %ty
888 // %1 = OpConstantComposite %T %initializers...
889 // %2 = OpVariable %P %1
890 // %result_id = OpSpecConstantOp OpBitcast %U %2
891 //
892 // The members consist of two options:
893 // - Literal values: ints, strings, etc. These are generated as u32 words.
894 // - Relocations, such as pointers: These are generated by embedding the pointer into the
895 // to-be-generated structure. There are two options here, depending on the alignment of the
896 // pointer value itself (not the alignment of the pointee).
897 // - Natively or over-aligned values. These can just be generated directly.
898 // - Underaligned pointers. These need to be packed into the word array by using a mixture of
899 // OpSpecConstantOp instructions such as OpConvertPtrToU, OpBitcast, OpShift, etc.
900
901 // TODO: Implement alignment here.
902 // This is hoing to require some hacks because there is no real way to
903 // set an OpVariable's alignment.
904 _ = alignment;
905
906 assert(storage_class != .Generic and storage_class != .Function);
907
908 const var_id = self.spv.allocId();
909 log.debug("lowerIndirectConstant: id = {}, index = {}, ty = {}, val = {}", .{ var_id.id, @intFromEnum(spv_decl_index), ty.fmt(self.module), val.fmtDebug() });
910
911 const section = &self.spv.globals.section;
912
913 const ty_ref = try self.resolveType(ty, .indirect);
914 const ptr_ty_ref = try self.spv.ptrType(ty_ref, storage_class);
915
916 // const target = self.getTarget();
917
918 // TODO: Fix the resulting global linking for these paths.
919 // if (val.isUndef(mod)) {
920 // // Special case: the entire value is undefined. In this case, we can just
921 // // generate an OpVariable with no initializer.
922 // return try section.emit(self.spv.gpa, .OpVariable, .{
923 // .id_result_type = self.typeId(ptr_ty_ref),
924 // .id_result = result_id,
925 // .storage_class = storage_class,
926 // });
927 // } else if (ty.abiSize(mod) == 0) {
928 // // Special case: if the type has no size, then return an undefined pointer.
929 // return try section.emit(self.spv.gpa, .OpUndef, .{
930 // .id_result_type = self.typeId(ptr_ty_ref),
931 // .id_result = result_id,
932 // });
933 // }
934
935 // TODO: Capture the above stuff in here as well...
936 const begin_inst = self.spv.beginGlobal();
937
938 const u32_ty_ref = try self.intType(.unsigned, 32);
939 var icl = IndirectConstantLowering{
940 .dg = self,
941 .u32_ty_ref = u32_ty_ref,
942 .members = std.ArrayList(CacheRef).init(self.gpa),
943 .initializers = std.ArrayList(IdRef).init(self.gpa),
944 .decl_deps = std.AutoArrayHashMap(SpvModule.Decl.Index, void).init(self.gpa),
945 };
946
947 defer icl.members.deinit();
948 defer icl.initializers.deinit();
949 defer icl.decl_deps.deinit();
950
951 try icl.lower(ty, val);
952 try icl.flush();
953
954 const constant_struct_ty_ref = try self.spv.resolve(.{ .struct_type = .{
955 .member_types = icl.members.items,
956 } });
957 const ptr_constant_struct_ty_ref = try self.spv.ptrType(constant_struct_ty_ref, storage_class);
958
959 const constant_struct_id = self.spv.allocId();
960 try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{
961 .id_result_type = self.typeId(constant_struct_ty_ref),
962 .id_result = constant_struct_id,
963 .constituents = icl.initializers.items,
964 });
965
966 self.spv.globalPtr(spv_decl_index).?.result_id = var_id;
967 try section.emit(self.spv.gpa, .OpVariable, .{
968 .id_result_type = self.typeId(ptr_constant_struct_ty_ref),
969 .id_result = var_id,
970 .storage_class = storage_class,
971 .initializer = constant_struct_id,
972 });
973 // TODO: Set alignment of OpVariable.
974 // TODO: We may be able to eliminate these casts.
975
976 const const_ptr_id = try self.makePointerConstant(section, ptr_constant_struct_ty_ref, var_id);
977 const result_id = self.spv.declPtr(spv_decl_index).result_id;
978
979 const bitcast_result_id = if (cast_to_generic)
980 self.spv.allocId()
981 else
982 result_id;
983
984 try section.emitSpecConstantOp(self.spv.gpa, .OpBitcast, .{
985 .id_result_type = self.typeId(ptr_ty_ref),
986 .id_result = bitcast_result_id,
987 .operand = const_ptr_id,
988 });
989
990 if (cast_to_generic) {
991 const generic_ptr_ty_ref = try self.spv.ptrType(ty_ref, .Generic);
992 try section.emitSpecConstantOp(self.spv.gpa, .OpPtrCastToGeneric, .{
993 .id_result_type = self.typeId(generic_ptr_ty_ref),
994 .id_result = result_id,
995 .pointer = bitcast_result_id,
996 });
997 }574 }
998
999 try self.spv.declareDeclDeps(spv_decl_index, icl.decl_deps.keys());
1000 self.spv.endGlobal(spv_decl_index, begin_inst);
1001 }575 }
1002576
1003 /// This function generates a load for a constant in direct (ie, non-memory) representation.577 /// This function generates a load for a constant in direct (ie, non-memory) representation.
1004 /// When the constant is simple, it can be generated directly using OpConstant instructions. When578 /// When the constant is simple, it can be generated directly using OpConstant instructions.
1005 /// the constant is more complicated however, it needs to be lowered to an indirect constant, which579 /// When the constant is more complicated however, it needs to be constructed using multiple values. This
1006 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.580 /// is done by emitting a sequence of instructions that initialize the value.
581 //
1007 /// This function should only be called during function code generation.582 /// This function should only be called during function code generation.
1008 fn constant(self: *DeclGen, ty: Type, arg_val: Value, repr: Repr) !IdRef {583 fn constant(self: *DeclGen, ty: Type, arg_val: Value, repr: Repr) !IdRef {
1009 const mod = self.module;584 const mod = self.module;
1010 const target = self.getTarget();585 const target = self.getTarget();
1011 const result_ty_ref = try self.resolveType(ty, repr);586 const result_ty_ref = try self.resolveType(ty, repr);
587 const ip = &mod.intern_pool;
1012588
1013 var val = arg_val;589 var val = arg_val;
1014 switch (mod.intern_pool.indexToKey(val.toIntern())) {590 switch (ip.indexToKey(val.toIntern())) {
1015 .runtime_value => |rt| val = rt.val.toValue(),591 .runtime_value => |rt| val = rt.val.toValue(),
1016 else => {},592 else => {},
1017 }593 }
1018594
1019 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtValue(ty, self.module) });595 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(ty, mod) });
1020 if (val.isUndef(mod)) {596 if (val.isUndefDeep(mod)) {
1021 return self.spv.constUndef(result_ty_ref);597 return self.spv.constUndef(result_ty_ref);
1022 }598 }
1023599
1024 switch (mod.intern_pool.indexToKey(val.toIntern())) {600 switch (ip.indexToKey(val.toIntern())) {
1025 .int_type,601 .int_type,
1026 .ptr_type,602 .ptr_type,
1027 .array_type,603 .array_type,
...@@ -1040,8 +616,7 @@ pub const DeclGen = struct {...@@ -1040,8 +616,7 @@ pub const DeclGen = struct {
1040 .inferred_error_set_type,616 .inferred_error_set_type,
1041 => unreachable, // types, not values617 => unreachable, // types, not values
1042618
1043 .undef => unreachable, // handled above619 .undef, .runtime_value => unreachable, // handled above
1044 .runtime_value => unreachable, // ???
1045620
1046 .variable,621 .variable,
1047 .extern_func,622 .extern_func,
...@@ -1059,17 +634,14 @@ pub const DeclGen = struct {...@@ -1059,17 +634,14 @@ pub const DeclGen = struct {
1059 .generic_poison,634 .generic_poison,
1060 => unreachable, // non-runtime values635 => unreachable, // non-runtime values
1061636
1062 .false, .true => switch (repr) {637 .false, .true => return try self.constBool(val.toBool(), repr),
1063 .direct => return try self.spv.constBool(result_ty_ref, val.toBool()),
1064 .indirect => return try self.spv.constInt(result_ty_ref, @intFromBool(val.toBool())),
1065 },
1066 },638 },
1067639
1068 .int => {640 .int => {
1069 if (ty.isSignedInt(mod)) {641 if (ty.isSignedInt(mod)) {
1070 return try self.spv.constInt(result_ty_ref, val.toSignedInt(mod));642 return try self.constInt(result_ty_ref, val.toSignedInt(mod));
1071 } else {643 } else {
1072 return try self.spv.constInt(result_ty_ref, val.toUnsignedInt(mod));644 return try self.constInt(result_ty_ref, val.toUnsignedInt(mod));
1073 }645 }
1074 },646 },
1075 .float => return switch (ty.floatBits(target)) {647 .float => return switch (ty.floatBits(target)) {
...@@ -1081,40 +653,206 @@ pub const DeclGen = struct {...@@ -1081,40 +653,206 @@ pub const DeclGen = struct {
1081 },653 },
1082 .err => |err| {654 .err => |err| {
1083 const value = try mod.getErrorValue(err.name);655 const value = try mod.getErrorValue(err.name);
1084 return try self.spv.constInt(result_ty_ref, value);656 return try self.constInt(result_ty_ref, value);
1085 },657 },
1086 // TODO: We can handle most pointers here (decl refs etc), because now they emit an extra658 .error_union => |error_union| {
1087 // OpVariable that is not really required.659 // TODO: Error unions may be constructed with constant instructions if the payload type
1088 else => {660 // allows it. For now, just generate it here regardless.
1089 // The value cannot be generated directly, so generate it as an indirect constant,661 const err_ty = switch (error_union.val) {
1090 // and then perform an OpLoad.662 .err_name => ty.errorUnionSet(mod),
1091 const result_id = self.spv.allocId();663 .payload => Type.err_int,
1092 const alignment = ty.abiAlignment(mod);664 };
1093 const spv_decl_index = try self.spv.allocDecl(.global);665 const err_val = switch (error_union.val) {
1094666 .err_name => |err_name| (try mod.intern(.{ .err = .{
1095 try self.lowerIndirectConstant(667 .ty = ty.errorUnionSet(mod).toIntern(),
1096 spv_decl_index,668 .name = err_name,
1097 ty,669 } })).toValue(),
1098 val,670 .payload => try mod.intValue(Type.err_int, 0),
1099 .UniformConstant,671 };
1100 false,672 const payload_ty = ty.errorUnionPayload(mod);
1101 @intCast(alignment.toByteUnits(0)),673 const eu_layout = self.errorUnionLayout(payload_ty);
1102 );674 if (!eu_layout.payload_has_bits) {
1103 log.debug("indirect constant: index = {}", .{@intFromEnum(spv_decl_index)});675 // We use the error type directly as the type.
1104 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});676 return try self.constant(err_ty, err_val, .indirect);
677 }
678
679 const payload_val = switch (error_union.val) {
680 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),
681 .payload => |payload| payload,
682 }.toValue();
683
684 var constituents: [2]IdRef = undefined;
685 if (eu_layout.error_first) {
686 constituents[0] = try self.constant(err_ty, err_val, .indirect);
687 constituents[1] = try self.constant(payload_ty, payload_val, .indirect);
688 } else {
689 constituents[0] = try self.constant(payload_ty, payload_val, .indirect);
690 constituents[1] = try self.constant(err_ty, err_val, .indirect);
691 }
692
693 return try self.constructStruct(result_ty_ref, &constituents);
694 },
695 .enum_tag => {
696 const int_val = try val.intFromEnum(ty, mod);
697 const int_ty = ty.intTagType(mod);
698 return try self.constant(int_ty, int_val, repr);
699 },
700 .ptr => |ptr| {
701 const ptr_ty = switch (ptr.len) {
702 .none => ty,
703 else => ty.slicePtrFieldType(mod),
704 };
705 const ptr_id = try self.constantPtr(ptr_ty, val);
706 if (ptr.len == .none) {
707 return ptr_id;
708 }
709
710 const len_id = try self.constant(Type.usize, ptr.len.toValue(), .indirect);
711 return try self.constructStruct(result_ty_ref, &.{ ptr_id, len_id });
712 },
713 .opt => {
714 const payload_ty = ty.optionalChild(mod);
715 const maybe_payload_val = val.optionalValue(mod);
716
717 if (!payload_ty.hasRuntimeBits(mod)) {
718 return try self.constBool(maybe_payload_val != null, .indirect);
719 } else if (ty.optionalReprIsPayload(mod)) {
720 // Optional representation is a nullable pointer or slice.
721 if (maybe_payload_val) |payload_val| {
722 return try self.constant(payload_ty, payload_val, .indirect);
723 } else {
724 const ptr_ty_ref = try self.resolveType(ty, .indirect);
725 return self.spv.constNull(ptr_ty_ref);
726 }
727 }
728
729 // Optional representation is a structure.
730 // { Payload, Bool }
731
732 const has_pl_id = try self.constBool(maybe_payload_val != null, .indirect);
733 const payload_id = if (maybe_payload_val) |payload_val|
734 try self.constant(payload_ty, payload_val, .indirect)
735 else
736 try self.spv.constUndef(try self.resolveType(payload_ty, .indirect));
737
738 return try self.constructStruct(result_ty_ref, &.{ payload_id, has_pl_id });
739 },
740 .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) {
741 .array_type => |array_type| {
742 const elem_ty = array_type.child.toType();
743 const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
744
745 const constituents = try self.gpa.alloc(IdRef, @as(u32, @intCast(ty.arrayLenIncludingSentinel(mod))));
746 defer self.gpa.free(constituents);
747
748 switch (aggregate.storage) {
749 .bytes => |bytes| {
750 // TODO: This is really space inefficient, perhaps there is a better
751 // way to do it?
752 for (bytes, 0..) |byte, i| {
753 constituents[i] = try self.constInt(elem_ty_ref, byte);
754 }
755 },
756 .elems => |elems| {
757 for (0..@as(usize, @intCast(array_type.len))) |i| {
758 constituents[i] = try self.constant(elem_ty, elems[i].toValue(), .indirect);
759 }
760 },
761 .repeated_elem => |elem| {
762 const val_id = try self.constant(elem_ty, elem.toValue(), .indirect);
763 for (0..@as(usize, @intCast(array_type.len))) |i| {
764 constituents[i] = val_id;
765 }
766 },
767 }
768 if (array_type.sentinel != .none) {
769 constituents[constituents.len - 1] = try self.constant(elem_ty, array_type.sentinel.toValue(), .indirect);
770 }
771 return try self.constructArray(result_ty_ref, constituents);
772 },
773 .struct_type => {
774 const struct_type = mod.typeToStruct(ty).?;
775 if (struct_type.layout == .Packed) {
776 return self.todo("packed struct constants", .{});
777 }
778
779 var constituents = std.ArrayList(IdRef).init(self.gpa);
780 defer constituents.deinit();
781
782 var it = struct_type.iterateRuntimeOrder(ip);
783 while (it.next()) |field_index| {
784 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
785 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
786 // This is a zero-bit field - we only needed it for the alignment.
787 continue;
788 }
789
790 // TODO: Padding?
791 const field_val = try val.fieldValue(mod, field_index);
792 const field_id = try self.constant(field_ty, field_val, .indirect);
1105793
1106 try self.func.body.emit(self.spv.gpa, .OpLoad, .{794 try constituents.append(field_id);
795 }
796
797 return try self.constructStruct(result_ty_ref, constituents.items);
798 },
799 .vector_type, .anon_struct_type => unreachable, // TODO
800 else => unreachable,
801 },
802 .un => |un| {
803 const active_field = ty.unionTagFieldIndex(un.tag.toValue(), mod).?;
804 const layout = self.unionLayout(ty, active_field);
805 const payload = if (layout.active_field_size != 0)
806 try self.constant(layout.active_field_ty, un.val.toValue(), .indirect)
807 else
808 null;
809
810 return try self.unionInit(ty, active_field, payload);
811 },
812 .memoized_call => unreachable,
813 }
814 }
815
816 fn constantPtr(self: *DeclGen, ptr_ty: Type, ptr_val: Value) Error!IdRef {
817 const result_ty_ref = try self.resolveType(ptr_ty, .direct);
818 const mod = self.module;
819 switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
820 .decl => |decl| return try self.constructDeclRef(ptr_ty, decl),
821 .mut_decl => |decl_mut| return try self.constructDeclRef(ptr_ty, decl_mut.decl),
822 .int => |int| {
823 const ptr_id = self.spv.allocId();
824 // TODO: This can probably be an OpSpecConstantOp Bitcast, but
825 // that is not implemented by Mesa yet. Therefore, just generate it
826 // as a runtime operation.
827 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
1107 .id_result_type = self.typeId(result_ty_ref),828 .id_result_type = self.typeId(result_ty_ref),
1108 .id_result = result_id,829 .id_result = ptr_id,
1109 .pointer = self.spv.declPtr(spv_decl_index).result_id,830 .integer_value = try self.constant(Type.usize, int.toValue(), .direct),
1110 });831 });
1111 // TODO: Convert bools? This logic should hook into `load`. It should be a dead832 return ptr_id;
1112 // path though considering .Bool is handled above.833 },
1113 return result_id;834 .eu_payload => unreachable, // TODO
835 .opt_payload => unreachable, // TODO
836 .comptime_field => unreachable,
837 .elem => |elem_ptr| {
838 const elem_ptr_ty = mod.intern_pool.typeOf(elem_ptr.base).toType();
839 const parent_ptr_id = try self.constantPtr(elem_ptr_ty, elem_ptr.base.toValue());
840 const size_ty_ref = try self.sizeType();
841 const index_id = try self.constInt(size_ty_ref, elem_ptr.index);
842 return self.ptrAccessChain(result_ty_ref, parent_ptr_id, index_id, &.{});
1114 },843 },
844 .field => unreachable, // TODO
1115 }845 }
1116 }846 }
1117847
848 // Turn a Zig type's name into a cache reference.
849 fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString {
850 var name = std.ArrayList(u8).init(self.gpa);
851 defer name.deinit();
852 try ty.print(name.writer(), self.module);
853 return try self.spv.resolveString(name.items);
854 }
855
1118 /// Turn a Zig type into a SPIR-V Type, and return its type result-id.856 /// Turn a Zig type into a SPIR-V Type, and return its type result-id.
1119 fn resolveTypeId(self: *DeclGen, ty: Type) !IdResultType {857 fn resolveTypeId(self: *DeclGen, ty: Type) !IdResultType {
1120 const type_ref = try self.resolveType(ty, .direct);858 const type_ref = try self.resolveType(ty, .direct);
...@@ -1135,7 +873,9 @@ pub const DeclGen = struct {...@@ -1135,7 +873,9 @@ pub const DeclGen = struct {
1135 // An array of largestSupportedIntBits.873 // An array of largestSupportedIntBits.
1136 return self.todo("Implement {s} composite int type of {} bits", .{ @tagName(signedness), bits });874 return self.todo("Implement {s} composite int type of {} bits", .{ @tagName(signedness), bits });
1137 };875 };
1138 return self.spv.intType(signedness, backing_bits);876 // Kernel only supports unsigned ints.
877 // TODO: Only do this with Kernels
878 return self.spv.intType(.unsigned, backing_bits);
1139 }879 }
1140880
1141 /// Create an integer type that represents 'usize'.881 /// Create an integer type that represents 'usize'.
...@@ -1168,71 +908,70 @@ pub const DeclGen = struct {...@@ -1168,71 +908,70 @@ pub const DeclGen = struct {
1168 fn resolveUnionType(self: *DeclGen, ty: Type, maybe_active_field: ?usize) !CacheRef {908 fn resolveUnionType(self: *DeclGen, ty: Type, maybe_active_field: ?usize) !CacheRef {
1169 const mod = self.module;909 const mod = self.module;
1170 const ip = &mod.intern_pool;910 const ip = &mod.intern_pool;
1171 const layout = ty.unionGetLayout(mod);
1172 const union_obj = mod.typeToUnion(ty).?;911 const union_obj = mod.typeToUnion(ty).?;
1173912
1174 if (union_obj.getLayout(ip) == .Packed) {913 if (union_obj.getLayout(ip) == .Packed) {
1175 return self.todo("packed union types", .{});914 return self.todo("packed union types", .{});
1176 }915 }
1177916
917 const layout = self.unionLayout(ty, maybe_active_field);
918
1178 if (layout.payload_size == 0) {919 if (layout.payload_size == 0) {
1179 // No payload, so represent this as just the tag type.920 // No payload, so represent this as just the tag type.
1180 return try self.resolveType(union_obj.enum_tag_ty.toType(), .indirect);921 return try self.resolveType(union_obj.enum_tag_ty.toType(), .indirect);
1181 }922 }
1182923
1183 var member_types = std.BoundedArray(CacheRef, 4){};924 // TODO: We need to add the active field to the key, somehow.
1184 var member_names = std.BoundedArray(CacheString, 4){};925 if (maybe_active_field == null) {
926 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
927 }
928
929 var member_types: [4]CacheRef = undefined;
930 var member_names: [4]CacheString = undefined;
1185931
1186 const has_tag = layout.tag_size != 0;
1187 const tag_first = layout.tag_align.compare(.gte, layout.payload_align);
1188 const u8_ty_ref = try self.intType(.unsigned, 8); // TODO: What if Int8Type is not enabled?932 const u8_ty_ref = try self.intType(.unsigned, 8); // TODO: What if Int8Type is not enabled?
1189933
1190 if (has_tag and tag_first) {934 if (layout.tag_size != 0) {
1191 const tag_ty_ref = try self.resolveType(union_obj.enum_tag_ty.toType(), .indirect);935 const tag_ty_ref = try self.resolveType(union_obj.enum_tag_ty.toType(), .indirect);
1192 member_types.appendAssumeCapacity(tag_ty_ref);936 member_types[layout.tag_index] = tag_ty_ref;
1193 member_names.appendAssumeCapacity(try self.spv.resolveString("tag"));937 member_names[layout.tag_index] = try self.spv.resolveString("(tag)");
1194 }938 }
1195939
1196 const active_field = maybe_active_field orelse layout.most_aligned_field;940 if (layout.active_field_size != 0) {
1197 const active_field_ty = union_obj.field_types.get(ip)[active_field].toType();941 const active_payload_ty_ref = try self.resolveType(layout.active_field_ty, .indirect);
1198942 member_types[layout.active_field_index] = active_payload_ty_ref;
1199 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod)) blk: {943 member_names[layout.active_field_index] = try self.spv.resolveString("(payload)");
1200 const active_payload_ty_ref = try self.resolveType(active_field_ty, .indirect);
1201 member_types.appendAssumeCapacity(active_payload_ty_ref);
1202 member_names.appendAssumeCapacity(try self.spv.resolveString("payload"));
1203 break :blk active_field_ty.abiSize(mod);
1204 } else 0;
1205
1206 const payload_padding_len = layout.payload_size - active_field_size;
1207 if (payload_padding_len != 0) {
1208 const payload_padding_ty_ref = try self.spv.arrayType(@as(u32, @intCast(payload_padding_len)), u8_ty_ref);
1209 member_types.appendAssumeCapacity(payload_padding_ty_ref);
1210 member_names.appendAssumeCapacity(try self.spv.resolveString("payload_padding"));
1211 }944 }
1212945
1213 if (has_tag and !tag_first) {946 if (layout.payload_padding_size != 0) {
1214 const tag_ty_ref = try self.resolveType(union_obj.enum_tag_ty.toType(), .indirect);947 const payload_padding_ty_ref = try self.spv.arrayType(@intCast(layout.payload_padding_size), u8_ty_ref);
1215 member_types.appendAssumeCapacity(tag_ty_ref);948 member_types[layout.payload_padding_index] = payload_padding_ty_ref;
1216 member_names.appendAssumeCapacity(try self.spv.resolveString("tag"));949 member_names[layout.payload_padding_index] = try self.spv.resolveString("(payload padding)");
1217 }950 }
1218951
1219 if (layout.padding != 0) {952 if (layout.padding_size != 0) {
1220 const padding_ty_ref = try self.spv.arrayType(layout.padding, u8_ty_ref);953 const padding_ty_ref = try self.spv.arrayType(@intCast(layout.padding_size), u8_ty_ref);
1221 member_types.appendAssumeCapacity(padding_ty_ref);954 member_types[layout.padding_index] = padding_ty_ref;
1222 member_names.appendAssumeCapacity(try self.spv.resolveString("padding"));955 member_names[layout.padding_index] = try self.spv.resolveString("(padding)");
1223 }956 }
1224957
1225 return try self.spv.resolve(.{ .struct_type = .{958 const ty_ref = try self.spv.resolve(.{ .struct_type = .{
1226 .member_types = member_types.slice(),959 .name = try self.resolveTypeName(ty),
1227 .member_names = member_names.slice(),960 .member_types = member_types[0..layout.total_fields],
961 .member_names = member_names[0..layout.total_fields],
1228 } });962 } });
963
964 if (maybe_active_field == null) {
965 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
966 }
967 return ty_ref;
1229 }968 }
1230969
1231 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.970 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
1232 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {971 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {
1233 const mod = self.module;972 const mod = self.module;
1234 const ip = &mod.intern_pool;973 const ip = &mod.intern_pool;
1235 log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});974 log.debug("resolveType: ty = {}", .{ty.fmt(mod)});
1236 const target = self.getTarget();975 const target = self.getTarget();
1237 switch (ty.zigTypeTag(mod)) {976 switch (ty.zigTypeTag(mod)) {
1238 .Void, .NoReturn => return try self.spv.resolve(.void_type),977 .Void, .NoReturn => return try self.spv.resolve(.void_type),
...@@ -1242,6 +981,7 @@ pub const DeclGen = struct {...@@ -1242,6 +981,7 @@ pub const DeclGen = struct {
1242 },981 },
1243 .Int => {982 .Int => {
1244 const int_info = ty.intInfo(mod);983 const int_info = ty.intInfo(mod);
984 // TODO: Integers in OpenCL kernels are always unsigned.
1245 return try self.intType(int_info.signedness, int_info.bits);985 return try self.intType(int_info.signedness, int_info.bits);
1246 },986 },
1247 .Enum => {987 .Enum => {
...@@ -1267,15 +1007,21 @@ pub const DeclGen = struct {...@@ -1267,15 +1007,21 @@ pub const DeclGen = struct {
1267 return try self.spv.resolve(.{ .float_type = .{ .bits = bits } });1007 return try self.spv.resolve(.{ .float_type = .{ .bits = bits } });
1268 },1008 },
1269 .Array => {1009 .Array => {
1010 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
1011
1270 const elem_ty = ty.childType(mod);1012 const elem_ty = ty.childType(mod);
1271 const elem_ty_ref = try self.resolveType(elem_ty, .direct);1013 const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
1272 const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(mod)) orelse {1014 const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(mod)) orelse {
1273 return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)});1015 return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)});
1274 };1016 };
1275 return self.spv.arrayType(total_len, elem_ty_ref);1017 const ty_ref = try self.spv.arrayType(total_len, elem_ty_ref);
1018 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1019 return ty_ref;
1276 },1020 },
1277 .Fn => switch (repr) {1021 .Fn => switch (repr) {
1278 .direct => {1022 .direct => {
1023 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
1024
1279 const fn_info = mod.typeToFunc(ty).?;1025 const fn_info = mod.typeToFunc(ty).?;
1280 // TODO: Put this somewhere in Sema.zig1026 // TODO: Put this somewhere in Sema.zig
1281 if (fn_info.is_var_args)1027 if (fn_info.is_var_args)
...@@ -1288,10 +1034,13 @@ pub const DeclGen = struct {...@@ -1288,10 +1034,13 @@ pub const DeclGen = struct {
1288 }1034 }
1289 const return_ty_ref = try self.resolveType(fn_info.return_type.toType(), .direct);1035 const return_ty_ref = try self.resolveType(fn_info.return_type.toType(), .direct);
12901036
1291 return try self.spv.resolve(.{ .function_type = .{1037 const ty_ref = try self.spv.resolve(.{ .function_type = .{
1292 .return_type = return_ty_ref,1038 .return_type = return_ty_ref,
1293 .parameters = param_ty_refs,1039 .parameters = param_ty_refs,
1294 } });1040 } });
1041
1042 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1043 return ty_ref;
1295 },1044 },
1296 .indirect => {1045 .indirect => {
1297 // TODO: Represent function pointers properly.1046 // TODO: Represent function pointers properly.
...@@ -1337,6 +1086,8 @@ pub const DeclGen = struct {...@@ -1337,6 +1086,8 @@ pub const DeclGen = struct {
1337 } });1086 } });
1338 },1087 },
1339 .Struct => {1088 .Struct => {
1089 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
1090
1340 const struct_type = switch (ip.indexToKey(ty.toIntern())) {1091 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1341 .anon_struct_type => |tuple| {1092 .anon_struct_type => |tuple| {
1342 const member_types = try self.gpa.alloc(CacheRef, tuple.values.len);1093 const member_types = try self.gpa.alloc(CacheRef, tuple.values.len);
...@@ -1350,9 +1101,13 @@ pub const DeclGen = struct {...@@ -1350,9 +1101,13 @@ pub const DeclGen = struct {
1350 member_index += 1;1101 member_index += 1;
1351 }1102 }
13521103
1353 return try self.spv.resolve(.{ .struct_type = .{1104 const ty_ref = try self.spv.resolve(.{ .struct_type = .{
1105 .name = try self.resolveTypeName(ty),
1354 .member_types = member_types[0..member_index],1106 .member_types = member_types[0..member_index],
1355 } });1107 } });
1108
1109 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1110 return ty_ref;
1356 },1111 },
1357 .struct_type => |struct_type| struct_type,1112 .struct_type => |struct_type| struct_type,
1358 else => unreachable,1113 else => unreachable,
...@@ -1376,13 +1131,14 @@ pub const DeclGen = struct {...@@ -1376,13 +1131,14 @@ pub const DeclGen = struct {
1376 try member_names.append(try self.spv.resolveString(field_name));1131 try member_names.append(try self.spv.resolveString(field_name));
1377 }1132 }
13781133
1379 const name = ip.stringToSlice(try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod));1134 const ty_ref = try self.spv.resolve(.{ .struct_type = .{
13801135 .name = try self.resolveTypeName(ty),
1381 return try self.spv.resolve(.{ .struct_type = .{
1382 .name = try self.spv.resolveString(name),
1383 .member_types = member_types.items,1136 .member_types = member_types.items,
1384 .member_names = member_names.items,1137 .member_names = member_names.items,
1385 } });1138 } });
1139
1140 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1141 return ty_ref;
1386 },1142 },
1387 .Optional => {1143 .Optional => {
1388 const payload_ty = ty.optionalChild(mod);1144 const payload_ty = ty.optionalChild(mod);
...@@ -1399,15 +1155,20 @@ pub const DeclGen = struct {...@@ -1399,15 +1155,20 @@ pub const DeclGen = struct {
1399 return payload_ty_ref;1155 return payload_ty_ref;
1400 }1156 }
14011157
1158 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
1159
1402 const bool_ty_ref = try self.resolveType(Type.bool, .indirect);1160 const bool_ty_ref = try self.resolveType(Type.bool, .indirect);
14031161
1404 return try self.spv.resolve(.{ .struct_type = .{1162 const ty_ref = try self.spv.resolve(.{ .struct_type = .{
1405 .member_types = &.{ payload_ty_ref, bool_ty_ref },1163 .member_types = &.{ payload_ty_ref, bool_ty_ref },
1406 .member_names = &.{1164 .member_names = &.{
1407 try self.spv.resolveString("payload"),1165 try self.spv.resolveString("payload"),
1408 try self.spv.resolveString("valid"),1166 try self.spv.resolveString("valid"),
1409 },1167 },
1410 } });1168 } });
1169
1170 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1171 return ty_ref;
1411 },1172 },
1412 .Union => return try self.resolveUnionType(ty, null),1173 .Union => return try self.resolveUnionType(ty, null),
1413 .ErrorSet => return try self.intType(.unsigned, 16),1174 .ErrorSet => return try self.intType(.unsigned, 16),
...@@ -1420,6 +1181,8 @@ pub const DeclGen = struct {...@@ -1420,6 +1181,8 @@ pub const DeclGen = struct {
1420 return error_ty_ref;1181 return error_ty_ref;
1421 }1182 }
14221183
1184 if (self.type_map.get(ty.toIntern())) |info| return info.ty_ref;
1185
1423 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);1186 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
14241187
1425 var member_types: [2]CacheRef = undefined;1188 var member_types: [2]CacheRef = undefined;
...@@ -1442,10 +1205,14 @@ pub const DeclGen = struct {...@@ -1442,10 +1205,14 @@ pub const DeclGen = struct {
1442 // TODO: ABI padding?1205 // TODO: ABI padding?
1443 }1206 }
14441207
1445 return try self.spv.resolve(.{ .struct_type = .{1208 const ty_ref = try self.spv.resolve(.{ .struct_type = .{
1209 .name = try self.resolveTypeName(ty),
1446 .member_types = &member_types,1210 .member_types = &member_types,
1447 .member_names = &member_names,1211 .member_names = &member_names,
1448 } });1212 } });
1213
1214 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
1215 return ty_ref;
1449 },1216 },
14501217
1451 .Null,1218 .Null,
...@@ -1509,6 +1276,85 @@ pub const DeclGen = struct {...@@ -1509,6 +1276,85 @@ pub const DeclGen = struct {
1509 };1276 };
1510 }1277 }
15111278
1279 const UnionLayout = struct {
1280 active_field: u32,
1281 active_field_ty: Type,
1282 payload_size: u32,
1283
1284 tag_size: u32,
1285 tag_index: u32,
1286 active_field_size: u32,
1287 active_field_index: u32,
1288 payload_padding_size: u32,
1289 payload_padding_index: u32,
1290 padding_size: u32,
1291 padding_index: u32,
1292 total_fields: u32,
1293 };
1294
1295 fn unionLayout(self: *DeclGen, ty: Type, maybe_active_field: ?usize) UnionLayout {
1296 const mod = self.module;
1297 const ip = &mod.intern_pool;
1298 const layout = ty.unionGetLayout(self.module);
1299 const union_obj = mod.typeToUnion(ty).?;
1300
1301 const active_field = maybe_active_field orelse layout.most_aligned_field;
1302 const active_field_ty = union_obj.field_types.get(ip)[active_field].toType();
1303
1304 var union_layout = UnionLayout{
1305 .active_field = @intCast(active_field),
1306 .active_field_ty = active_field_ty,
1307 .payload_size = @intCast(layout.payload_size),
1308 .tag_size = @intCast(layout.tag_size),
1309 .tag_index = undefined,
1310 .active_field_size = undefined,
1311 .active_field_index = undefined,
1312 .payload_padding_size = undefined,
1313 .payload_padding_index = undefined,
1314 .padding_size = @intCast(layout.padding),
1315 .padding_index = undefined,
1316 .total_fields = undefined,
1317 };
1318
1319 union_layout.active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod))
1320 @intCast(active_field_ty.abiSize(mod))
1321 else
1322 0;
1323 union_layout.payload_padding_size = @intCast(layout.payload_size - union_layout.active_field_size);
1324
1325 const tag_first = layout.tag_align.compare(.gte, layout.payload_align);
1326 var field_index: u32 = 0;
1327
1328 if (union_layout.tag_size != 0 and tag_first) {
1329 union_layout.tag_index = field_index;
1330 field_index += 1;
1331 }
1332
1333 if (union_layout.active_field_size != 0) {
1334 union_layout.active_field_index = field_index;
1335 field_index += 1;
1336 }
1337
1338 if (union_layout.payload_padding_size != 0) {
1339 union_layout.payload_padding_index = field_index;
1340 field_index += 1;
1341 }
1342
1343 if (union_layout.tag_size != 0 and !tag_first) {
1344 union_layout.tag_index = field_index;
1345 field_index += 1;
1346 }
1347
1348 if (union_layout.padding_size != 0) {
1349 union_layout.padding_index = field_index;
1350 field_index += 1;
1351 }
1352
1353 union_layout.total_fields = field_index;
1354
1355 return union_layout;
1356 }
1357
1512 /// The SPIR-V backend is not yet advanced enough to support the std testing infrastructure.1358 /// The SPIR-V backend is not yet advanced enough to support the std testing infrastructure.
1513 /// In order to be able to run tests, we "temporarily" lower test kernels into separate entry-1359 /// In order to be able to run tests, we "temporarily" lower test kernels into separate entry-
1514 /// points. The test executor will then be able to invoke these to run the tests.1360 /// points. The test executor will then be able to invoke these to run the tests.
...@@ -1588,6 +1434,8 @@ pub const DeclGen = struct {...@@ -1588,6 +1434,8 @@ pub const DeclGen = struct {
15881434
1589 const decl_id = self.spv.declPtr(spv_decl_index).result_id;1435 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
15901436
1437 try self.base_line_stack.append(self.gpa, decl.src_line);
1438
1591 if (decl.val.getFunction(mod)) |_| {1439 if (decl.val.getFunction(mod)) |_| {
1592 assert(decl.ty.zigTypeTag(mod) == .Fn);1440 assert(decl.ty.zigTypeTag(mod) == .Fn);
1593 const prototype_id = try self.resolveTypeId(decl.ty);1441 const prototype_id = try self.resolveTypeId(decl.ty);
...@@ -1630,11 +1478,7 @@ pub const DeclGen = struct {...@@ -1630,11 +1478,7 @@ pub const DeclGen = struct {
1630 try self.spv.addFunction(spv_decl_index, self.func);1478 try self.spv.addFunction(spv_decl_index, self.func);
16311479
1632 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));1480 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));
16331481 try self.spv.debugName(decl_id, fqn);
1634 try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{
1635 .target = decl_id,
1636 .name = fqn,
1637 });
16381482
1639 // Temporarily generate a test kernel declaration if this is a test function.1483 // Temporarily generate a test kernel declaration if this is a test function.
1640 if (self.module.test_functions.contains(self.decl_index)) {1484 if (self.module.test_functions.contains(self.decl_index)) {
...@@ -1650,28 +1494,69 @@ pub const DeclGen = struct {...@@ -1650,28 +1494,69 @@ pub const DeclGen = struct {
1650 return self.todo("importing extern variables", .{});1494 return self.todo("importing extern variables", .{});
1651 }1495 }
16521496
1653 // TODO: integrate with variable().1497 // Currently, initializers for CrossWorkgroup variables is not implemented
1498 // in Mesa. Therefore we generate an initialization kernel instead.
16541499
1500 const void_ty_ref = try self.resolveType(Type.void, .direct);
1501
1502 const initializer_proto_ty_ref = try self.spv.resolve(.{ .function_type = .{
1503 .return_type = void_ty_ref,
1504 .parameters = &.{},
1505 } });
1506
1507 // Generate the actual variable for the global...
1655 const final_storage_class = spvStorageClass(decl.@"addrspace");1508 const final_storage_class = spvStorageClass(decl.@"addrspace");
1656 const actual_storage_class = switch (final_storage_class) {1509 const actual_storage_class = switch (final_storage_class) {
1657 .Generic => .CrossWorkgroup,1510 .Generic => .CrossWorkgroup,
1658 else => final_storage_class,1511 else => final_storage_class,
1659 };1512 };
16601513
1661 try self.lowerIndirectConstant(1514 const ty_ref = try self.resolveType(decl.ty, .indirect);
1662 spv_decl_index,1515 const ptr_ty_ref = try self.spv.ptrType(ty_ref, actual_storage_class);
1663 decl.ty,1516
1664 init_val,1517 const begin = self.spv.beginGlobal();
1665 actual_storage_class,1518 try self.spv.globals.section.emit(self.spv.gpa, .OpVariable, .{
1666 final_storage_class == .Generic,1519 .id_result_type = self.typeId(ptr_ty_ref),
1667 @intCast(decl.alignment.toByteUnits(0)),1520 .id_result = decl_id,
1668 );1521 .storage_class = actual_storage_class,
1522 });
1523
1524 // Now emit the instructions that initialize the variable.
1525 const initializer_id = self.spv.allocId();
1526 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
1527 .id_result_type = self.typeId(void_ty_ref),
1528 .id_result = initializer_id,
1529 .function_control = .{},
1530 .function_type = self.typeId(initializer_proto_ty_ref),
1531 });
1532 const root_block_id = self.spv.allocId();
1533 try self.func.prologue.emit(self.spv.gpa, .OpLabel, .{
1534 .id_result = root_block_id,
1535 });
1536 self.current_block_label_id = root_block_id;
1537
1538 const val_id = try self.constant(decl.ty, init_val, .indirect);
1539 try self.func.body.emit(self.spv.gpa, .OpStore, .{
1540 .pointer = decl_id,
1541 .object = val_id,
1542 });
1543
1544 // TODO: We should be able to get rid of this by now...
1545 self.spv.endGlobal(spv_decl_index, begin, decl_id, initializer_id);
1546
1547 try self.func.body.emit(self.spv.gpa, .OpReturn, {});
1548 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
1549 try self.spv.addFunction(spv_decl_index, self.func);
1550
1551 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));
1552 try self.spv.debugName(decl_id, fqn);
1553 try self.spv.debugNameFmt(initializer_id, "initializer of {s}", .{fqn});
1669 }1554 }
1670 }1555 }
16711556
1672 fn intFromBool(self: *DeclGen, result_ty_ref: CacheRef, condition_id: IdRef) !IdRef {1557 fn intFromBool(self: *DeclGen, result_ty_ref: CacheRef, condition_id: IdRef) !IdRef {
1673 const zero_id = try self.spv.constInt(result_ty_ref, 0);1558 const zero_id = try self.constInt(result_ty_ref, 0);
1674 const one_id = try self.spv.constInt(result_ty_ref, 1);1559 const one_id = try self.constInt(result_ty_ref, 1);
1675 const result_id = self.spv.allocId();1560 const result_id = self.spv.allocId();
1676 try self.func.body.emit(self.spv.gpa, .OpSelect, .{1561 try self.func.body.emit(self.spv.gpa, .OpSelect, .{
1677 .id_result_type = self.typeId(result_ty_ref),1562 .id_result_type = self.typeId(result_ty_ref),
...@@ -1691,7 +1576,7 @@ pub const DeclGen = struct {...@@ -1691,7 +1576,7 @@ pub const DeclGen = struct {
1691 .Bool => blk: {1576 .Bool => blk: {
1692 const direct_bool_ty_ref = try self.resolveType(ty, .direct);1577 const direct_bool_ty_ref = try self.resolveType(ty, .direct);
1693 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);1578 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
1694 const zero_id = try self.spv.constInt(indirect_bool_ty_ref, 0);1579 const zero_id = try self.constInt(indirect_bool_ty_ref, 0);
1695 const result_id = self.spv.allocId();1580 const result_id = self.spv.allocId();
1696 try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{1581 try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{
1697 .id_result_type = self.typeId(direct_bool_ty_ref),1582 .id_result_type = self.typeId(direct_bool_ty_ref),
...@@ -1732,13 +1617,11 @@ pub const DeclGen = struct {...@@ -1732,13 +1617,11 @@ pub const DeclGen = struct {
1732 return try self.convertToDirect(result_ty, result_id);1617 return try self.convertToDirect(result_ty, result_id);
1733 }1618 }
17341619
1735 fn load(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef) !IdRef {1620 fn load(self: *DeclGen, value_ty: Type, ptr_id: IdRef, is_volatile: bool) !IdRef {
1736 const mod = self.module;
1737 const value_ty = ptr_ty.childType(mod);
1738 const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect);1621 const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect);
1739 const result_id = self.spv.allocId();1622 const result_id = self.spv.allocId();
1740 const access = spec.MemoryAccess.Extended{1623 const access = spec.MemoryAccess.Extended{
1741 .Volatile = ptr_ty.isVolatilePtr(mod),1624 .Volatile = is_volatile,
1742 };1625 };
1743 try self.func.body.emit(self.spv.gpa, .OpLoad, .{1626 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
1744 .id_result_type = self.typeId(indirect_value_ty_ref),1627 .id_result_type = self.typeId(indirect_value_ty_ref),
...@@ -1749,12 +1632,10 @@ pub const DeclGen = struct {...@@ -1749,12 +1632,10 @@ pub const DeclGen = struct {
1749 return try self.convertToDirect(value_ty, result_id);1632 return try self.convertToDirect(value_ty, result_id);
1750 }1633 }
17511634
1752 fn store(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, value_id: IdRef) !void {1635 fn store(self: *DeclGen, value_ty: Type, ptr_id: IdRef, value_id: IdRef, is_volatile: bool) !void {
1753 const mod = self.module;
1754 const value_ty = ptr_ty.childType(mod);
1755 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);1636 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
1756 const access = spec.MemoryAccess.Extended{1637 const access = spec.MemoryAccess.Extended{
1757 .Volatile = ptr_ty.isVolatilePtr(mod),1638 .Volatile = is_volatile,
1758 };1639 };
1759 try self.func.body.emit(self.spv.gpa, .OpStore, .{1640 try self.func.body.emit(self.spv.gpa, .OpStore, .{
1760 .pointer = ptr_id,1641 .pointer = ptr_id,
...@@ -1795,7 +1676,8 @@ pub const DeclGen = struct {...@@ -1795,7 +1676,8 @@ pub const DeclGen = struct {
1795 .rem_optimized,1676 .rem_optimized,
1796 => try self.airArithOp(inst, .OpFRem, .OpSRem, .OpSRem, false),1677 => try self.airArithOp(inst, .OpFRem, .OpSRem, .OpSRem, false),
17971678
1798 .add_with_overflow => try self.airOverflowArithOp(inst),1679 .add_with_overflow => try self.airAddSubOverflow(inst, .OpIAdd, .OpULessThan, .OpSLessThan),
1680 .sub_with_overflow => try self.airAddSubOverflow(inst, .OpISub, .OpUGreaterThan, .OpSGreaterThan),
17991681
1800 .shuffle => try self.airShuffle(inst),1682 .shuffle => try self.airShuffle(inst),
18011683
...@@ -1812,19 +1694,27 @@ pub const DeclGen = struct {...@@ -1812,19 +1694,27 @@ pub const DeclGen = struct {
18121694
1813 .bitcast => try self.airBitCast(inst),1695 .bitcast => try self.airBitCast(inst),
1814 .intcast, .trunc => try self.airIntCast(inst),1696 .intcast, .trunc => try self.airIntCast(inst),
1815 .int_from_ptr => try self.airIntFromPtr(inst),1697 .int_from_ptr => try self.airIntFromPtr(inst),
1816 .float_from_int => try self.airFloatFromInt(inst),1698 .float_from_int => try self.airFloatFromInt(inst),
1817 .int_from_float => try self.airIntFromFloat(inst),1699 .int_from_float => try self.airIntFromFloat(inst),
1818 .not => try self.airNot(inst),1700 .not => try self.airNot(inst),
18191701
1702 .array_to_slice => try self.airArrayToSlice(inst),
1703 .slice => try self.airSlice(inst),
1704 .aggregate_init => try self.airAggregateInit(inst),
1705
1820 .slice_ptr => try self.airSliceField(inst, 0),1706 .slice_ptr => try self.airSliceField(inst, 0),
1821 .slice_len => try self.airSliceField(inst, 1),1707 .slice_len => try self.airSliceField(inst, 1),
1822 .slice_elem_ptr => try self.airSliceElemPtr(inst),1708 .slice_elem_ptr => try self.airSliceElemPtr(inst),
1823 .slice_elem_val => try self.airSliceElemVal(inst),1709 .slice_elem_val => try self.airSliceElemVal(inst),
1824 .ptr_elem_ptr => try self.airPtrElemPtr(inst),1710 .ptr_elem_ptr => try self.airPtrElemPtr(inst),
1825 .ptr_elem_val => try self.airPtrElemVal(inst),1711 .ptr_elem_val => try self.airPtrElemVal(inst),
1712 .array_elem_val => try self.airArrayElemVal(inst),
18261713
1714 .set_union_tag => return try self.airSetUnionTag(inst),
1827 .get_union_tag => try self.airGetUnionTag(inst),1715 .get_union_tag => try self.airGetUnionTag(inst),
1716 .union_init => try self.airUnionInit(inst),
1717
1828 .struct_field_val => try self.airStructFieldVal(inst),1718 .struct_field_val => try self.airStructFieldVal(inst),
18291719
1830 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),1720 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
...@@ -1851,7 +1741,6 @@ pub const DeclGen = struct {...@@ -1851,7 +1741,6 @@ pub const DeclGen = struct {
1851 .br => return self.airBr(inst),1741 .br => return self.airBr(inst),
1852 .breakpoint => return,1742 .breakpoint => return,
1853 .cond_br => return self.airCondBr(inst),1743 .cond_br => return self.airCondBr(inst),
1854 .dbg_stmt => return self.airDbgStmt(inst),
1855 .loop => return self.airLoop(inst),1744 .loop => return self.airLoop(inst),
1856 .ret => return self.airRet(inst),1745 .ret => return self.airRet(inst),
1857 .ret_load => return self.airRetLoad(inst),1746 .ret_load => return self.airRetLoad(inst),
...@@ -1859,11 +1748,22 @@ pub const DeclGen = struct {...@@ -1859,11 +1748,22 @@ pub const DeclGen = struct {
1859 .switch_br => return self.airSwitchBr(inst),1748 .switch_br => return self.airSwitchBr(inst),
1860 .unreach, .trap => return self.airUnreach(),1749 .unreach, .trap => return self.airUnreach(),
18611750
1751 .dbg_stmt => return self.airDbgStmt(inst),
1752 .dbg_inline_begin => return self.airDbgInlineBegin(inst),
1753 .dbg_inline_end => return self.airDbgInlineEnd(inst),
1754 .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst),
1755 .dbg_block_begin => return,
1756 .dbg_block_end => return,
1757
1862 .unwrap_errunion_err => try self.airErrUnionErr(inst),1758 .unwrap_errunion_err => try self.airErrUnionErr(inst),
1759 .unwrap_errunion_payload => try self.airErrUnionPayload(inst),
1863 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),1760 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
1761 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
18641762
1865 .is_null => try self.airIsNull(inst, .is_null),1763 .is_null => try self.airIsNull(inst, .is_null),
1866 .is_non_null => try self.airIsNull(inst, .is_non_null),1764 .is_non_null => try self.airIsNull(inst, .is_non_null),
1765 .is_err => try self.airIsErr(inst, .is_err),
1766 .is_non_err => try self.airIsErr(inst, .is_non_err),
18671767
1868 .optional_payload => try self.airUnwrapOptional(inst),1768 .optional_payload => try self.airUnwrapOptional(inst),
1869 .wrap_optional => try self.airWrapOptional(inst),1769 .wrap_optional => try self.airWrapOptional(inst),
...@@ -1874,13 +1774,6 @@ pub const DeclGen = struct {...@@ -1874,13 +1774,6 @@ pub const DeclGen = struct {
1874 .call_always_tail => try self.airCall(inst, .always_tail),1774 .call_always_tail => try self.airCall(inst, .always_tail),
1875 .call_never_tail => try self.airCall(inst, .never_tail),1775 .call_never_tail => try self.airCall(inst, .never_tail),
1876 .call_never_inline => try self.airCall(inst, .never_inline),1776 .call_never_inline => try self.airCall(inst, .never_inline),
1877
1878 .dbg_inline_begin => return,
1879 .dbg_inline_end => return,
1880 .dbg_var_ptr => return,
1881 .dbg_var_val => return,
1882 .dbg_block_begin => return,
1883 .dbg_block_end => return,
1884 // zig fmt: on1777 // zig fmt: on
18851778
1886 else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}),1779 else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}),
...@@ -1934,7 +1827,7 @@ pub const DeclGen = struct {...@@ -1934,7 +1827,7 @@ pub const DeclGen = struct {
1934 fn maskStrangeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, bits: u16) !IdRef {1827 fn maskStrangeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, bits: u16) !IdRef {
1935 const mask_value = if (bits == 64) 0xFFFF_FFFF_FFFF_FFFF else (@as(u64, 1) << @as(u6, @intCast(bits))) - 1;1828 const mask_value = if (bits == 64) 0xFFFF_FFFF_FFFF_FFFF else (@as(u64, 1) << @as(u6, @intCast(bits))) - 1;
1936 const result_id = self.spv.allocId();1829 const result_id = self.spv.allocId();
1937 const mask_id = try self.spv.constInt(ty_ref, mask_value);1830 const mask_id = try self.constInt(ty_ref, mask_value);
1938 try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{1831 try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{
1939 .id_result_type = self.typeId(ty_ref),1832 .id_result_type = self.typeId(ty_ref),
1940 .id_result = result_id,1833 .id_result = result_id,
...@@ -2012,7 +1905,13 @@ pub const DeclGen = struct {...@@ -2012,7 +1905,13 @@ pub const DeclGen = struct {
2012 return result_id;1905 return result_id;
2013 }1906 }
20141907
2015 fn airOverflowArithOp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {1908 fn airAddSubOverflow(
1909 self: *DeclGen,
1910 inst: Air.Inst.Index,
1911 comptime add: Opcode,
1912 comptime ucmp: Opcode,
1913 comptime scmp: Opcode,
1914 ) !?IdRef {
2016 if (self.liveness.isUnused(inst)) return null;1915 if (self.liveness.isUnused(inst)) return null;
20171916
2018 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1917 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
...@@ -2044,7 +1943,7 @@ pub const DeclGen = struct {...@@ -2044,7 +1943,7 @@ pub const DeclGen = struct {
20441943
2045 // TODO: Operations other than addition.1944 // TODO: Operations other than addition.
2046 const value_id = self.spv.allocId();1945 const value_id = self.spv.allocId();
2047 try self.func.body.emit(self.spv.gpa, .OpIAdd, .{1946 try self.func.body.emit(self.spv.gpa, add, .{
2048 .id_result_type = operand_ty_id,1947 .id_result_type = operand_ty_id,
2049 .id_result = value_id,1948 .id_result = value_id,
2050 .operand_1 = lhs,1949 .operand_1 = lhs,
...@@ -2054,8 +1953,9 @@ pub const DeclGen = struct {...@@ -2054,8 +1953,9 @@ pub const DeclGen = struct {
2054 const overflowed_id = switch (info.signedness) {1953 const overflowed_id = switch (info.signedness) {
2055 .unsigned => blk: {1954 .unsigned => blk: {
2056 // Overflow happened if the result is smaller than either of the operands. It doesn't matter which.1955 // Overflow happened if the result is smaller than either of the operands. It doesn't matter which.
1956 // For subtraction the conditions need to be swapped.
2057 const overflowed_id = self.spv.allocId();1957 const overflowed_id = self.spv.allocId();
2058 try self.func.body.emit(self.spv.gpa, .OpULessThan, .{1958 try self.func.body.emit(self.spv.gpa, ucmp, .{
2059 .id_result_type = self.typeId(bool_ty_ref),1959 .id_result_type = self.typeId(bool_ty_ref),
2060 .id_result = overflowed_id,1960 .id_result = overflowed_id,
2061 .operand_1 = value_id,1961 .operand_1 = value_id,
...@@ -2064,16 +1964,25 @@ pub const DeclGen = struct {...@@ -2064,16 +1964,25 @@ pub const DeclGen = struct {
2064 break :blk overflowed_id;1964 break :blk overflowed_id;
2065 },1965 },
2066 .signed => blk: {1966 .signed => blk: {
2067 // Overflow happened if:1967 // lhs - rhs
1968 // For addition, overflow happened if:
2068 // - rhs is negative and value > lhs1969 // - rhs is negative and value > lhs
2069 // - rhs is positive and value < lhs1970 // - rhs is positive and value < lhs
2070 // This can be shortened to:1971 // This can be shortened to:
2071 // (rhs < 0 && value > lhs) || (rhs >= 0 && value <= lhs)1972 // (rhs < 0 and value > lhs) or (rhs >= 0 and value <= lhs)
2072 // = (rhs < 0) == (value > lhs)1973 // = (rhs < 0) == (value > lhs)
1974 // = (rhs < 0) == (lhs < value)
2073 // Note that signed overflow is also wrapping in spir-v.1975 // Note that signed overflow is also wrapping in spir-v.
1976 // For subtraction, overflow happened if:
1977 // - rhs is negative and value < lhs
1978 // - rhs is positive and value > lhs
1979 // This can be shortened to:
1980 // (rhs < 0 and value < lhs) or (rhs >= 0 and value >= lhs)
1981 // = (rhs < 0) == (value < lhs)
1982 // = (rhs < 0) == (lhs > value)
20741983
2075 const rhs_lt_zero_id = self.spv.allocId();1984 const rhs_lt_zero_id = self.spv.allocId();
2076 const zero_id = try self.spv.constInt(operand_ty_ref, 0);1985 const zero_id = try self.constInt(operand_ty_ref, 0);
2077 try self.func.body.emit(self.spv.gpa, .OpSLessThan, .{1986 try self.func.body.emit(self.spv.gpa, .OpSLessThan, .{
2078 .id_result_type = self.typeId(bool_ty_ref),1987 .id_result_type = self.typeId(bool_ty_ref),
2079 .id_result = rhs_lt_zero_id,1988 .id_result = rhs_lt_zero_id,
...@@ -2082,11 +1991,11 @@ pub const DeclGen = struct {...@@ -2082,11 +1991,11 @@ pub const DeclGen = struct {
2082 });1991 });
20831992
2084 const value_gt_lhs_id = self.spv.allocId();1993 const value_gt_lhs_id = self.spv.allocId();
2085 try self.func.body.emit(self.spv.gpa, .OpSGreaterThan, .{1994 try self.func.body.emit(self.spv.gpa, scmp, .{
2086 .id_result_type = self.typeId(bool_ty_ref),1995 .id_result_type = self.typeId(bool_ty_ref),
2087 .id_result = value_gt_lhs_id,1996 .id_result = value_gt_lhs_id,
2088 .operand_1 = value_id,1997 .operand_1 = lhs,
2089 .operand_2 = lhs,1998 .operand_2 = value_id,
2090 });1999 });
20912000
2092 const overflowed_id = self.spv.allocId();2001 const overflowed_id = self.spv.allocId();
...@@ -2146,40 +2055,65 @@ pub const DeclGen = struct {...@@ -2146,40 +2055,65 @@ pub const DeclGen = struct {
2146 return result_id;2055 return result_id;
2147 }2056 }
21482057
2149 /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective2058 fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef {
2150 /// difference lies in whether the resulting type of the first dereference will be the2059 const index_ty_ref = try self.intType(.unsigned, 32);
2151 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain2060 const ids = try self.gpa.alloc(IdRef, indices.len);
2152 /// is the latter and PtrAccessChain is the former.2061 errdefer self.gpa.free(ids);
2153 fn accessChain(2062 for (indices, ids) |index, *id| {
2063 id.* = try self.constInt(index_ty_ref, index);
2064 }
2065
2066 return ids;
2067 }
2068
2069 fn accessChainId(
2154 self: *DeclGen,2070 self: *DeclGen,
2155 result_ty_ref: CacheRef,2071 result_ty_ref: CacheRef,
2156 base: IdRef,2072 base: IdRef,
2157 indexes: []const IdRef,2073 indices: []const IdRef,
2158 ) !IdRef {2074 ) !IdRef {
2159 const result_id = self.spv.allocId();2075 const result_id = self.spv.allocId();
2160 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{2076 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2161 .id_result_type = self.typeId(result_ty_ref),2077 .id_result_type = self.typeId(result_ty_ref),
2162 .id_result = result_id,2078 .id_result = result_id,
2163 .base = base,2079 .base = base,
2164 .indexes = indexes,2080 .indexes = indices,
2165 });2081 });
2166 return result_id;2082 return result_id;
2167 }2083 }
21682084
2085 /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective
2086 /// difference lies in whether the resulting type of the first dereference will be the
2087 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain
2088 /// is the latter and PtrAccessChain is the former.
2089 fn accessChain(
2090 self: *DeclGen,
2091 result_ty_ref: CacheRef,
2092 base: IdRef,
2093 indices: []const u32,
2094 ) !IdRef {
2095 const ids = try self.indicesToIds(indices);
2096 defer self.gpa.free(ids);
2097 return try self.accessChainId(result_ty_ref, base, ids);
2098 }
2099
2169 fn ptrAccessChain(2100 fn ptrAccessChain(
2170 self: *DeclGen,2101 self: *DeclGen,
2171 result_ty_ref: CacheRef,2102 result_ty_ref: CacheRef,
2172 base: IdRef,2103 base: IdRef,
2173 element: IdRef,2104 element: IdRef,
2174 indexes: []const IdRef,2105 indices: []const u32,
2175 ) !IdRef {2106 ) !IdRef {
2107 const ids = try self.indicesToIds(indices);
2108 defer self.gpa.free(ids);
2109
2176 const result_id = self.spv.allocId();2110 const result_id = self.spv.allocId();
2177 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{2111 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2178 .id_result_type = self.typeId(result_ty_ref),2112 .id_result_type = self.typeId(result_ty_ref),
2179 .id_result = result_id,2113 .id_result = result_id,
2180 .base = base,2114 .base = base,
2181 .element = element,2115 .element = element,
2182 .indexes = indexes,2116 .indexes = ids,
2183 });2117 });
2184 return result_id;2118 return result_id;
2185 }2119 }
...@@ -2192,7 +2126,7 @@ pub const DeclGen = struct {...@@ -2192,7 +2126,7 @@ pub const DeclGen = struct {
2192 .One => {2126 .One => {
2193 // Pointer to array2127 // Pointer to array
2194 // TODO: Is this correct?2128 // TODO: Is this correct?
2195 return try self.accessChain(result_ty_ref, ptr_id, &.{offset_id});2129 return try self.accessChainId(result_ty_ref, ptr_id, &.{offset_id});
2196 },2130 },
2197 .C, .Many => {2131 .C, .Many => {
2198 return try self.ptrAccessChain(result_ty_ref, ptr_id, offset_id, &.{});2132 return try self.ptrAccessChain(result_ty_ref, ptr_id, offset_id, &.{});
...@@ -2294,8 +2228,8 @@ pub const DeclGen = struct {...@@ -2294,8 +2228,8 @@ pub const DeclGen = struct {
2294 .gte => .OpFOrdGreaterThanEqual,2228 .gte => .OpFOrdGreaterThanEqual,
2295 },2229 },
2296 .bool => break :opcode switch (op) {2230 .bool => break :opcode switch (op) {
2297 .eq => .OpIEqual,2231 .eq => .OpLogicalEqual,
2298 .neq => .OpINotEqual,2232 .neq => .OpLogicalNotEqual,
2299 else => unreachable,2233 else => unreachable,
2300 },2234 },
2301 .strange_integer => sign: {2235 .strange_integer => sign: {
...@@ -2491,16 +2425,110 @@ pub const DeclGen = struct {...@@ -2491,16 +2425,110 @@ pub const DeclGen = struct {
2491 if (self.liveness.isUnused(inst)) return null;2425 if (self.liveness.isUnused(inst)) return null;
2492 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2426 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2493 const operand_id = try self.resolve(ty_op.operand);2427 const operand_id = try self.resolve(ty_op.operand);
2428 const result_ty = self.typeOfIndex(inst);
2429 const result_ty_id = try self.resolveTypeId(result_ty);
2430 const info = try self.arithmeticTypeInfo(result_ty);
2431
2494 const result_id = self.spv.allocId();2432 const result_id = self.spv.allocId();
2495 const result_type_id = try self.resolveTypeId(Type.bool);2433 switch (info.class) {
2496 try self.func.body.emit(self.spv.gpa, .OpLogicalNot, .{2434 .bool => {
2497 .id_result_type = result_type_id,2435 try self.func.body.emit(self.spv.gpa, .OpLogicalNot, .{
2498 .id_result = result_id,2436 .id_result_type = result_ty_id,
2499 .operand = operand_id,2437 .id_result = result_id,
2500 });2438 .operand = operand_id,
2439 });
2440 },
2441 .float => unreachable,
2442 .composite_integer => unreachable, // TODO
2443 .strange_integer, .integer => {
2444 // Note: strange integer bits will be masked before operations that do not hold under modulo.
2445 try self.func.body.emit(self.spv.gpa, .OpNot, .{
2446 .id_result_type = result_ty_id,
2447 .id_result = result_id,
2448 .operand = operand_id,
2449 });
2450 },
2451 }
2452
2501 return result_id;2453 return result_id;
2502 }2454 }
25032455
2456 fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2457 if (self.liveness.isUnused(inst)) return null;
2458
2459 const mod = self.module;
2460 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2461 const array_ptr_ty = self.typeOf(ty_op.operand);
2462 const array_ty = array_ptr_ty.childType(mod);
2463 const elem_ty = array_ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.
2464 const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
2465 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(array_ptr_ty.ptrAddressSpace(mod)));
2466 const slice_ty = self.typeOfIndex(inst);
2467 const slice_ty_ref = try self.resolveType(slice_ty, .direct);
2468 const size_ty_ref = try self.sizeType();
2469
2470 const array_ptr_id = try self.resolve(ty_op.operand);
2471 const len_id = try self.constInt(size_ty_ref, array_ty.arrayLen(mod));
2472
2473 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2474 unreachable; // TODO
2475 }
2476
2477 // Convert the pointer-to-array to a pointer to the first element.
2478 const elem_ptr_id = try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0});
2479 return try self.constructStruct(slice_ty_ref, &.{ elem_ptr_id, len_id });
2480 }
2481
2482 fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2483 if (self.liveness.isUnused(inst)) return null;
2484
2485 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2486 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2487 const ptr_id = try self.resolve(bin_op.lhs);
2488 const len_id = try self.resolve(bin_op.rhs);
2489 const slice_ty = self.typeOfIndex(inst);
2490 const slice_ty_ref = try self.resolveType(slice_ty, .direct);
2491
2492 return try self.constructStruct(slice_ty_ref, &.{
2493 ptr_id, // Note: Type should not need to be converted to direct.
2494 len_id, // Note: Type should not need to be converted to direct.
2495 });
2496 }
2497
2498 fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2499 if (self.liveness.isUnused(inst)) return null;
2500
2501 const mod = self.module;
2502 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2503 const result_ty = self.typeOfIndex(inst);
2504 const result_ty_ref = try self.resolveType(result_ty, .direct);
2505 const len: usize = @intCast(result_ty.arrayLen(mod));
2506 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
2507
2508 switch (result_ty.zigTypeTag(mod)) {
2509 .Vector => unreachable, // TODO
2510 .Struct => unreachable, // TODO
2511 .Array => {
2512 const array_info = result_ty.arrayInfo(mod);
2513 const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));
2514 const elem_ids = try self.gpa.alloc(IdRef, n_elems);
2515 defer self.gpa.free(elem_ids);
2516
2517 for (elements, 0..) |elem_inst, i| {
2518 const id = try self.resolve(elem_inst);
2519 elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);
2520 }
2521
2522 if (array_info.sentinel) |sentinel_val| {
2523 elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect);
2524 }
2525
2526 return try self.constructArray(result_ty_ref, elem_ids);
2527 },
2528 else => unreachable,
2529 }
2530 }
2531
2504 fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {2532 fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
2505 if (self.liveness.isUnused(inst)) return null;2533 if (self.liveness.isUnused(inst)) return null;
2506 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2534 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
...@@ -2539,7 +2567,7 @@ pub const DeclGen = struct {...@@ -2539,7 +2567,7 @@ pub const DeclGen = struct {
25392567
2540 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);2568 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
2541 const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index_id, &.{});2569 const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index_id, &.{});
2542 return try self.load(slice_ty, elem_ptr);2570 return try self.load(slice_ty.childType(mod), elem_ptr, slice_ty.isVolatilePtr(mod));
2543 }2571 }
25442572
2545 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {2573 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
...@@ -2551,7 +2579,7 @@ pub const DeclGen = struct {...@@ -2551,7 +2579,7 @@ pub const DeclGen = struct {
2551 if (ptr_ty.isSinglePointer(mod)) {2579 if (ptr_ty.isSinglePointer(mod)) {
2552 // Pointer-to-array. In this case, the resulting pointer is not of the same type2580 // Pointer-to-array. In this case, the resulting pointer is not of the same type
2553 // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain.2581 // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain.
2554 return try self.accessChain(elem_ptr_ty_ref, ptr_id, &.{index_id});2582 return try self.accessChainId(elem_ptr_ty_ref, ptr_id, &.{index_id});
2555 } else {2583 } else {
2556 // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain2584 // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain
2557 return try self.ptrAccessChain(elem_ptr_ty_ref, ptr_id, index_id, &.{});2585 return try self.ptrAccessChain(elem_ptr_ty_ref, ptr_id, index_id, &.{});
...@@ -2574,39 +2602,199 @@ pub const DeclGen = struct {...@@ -2574,39 +2602,199 @@ pub const DeclGen = struct {
2574 return try self.ptrElemPtr(ptr_ty, ptr_id, index_id);2602 return try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
2575 }2603 }
25762604
2605 fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2606 if (self.liveness.isUnused(inst)) return null;
2607
2608 const mod = self.module;
2609 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2610 const array_ty = self.typeOf(bin_op.lhs);
2611 const array_ty_ref = try self.resolveType(array_ty, .direct);
2612 const elem_ty = array_ty.childType(mod);
2613 const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
2614 const array_id = try self.resolve(bin_op.lhs);
2615 const index_id = try self.resolve(bin_op.rhs);
2616
2617 // SPIR-V doesn't have an array indexing function for some damn reason.
2618 // For now, just generate a temporary and use that.
2619 // TODO: This backend probably also should use isByRef from llvm...
2620
2621 const array_ptr_ty_ref = try self.spv.ptrType(array_ty_ref, .Function);
2622 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, .Function);
2623
2624 const tmp_id = self.spv.allocId();
2625 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
2626 .id_result_type = self.typeId(array_ptr_ty_ref),
2627 .id_result = tmp_id,
2628 .storage_class = .Function,
2629 });
2630 try self.func.body.emit(self.spv.gpa, .OpStore, .{
2631 .pointer = tmp_id,
2632 .object = array_id,
2633 });
2634
2635 const elem_ptr_id = try self.accessChainId(elem_ptr_ty_ref, tmp_id, &.{index_id});
2636 return try self.load(elem_ty, elem_ptr_id, false);
2637 }
2638
2577 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2639 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2640 if (self.liveness.isUnused(inst)) return null;
2641
2578 const mod = self.module;2642 const mod = self.module;
2579 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2643 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2580 const ptr_ty = self.typeOf(bin_op.lhs);2644 const ptr_ty = self.typeOf(bin_op.lhs);
2645 const elem_ty = self.typeOfIndex(inst);
2581 const ptr_id = try self.resolve(bin_op.lhs);2646 const ptr_id = try self.resolve(bin_op.lhs);
2582 const index_id = try self.resolve(bin_op.rhs);2647 const index_id = try self.resolve(bin_op.rhs);
2583
2584 const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id);2648 const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
2649 return try self.load(elem_ty, elem_ptr_id, ptr_ty.isVolatilePtr(mod));
2650 }
2651
2652 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {
2653 const mod = self.module;
2654 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2655 const un_ptr_ty = self.typeOf(bin_op.lhs);
2656 const un_ty = un_ptr_ty.childType(mod);
2657 const layout = self.unionLayout(un_ty, null);
25852658
2586 // If we have a pointer-to-array, construct an element pointer to use with load()2659 if (layout.tag_size == 0) return;
2587 // If we pass ptr_ty directly, it will attempt to load the entire array rather than
2588 // just an element.
2589 var elem_ptr_info = ptr_ty.ptrInfo(mod);
2590 elem_ptr_info.flags.size = .One;
2591 const elem_ptr_ty = try mod.intern_pool.get(mod.gpa, .{ .ptr_type = elem_ptr_info });
25922660
2593 return try self.load(elem_ptr_ty.toType(), elem_ptr_id);2661 const tag_ty = un_ty.unionTagTypeSafety(mod).?;
2662 const tag_ty_ref = try self.resolveType(tag_ty, .indirect);
2663 const tag_ptr_ty_ref = try self.spv.ptrType(tag_ty_ref, spvStorageClass(un_ptr_ty.ptrAddressSpace(mod)));
2664
2665 const union_ptr_id = try self.resolve(bin_op.lhs);
2666 const new_tag_id = try self.resolve(bin_op.rhs);
2667
2668 if (layout.payload_size == 0) {
2669 try self.store(tag_ty, union_ptr_id, new_tag_id, un_ptr_ty.isVolatilePtr(mod));
2670 } else {
2671 const ptr_id = try self.accessChain(tag_ptr_ty_ref, union_ptr_id, &.{layout.tag_index});
2672 try self.store(tag_ty, ptr_id, new_tag_id, un_ptr_ty.isVolatilePtr(mod));
2673 }
2594 }2674 }
25952675
2596 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2676 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2677 if (self.liveness.isUnused(inst)) return null;
2678
2597 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2679 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2598 const un_ty = self.typeOf(ty_op.operand);2680 const un_ty = self.typeOf(ty_op.operand);
25992681
2600 const mod = self.module;2682 const mod = self.module;
2601 const layout = un_ty.unionGetLayout(mod);2683 const layout = self.unionLayout(un_ty, null);
2602 if (layout.tag_size == 0) return null;2684 if (layout.tag_size == 0) return null;
26032685
2604 const union_handle = try self.resolve(ty_op.operand);2686 const union_handle = try self.resolve(ty_op.operand);
2605 if (layout.payload_size == 0) return union_handle;2687 if (layout.payload_size == 0) return union_handle;
26062688
2607 const tag_ty = un_ty.unionTagTypeSafety(mod).?;2689 const tag_ty = un_ty.unionTagTypeSafety(mod).?;
2608 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));2690 return try self.extractField(tag_ty, union_handle, layout.tag_index);
2609 return try self.extractField(tag_ty, union_handle, tag_index);2691 }
2692
2693 fn unionInit(
2694 self: *DeclGen,
2695 ty: Type,
2696 active_field: u32,
2697 payload: ?IdRef,
2698 ) !IdRef {
2699 // To initialize a union, generate a temporary variable with the
2700 // type that has the right field active, then pointer-cast and store
2701 // the active field, and finally load and return the entire union.
2702
2703 const mod = self.module;
2704 const ip = &mod.intern_pool;
2705 const union_ty = mod.typeToUnion(ty).?;
2706
2707 if (union_ty.getLayout(ip) == .Packed) {
2708 unreachable; // TODO
2709 }
2710
2711 const maybe_tag_ty = ty.unionTagTypeSafety(mod);
2712 const layout = self.unionLayout(ty, active_field);
2713
2714 const tag_int = if (layout.tag_size != 0) blk: {
2715 const tag_ty = maybe_tag_ty.?;
2716 const union_field_name = union_ty.field_names.get(ip)[active_field];
2717 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
2718 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
2719 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);
2720 break :blk tag_int_val.toUnsignedInt(mod);
2721 } else 0;
2722
2723 if (layout.payload_size == 0) {
2724 const tag_ty_ref = try self.resolveType(maybe_tag_ty.?, .direct);
2725 return try self.constInt(tag_ty_ref, tag_int);
2726 }
2727
2728 const un_active_ty_ref = try self.resolveUnionType(ty, active_field);
2729 const un_active_ptr_ty_ref = try self.spv.ptrType(un_active_ty_ref, .Function);
2730 const un_general_ty_ref = try self.resolveType(ty, .direct);
2731 const un_general_ptr_ty_ref = try self.spv.ptrType(un_general_ty_ref, .Function);
2732
2733 const tmp_id = self.spv.allocId();
2734 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
2735 .id_result_type = self.typeId(un_active_ptr_ty_ref),
2736 .id_result = tmp_id,
2737 .storage_class = .Function,
2738 });
2739
2740 if (layout.tag_size != 0) {
2741 const tag_ty_ref = try self.resolveType(maybe_tag_ty.?, .direct);
2742 const tag_ptr_ty_ref = try self.spv.ptrType(tag_ty_ref, .Function);
2743 const ptr_id = try self.accessChain(tag_ptr_ty_ref, tmp_id, &.{@as(u32, @intCast(layout.tag_index))});
2744 const tag_id = try self.constInt(tag_ty_ref, tag_int);
2745 try self.func.body.emit(self.spv.gpa, .OpStore, .{
2746 .pointer = ptr_id,
2747 .object = tag_id,
2748 });
2749 }
2750
2751 if (layout.active_field_size != 0) {
2752 const active_field_ty_ref = try self.resolveType(layout.active_field_ty, .indirect);
2753 const active_field_ptr_ty_ref = try self.spv.ptrType(active_field_ty_ref, .Function);
2754 const ptr_id = try self.accessChain(active_field_ptr_ty_ref, tmp_id, &.{@as(u32, @intCast(layout.active_field_index))});
2755 try self.func.body.emit(self.spv.gpa, .OpStore, .{
2756 .pointer = ptr_id,
2757 .object = payload.?,
2758 });
2759 } else {
2760 assert(payload == null);
2761 }
2762
2763 // Just leave the padding fields uninitialized...
2764 // TODO: Or should we initialize them with undef explicitly?
2765
2766 // Now cast the pointer and load it as the 'generic' union type.
2767
2768 const casted_var_id = self.spv.allocId();
2769 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
2770 .id_result_type = self.typeId(un_general_ptr_ty_ref),
2771 .id_result = casted_var_id,
2772 .operand = tmp_id,
2773 });
2774
2775 const result_id = self.spv.allocId();
2776 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
2777 .id_result_type = self.typeId(un_general_ty_ref),
2778 .id_result = result_id,
2779 .pointer = casted_var_id,
2780 });
2781
2782 return result_id;
2783 }
2784
2785 fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2786 if (self.liveness.isUnused(inst)) return null;
2787
2788 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2789 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
2790 const ty = self.typeOfIndex(inst);
2791 const layout = self.unionLayout(ty, extra.field_index);
2792
2793 const payload = if (layout.active_field_size != 0)
2794 try self.resolve(extra.init)
2795 else
2796 null;
2797 return try self.unionInit(ty, extra.field_index, payload);
2610 }2798 }
26112799
2612 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2800 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -2616,16 +2804,49 @@ pub const DeclGen = struct {...@@ -2616,16 +2804,49 @@ pub const DeclGen = struct {
2616 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2804 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2617 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2805 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
26182806
2619 const struct_ty = self.typeOf(struct_field.struct_operand);2807 const object_ty = self.typeOf(struct_field.struct_operand);
2620 const object_id = try self.resolve(struct_field.struct_operand);2808 const object_id = try self.resolve(struct_field.struct_operand);
2621 const field_index = struct_field.field_index;2809 const field_index = struct_field.field_index;
2622 const field_ty = struct_ty.structFieldType(field_index, mod);2810 const field_ty = object_ty.structFieldType(field_index, mod);
26232811
2624 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;2812 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
26252813
2626 assert(struct_ty.zigTypeTag(mod) == .Struct); // Cannot do unions yet.2814 switch (object_ty.zigTypeTag(mod)) {
26272815 .Struct => switch (object_ty.containerLayout(mod)) {
2628 return try self.extractField(field_ty, object_id, field_index);2816 .Packed => unreachable, // TODO
2817 else => return try self.extractField(field_ty, object_id, field_index),
2818 },
2819 .Union => switch (object_ty.containerLayout(mod)) {
2820 .Packed => unreachable, // TODO
2821 else => {
2822 // Store, pointer-cast, load
2823 const un_general_ty_ref = try self.resolveType(object_ty, .indirect);
2824 const un_general_ptr_ty_ref = try self.spv.ptrType(un_general_ty_ref, .Function);
2825 const un_active_ty_ref = try self.resolveUnionType(object_ty, field_index);
2826 const un_active_ptr_ty_ref = try self.spv.ptrType(un_active_ty_ref, .Function);
2827 const field_ty_ref = try self.resolveType(field_ty, .indirect);
2828 const field_ptr_ty_ref = try self.spv.ptrType(field_ty_ref, .Function);
2829
2830 const tmp_id = self.spv.allocId();
2831 try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
2832 .id_result_type = self.typeId(un_general_ptr_ty_ref),
2833 .id_result = tmp_id,
2834 .storage_class = .Function,
2835 });
2836 try self.store(object_ty, tmp_id, object_id, false);
2837 const casted_tmp_id = self.spv.allocId();
2838 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
2839 .id_result_type = self.typeId(un_active_ptr_ty_ref),
2840 .id_result = casted_tmp_id,
2841 .operand = tmp_id,
2842 });
2843 const layout = self.unionLayout(object_ty, field_index);
2844 const field_ptr_id = try self.accessChain(field_ptr_ty_ref, casted_tmp_id, &.{layout.active_field_index});
2845 return try self.load(field_ty, field_ptr_id, false);
2846 },
2847 },
2848 else => unreachable,
2849 }
2629 }2850 }
26302851
2631 fn structFieldPtr(2852 fn structFieldPtr(
...@@ -2635,19 +2856,35 @@ pub const DeclGen = struct {...@@ -2635,19 +2856,35 @@ pub const DeclGen = struct {
2635 object_ptr: IdRef,2856 object_ptr: IdRef,
2636 field_index: u32,2857 field_index: u32,
2637 ) !?IdRef {2858 ) !?IdRef {
2859 const result_ty_ref = try self.resolveType(result_ptr_ty, .direct);
2860
2638 const mod = self.module;2861 const mod = self.module;
2639 const object_ty = object_ptr_ty.childType(mod);2862 const object_ty = object_ptr_ty.childType(mod);
2640 switch (object_ty.zigTypeTag(mod)) {2863 switch (object_ty.zigTypeTag(mod)) {
2641 .Struct => switch (object_ty.containerLayout(mod)) {2864 .Struct => switch (object_ty.containerLayout(mod)) {
2642 .Packed => unreachable, // TODO2865 .Packed => unreachable, // TODO
2643 else => {2866 else => {
2644 const field_index_ty_ref = try self.intType(.unsigned, 32);2867 return try self.accessChain(result_ty_ref, object_ptr, &.{field_index});
2645 const field_index_id = try self.spv.constInt(field_index_ty_ref, field_index);
2646 const result_ty_ref = try self.resolveType(result_ptr_ty, .direct);
2647 return try self.accessChain(result_ty_ref, object_ptr, &.{field_index_id});
2648 },2868 },
2649 },2869 },
2650 else => unreachable, // TODO2870 .Union => switch (object_ty.containerLayout(mod)) {
2871 .Packed => unreachable, // TODO
2872 else => {
2873 const storage_class = spvStorageClass(object_ptr_ty.ptrAddressSpace(mod));
2874 const un_active_ty_ref = try self.resolveUnionType(object_ty, field_index);
2875 const un_active_ptr_ty_ref = try self.spv.ptrType(un_active_ty_ref, storage_class);
2876
2877 const casted_id = self.spv.allocId();
2878 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
2879 .id_result_type = self.typeId(un_active_ptr_ty_ref),
2880 .id_result = casted_id,
2881 .operand = object_ptr,
2882 });
2883 const layout = self.unionLayout(object_ty, field_index);
2884 return try self.accessChain(result_ty_ref, casted_id, &.{layout.active_field_index});
2885 },
2886 },
2887 else => unreachable,
2651 }2888 }
2652 }2889 }
26532890
...@@ -2726,50 +2963,50 @@ pub const DeclGen = struct {...@@ -2726,50 +2963,50 @@ pub const DeclGen = struct {
2726 }2963 }
27272964
2728 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2965 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2729 // In AIR, a block doesn't really define an entry point like a block, but more like a scope that breaks can jump out of and2966 // In AIR, a block doesn't really define an entry point like a block, but
2730 // "return" a value from. This cannot be directly modelled in SPIR-V, so in a block instruction, we're going to split up2967 // more like a scope that breaks can jump out of and "return" a value from.
2731 // the current block by first generating the code of the block, then a label, and then generate the rest of the current2968 // This cannot be directly modelled in SPIR-V, so in a block instruction,
2969 // we're going to split up the current block by first generating the code
2970 // of the block, then a label, and then generate the rest of the current
2732 // ir.Block in a different SPIR-V block.2971 // ir.Block in a different SPIR-V block.
27332972
2734 const mod = self.module;2973 const mod = self.module;
2735 const label_id = self.spv.allocId();
2736
2737 // 4 chosen as arbitrary initial capacity.
2738 var incoming_blocks = try std.ArrayListUnmanaged(IncomingBlock).initCapacity(self.gpa, 4);
2739
2740 try self.blocks.putNoClobber(self.gpa, inst, .{
2741 .label_id = label_id,
2742 .incoming_blocks = &incoming_blocks,
2743 });
2744 defer {
2745 assert(self.blocks.remove(inst));
2746 incoming_blocks.deinit(self.gpa);
2747 }
2748
2749 const ty = self.typeOfIndex(inst);2974 const ty = self.typeOfIndex(inst);
2750 const inst_datas = self.air.instructions.items(.data);2975 const inst_datas = self.air.instructions.items(.data);
2751 const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);2976 const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);
2752 const body = self.air.extra[extra.end..][0..extra.data.body_len];2977 const body = self.air.extra[extra.end..][0..extra.data.body_len];
2978 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);
2979
2980 // 4 chosen as arbitrary initial capacity.
2981 var block = Block{
2982 // Label id is lazily allocated if needed.
2983 .label_id = null,
2984 .incoming_blocks = try std.ArrayListUnmanaged(IncomingBlock).initCapacity(self.gpa, 4),
2985 };
2986 defer block.incoming_blocks.deinit(self.gpa);
2987
2988 try self.blocks.putNoClobber(self.gpa, inst, &block);
2989 defer assert(self.blocks.remove(inst));
27532990
2754 try self.genBody(body);2991 try self.genBody(body);
2755 try self.beginSpvBlock(label_id);
27562992
2757 // If this block didn't produce a value, simply return here.2993 // Only begin a new block if there were actually any breaks towards it.
2758 if (!ty.hasRuntimeBitsIgnoreComptime(mod))2994 if (block.label_id) |label_id| {
2995 try self.beginSpvBlock(label_id);
2996 }
2997
2998 if (!have_block_result)
2759 return null;2999 return null;
27603000
2761 // Combine the result from the blocks using the Phi instruction.3001 assert(block.label_id != null);
2762 const result_id = self.spv.allocId();3002 const result_id = self.spv.allocId();
2763
2764 // TODO: OpPhi is limited in the types that it may produce, such as pointers. Figure out which other types
2765 // are not allowed to be created from a phi node, and throw an error for those.
2766 const result_type_id = try self.resolveTypeId(ty);3003 const result_type_id = try self.resolveTypeId(ty);
27673004
2768 try self.func.body.emitRaw(self.spv.gpa, .OpPhi, 2 + @as(u16, @intCast(incoming_blocks.items.len * 2))); // result type + result + variable/parent...3005 try self.func.body.emitRaw(self.spv.gpa, .OpPhi, 2 + @as(u16, @intCast(block.incoming_blocks.items.len * 2))); // result type + result + variable/parent...
2769 self.func.body.writeOperand(spec.IdResultType, result_type_id);3006 self.func.body.writeOperand(spec.IdResultType, result_type_id);
2770 self.func.body.writeOperand(spec.IdRef, result_id);3007 self.func.body.writeOperand(spec.IdRef, result_id);
27713008
2772 for (incoming_blocks.items) |incoming| {3009 for (block.incoming_blocks.items) |incoming| {
2773 self.func.body.writeOperand(spec.PairIdRefIdRef, .{ incoming.break_value_id, incoming.src_label_id });3010 self.func.body.writeOperand(spec.PairIdRefIdRef, .{ incoming.break_value_id, incoming.src_label_id });
2774 }3011 }
27753012
...@@ -2778,17 +3015,24 @@ pub const DeclGen = struct {...@@ -2778,17 +3015,24 @@ pub const DeclGen = struct {
27783015
2779 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {3016 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
2780 const br = self.air.instructions.items(.data)[inst].br;3017 const br = self.air.instructions.items(.data)[inst].br;
2781 const block = self.blocks.get(br.block_inst).?;
2782 const operand_ty = self.typeOf(br.operand);3018 const operand_ty = self.typeOf(br.operand);
3019 const block = self.blocks.get(br.block_inst).?;
27833020
2784 const mod = self.module;3021 const mod = self.module;
2785 if (operand_ty.hasRuntimeBits(mod)) {3022 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
2786 const operand_id = try self.resolve(br.operand);3023 const operand_id = try self.resolve(br.operand);
2787 // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.3024 // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.
2788 try block.incoming_blocks.append(self.gpa, .{ .src_label_id = self.current_block_label_id, .break_value_id = operand_id });3025 try block.incoming_blocks.append(self.gpa, .{
3026 .src_label_id = self.current_block_label_id,
3027 .break_value_id = operand_id,
3028 });
2789 }3029 }
27903030
2791 try self.func.body.emit(self.spv.gpa, .OpBranch, .{ .target_label = block.label_id });3031 if (block.label_id == null) {
3032 block.label_id = self.spv.allocId();
3033 }
3034
3035 try self.func.body.emit(self.spv.gpa, .OpBranch, .{ .target_label = block.label_id.? });
2792 }3036 }
27933037
2794 fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {3038 fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {
...@@ -2817,44 +3061,25 @@ pub const DeclGen = struct {...@@ -2817,44 +3061,25 @@ pub const DeclGen = struct {
2817 try self.genBody(else_body);3061 try self.genBody(else_body);
2818 }3062 }
28193063
2820 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
2821 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
2822 const src_fname_id = try self.spv.resolveSourceFileName(
2823 self.module,
2824 self.module.declPtr(self.decl_index),
2825 );
2826 try self.func.body.emit(self.spv.gpa, .OpLine, .{
2827 .file = src_fname_id,
2828 .line = dbg_stmt.line,
2829 .column = dbg_stmt.column,
2830 });
2831 }
2832
2833 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3064 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2834 const mod = self.module;3065 const mod = self.module;
2835 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3066 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2836 const ptr_ty = self.typeOf(ty_op.operand);3067 const ptr_ty = self.typeOf(ty_op.operand);
3068 const elem_ty = self.typeOfIndex(inst);
2837 const operand = try self.resolve(ty_op.operand);3069 const operand = try self.resolve(ty_op.operand);
2838 if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;3070 if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
28393071
2840 return try self.load(ptr_ty, operand);3072 return try self.load(elem_ty, operand, ptr_ty.isVolatilePtr(mod));
2841 }3073 }
28423074
2843 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {3075 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
2844 const mod = self.module;
2845 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3076 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2846 const ptr_ty = self.typeOf(bin_op.lhs);3077 const ptr_ty = self.typeOf(bin_op.lhs);
3078 const elem_ty = ptr_ty.childType(self.module);
2847 const ptr = try self.resolve(bin_op.lhs);3079 const ptr = try self.resolve(bin_op.lhs);
2848 const value = try self.resolve(bin_op.rhs);3080 const value = try self.resolve(bin_op.rhs);
2849 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
28503081
2851 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;3082 try self.store(elem_ty, ptr, value, ptr_ty.isVolatilePtr(self.module));
2852 if (val_is_undef) {
2853 const undef = try self.spv.constUndef(ptr_ty_ref);
2854 try self.store(ptr_ty, ptr, undef);
2855 } else {
2856 try self.store(ptr_ty, ptr, value);
2857 }
2858 }3083 }
28593084
2860 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {3085 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
...@@ -2878,6 +3103,7 @@ pub const DeclGen = struct {...@@ -2878,6 +3103,7 @@ pub const DeclGen = struct {
2878 const operand_ty = self.typeOf(operand);3103 const operand_ty = self.typeOf(operand);
2879 const mod = self.module;3104 const mod = self.module;
2880 if (operand_ty.hasRuntimeBits(mod)) {3105 if (operand_ty.hasRuntimeBits(mod)) {
3106 // TODO: If we return an empty struct, this branch is also hit incorrectly.
2881 const operand_id = try self.resolve(operand);3107 const operand_id = try self.resolve(operand);
2882 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });3108 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
2883 } else {3109 } else {
...@@ -2897,7 +3123,7 @@ pub const DeclGen = struct {...@@ -2897,7 +3123,7 @@ pub const DeclGen = struct {
2897 }3123 }
28983124
2899 const ptr = try self.resolve(un_op);3125 const ptr = try self.resolve(un_op);
2900 const value = try self.load(ptr_ty, ptr);3126 const value = try self.load(ret_ty, ptr, ptr_ty.isVolatilePtr(mod));
2901 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{3127 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{
2902 .value = value,3128 .value = value,
2903 });3129 });
...@@ -2924,7 +3150,7 @@ pub const DeclGen = struct {...@@ -2924,7 +3150,7 @@ pub const DeclGen = struct {
2924 else3150 else
2925 err_union_id;3151 err_union_id;
29263152
2927 const zero_id = try self.spv.constInt(err_ty_ref, 0);3153 const zero_id = try self.constInt(err_ty_ref, 0);
2928 const is_err_id = self.spv.allocId();3154 const is_err_id = self.spv.allocId();
2929 try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{3155 try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{
2930 .id_result_type = self.typeId(bool_ty_ref),3156 .id_result_type = self.typeId(bool_ty_ref),
...@@ -2988,6 +3214,21 @@ pub const DeclGen = struct {...@@ -2988,6 +3214,21 @@ pub const DeclGen = struct {
2988 return try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());3214 return try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
2989 }3215 }
29903216
3217 fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3218 if (self.liveness.isUnused(inst)) return null;
3219
3220 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3221 const operand_id = try self.resolve(ty_op.operand);
3222 const payload_ty = self.typeOfIndex(inst);
3223 const eu_layout = self.errorUnionLayout(payload_ty);
3224
3225 if (!eu_layout.payload_has_bits) {
3226 return null; // No error possible.
3227 }
3228
3229 return try self.extractField(payload_ty, operand_id, eu_layout.payloadFieldIndex());
3230 }
3231
2991 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3232 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2992 if (self.liveness.isUnused(inst)) return null;3233 if (self.liveness.isUnused(inst)) return null;
29933234
...@@ -3003,20 +3244,35 @@ pub const DeclGen = struct {...@@ -3003,20 +3244,35 @@ pub const DeclGen = struct {
3003 }3244 }
30043245
3005 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);3246 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
3006 var members = std.BoundedArray(IdRef, 2){};3247
3007 const payload_id = try self.spv.constUndef(payload_ty_ref);3248 var members: [2]IdRef = undefined;
3008 if (eu_layout.error_first) {3249 members[eu_layout.errorFieldIndex()] = operand_id;
3009 members.appendAssumeCapacity(operand_id);3250 members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref);
3010 members.appendAssumeCapacity(payload_id);3251
3011 // TODO: ABI padding?3252 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
3012 } else {3253 return try self.constructStruct(err_union_ty_ref, &members);
3013 members.appendAssumeCapacity(payload_id);3254 }
3014 members.appendAssumeCapacity(operand_id);3255
3015 // TODO: ABI padding?3256 fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3257 if (self.liveness.isUnused(inst)) return null;
3258
3259 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3260 const err_union_ty = self.typeOfIndex(inst);
3261 const operand_id = try self.resolve(ty_op.operand);
3262 const payload_ty = self.typeOf(ty_op.operand);
3263 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
3264 const eu_layout = self.errorUnionLayout(payload_ty);
3265
3266 if (!eu_layout.payload_has_bits) {
3267 return try self.constInt(err_ty_ref, 0);
3016 }3268 }
30173269
3270 var members: [2]IdRef = undefined;
3271 members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0);
3272 members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id);
3273
3018 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);3274 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
3019 return try self.constructStruct(err_union_ty_ref, members.slice());3275 return try self.constructStruct(err_union_ty_ref, &members);
3020 }3276 }
30213277
3022 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {3278 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
...@@ -3081,6 +3337,42 @@ pub const DeclGen = struct {...@@ -3081,6 +3337,42 @@ pub const DeclGen = struct {
3081 };3337 };
3082 }3338 }
30833339
3340 fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef {
3341 if (self.liveness.isUnused(inst)) return null;
3342
3343 const mod = self.module;
3344 const un_op = self.air.instructions.items(.data)[inst].un_op;
3345 const operand_id = try self.resolve(un_op);
3346 const err_union_ty = self.typeOf(un_op);
3347
3348 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
3349 return try self.constBool(pred == .is_non_err, .direct);
3350 }
3351
3352 const payload_ty = err_union_ty.errorUnionPayload(mod);
3353 const eu_layout = self.errorUnionLayout(payload_ty);
3354 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
3355 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
3356
3357 const error_id = if (!eu_layout.payload_has_bits)
3358 operand_id
3359 else
3360 try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
3361
3362 const result_id = self.spv.allocId();
3363 const operands = .{
3364 .id_result_type = self.typeId(bool_ty_ref),
3365 .id_result = result_id,
3366 .operand_1 = error_id,
3367 .operand_2 = try self.constInt(err_ty_ref, 0),
3368 };
3369 switch (pred) {
3370 .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands),
3371 .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands),
3372 }
3373 return result_id;
3374 }
3375
3084 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3376 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3085 if (self.liveness.isUnused(inst)) return null;3377 if (self.liveness.isUnused(inst)) return null;
30863378
...@@ -3238,6 +3530,40 @@ pub const DeclGen = struct {...@@ -3238,6 +3530,40 @@ pub const DeclGen = struct {
3238 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});3530 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
3239 }3531 }
32403532
3533 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
3534 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
3535 const src_fname_id = try self.spv.resolveSourceFileName(
3536 self.module,
3537 self.module.declPtr(self.decl_index),
3538 );
3539 const base_line = self.base_line_stack.getLast();
3540 try self.func.body.emit(self.spv.gpa, .OpLine, .{
3541 .file = src_fname_id,
3542 .line = base_line + dbg_stmt.line + 1,
3543 .column = dbg_stmt.column + 1,
3544 });
3545 }
3546
3547 fn airDbgInlineBegin(self: *DeclGen, inst: Air.Inst.Index) !void {
3548 const mod = self.module;
3549 const fn_ty = self.air.instructions.items(.data)[inst].ty_fn;
3550 const decl_index = mod.funcInfo(fn_ty.func).owner_decl;
3551 const decl = mod.declPtr(decl_index);
3552 try self.base_line_stack.append(self.gpa, decl.src_line);
3553 }
3554
3555 fn airDbgInlineEnd(self: *DeclGen, inst: Air.Inst.Index) !void {
3556 _ = inst;
3557 _ = self.base_line_stack.pop();
3558 }
3559
3560 fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {
3561 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3562 const target_id = try self.resolve(pl_op.operand);
3563 const name = self.air.nullTerminatedString(pl_op.payload);
3564 try self.spv.debugName(target_id, name);
3565 }
3566
3241 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3567 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3242 const mod = self.module;3568 const mod = self.module;
3243 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3569 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
src/codegen/spirv/Cache.zig+6-6
...@@ -462,11 +462,11 @@ fn emit(...@@ -462,11 +462,11 @@ fn emit(
462 switch (key) {462 switch (key) {
463 .void_type => {463 .void_type => {
464 try section.emit(spv.gpa, .OpTypeVoid, .{ .id_result = result_id });464 try section.emit(spv.gpa, .OpTypeVoid, .{ .id_result = result_id });
465 try spv.debugName(result_id, "void", .{});465 try spv.debugName(result_id, "void");
466 },466 },
467 .bool_type => {467 .bool_type => {
468 try section.emit(spv.gpa, .OpTypeBool, .{ .id_result = result_id });468 try section.emit(spv.gpa, .OpTypeBool, .{ .id_result = result_id });
469 try spv.debugName(result_id, "bool", .{});469 try spv.debugName(result_id, "bool");
470 },470 },
471 .int_type => |int| {471 .int_type => |int| {
472 try section.emit(spv.gpa, .OpTypeInt, .{472 try section.emit(spv.gpa, .OpTypeInt, .{
...@@ -481,14 +481,14 @@ fn emit(...@@ -481,14 +481,14 @@ fn emit(
481 .unsigned => "u",481 .unsigned => "u",
482 .signed => "i",482 .signed => "i",
483 };483 };
484 try spv.debugName(result_id, "{s}{}", .{ ui, int.bits });484 try spv.debugNameFmt(result_id, "{s}{}", .{ ui, int.bits });
485 },485 },
486 .float_type => |float| {486 .float_type => |float| {
487 try section.emit(spv.gpa, .OpTypeFloat, .{487 try section.emit(spv.gpa, .OpTypeFloat, .{
488 .id_result = result_id,488 .id_result = result_id,
489 .width = float.bits,489 .width = float.bits,
490 });490 });
491 try spv.debugName(result_id, "f{}", .{float.bits});491 try spv.debugNameFmt(result_id, "f{}", .{float.bits});
492 },492 },
493 .vector_type => |vector| {493 .vector_type => |vector| {
494 try section.emit(spv.gpa, .OpTypeVector, .{494 try section.emit(spv.gpa, .OpTypeVector, .{
...@@ -530,11 +530,11 @@ fn emit(...@@ -530,11 +530,11 @@ fn emit(
530 section.writeOperand(IdResult, self.resultId(member_type));530 section.writeOperand(IdResult, self.resultId(member_type));
531 }531 }
532 if (self.getString(struct_type.name)) |name| {532 if (self.getString(struct_type.name)) |name| {
533 try spv.debugName(result_id, "{s}", .{name});533 try spv.debugName(result_id, name);
534 }534 }
535 for (struct_type.memberNames(), 0..) |member_name, i| {535 for (struct_type.memberNames(), 0..) |member_name, i| {
536 if (self.getString(member_name)) |name| {536 if (self.getString(member_name)) |name| {
537 try spv.memberDebugName(result_id, @as(u32, @intCast(i)), "{s}", .{name});537 try spv.memberDebugName(result_id, @as(u32, @intCast(i)), name);
538 }538 }
539 }539 }
540 // TODO: Decorations?540 // TODO: Decorations?
src/codegen/spirv/Module.zig+101-20
...@@ -94,6 +94,8 @@ pub const Global = struct {...@@ -94,6 +94,8 @@ pub const Global = struct {
94 begin_inst: u32,94 begin_inst: u32,
95 /// The past-end offset into `self.flobals.section`.95 /// The past-end offset into `self.flobals.section`.
96 end_inst: u32,96 end_inst: u32,
97 /// The result-id of the function that initializes this value.
98 initializer_id: IdRef,
97};99};
98100
99/// This models a kernel entry point.101/// This models a kernel entry point.
...@@ -284,6 +286,10 @@ fn addEntryPointDeps(...@@ -284,6 +286,10 @@ fn addEntryPointDeps(
284 const decl = self.declPtr(decl_index);286 const decl = self.declPtr(decl_index);
285 const deps = self.decl_deps.items[decl.begin_dep..decl.end_dep];287 const deps = self.decl_deps.items[decl.begin_dep..decl.end_dep];
286288
289 if (seen.isSet(@intFromEnum(decl_index))) {
290 return;
291 }
292
287 seen.set(@intFromEnum(decl_index));293 seen.set(@intFromEnum(decl_index));
288294
289 if (self.globalPtr(decl_index)) |global| {295 if (self.globalPtr(decl_index)) |global| {
...@@ -291,9 +297,7 @@ fn addEntryPointDeps(...@@ -291,9 +297,7 @@ fn addEntryPointDeps(
291 }297 }
292298
293 for (deps) |dep| {299 for (deps) |dep| {
294 if (!seen.isSet(@intFromEnum(dep))) {300 try self.addEntryPointDeps(dep, seen, interface);
295 try self.addEntryPointDeps(dep, seen, interface);
296 }
297 }301 }
298}302}
299303
...@@ -325,20 +329,76 @@ fn entryPoints(self: *Module) !Section {...@@ -325,20 +329,76 @@ fn entryPoints(self: *Module) !Section {
325 return entry_points;329 return entry_points;
326}330}
327331
332/// Generate a function that calls all initialization functions,
333/// in unspecified order (an order should not be required here).
334/// It generated as follows:
335/// %init = OpFunction %void None
336/// foreach %initializer:
337/// OpFunctionCall %initializer
338/// OpReturn
339/// OpFunctionEnd
340fn initializer(self: *Module, entry_points: *Section) !Section {
341 var section = Section{};
342 errdefer section.deinit(self.gpa);
343
344 // const void_ty_ref = try self.resolveType(Type.void, .direct);
345 const void_ty_ref = try self.resolve(.void_type);
346 const void_ty_id = self.resultId(void_ty_ref);
347 const init_proto_ty_ref = try self.resolve(.{ .function_type = .{
348 .return_type = void_ty_ref,
349 .parameters = &.{},
350 } });
351
352 const init_id = self.allocId();
353 try section.emit(self.gpa, .OpFunction, .{
354 .id_result_type = void_ty_id,
355 .id_result = init_id,
356 .function_control = .{},
357 .function_type = self.resultId(init_proto_ty_ref),
358 });
359 try section.emit(self.gpa, .OpLabel, .{
360 .id_result = self.allocId(),
361 });
362
363 var seen = try std.DynamicBitSetUnmanaged.initEmpty(self.gpa, self.decls.items.len);
364 defer seen.deinit(self.gpa);
365
366 var interface = std.ArrayList(IdRef).init(self.gpa);
367 defer interface.deinit();
368
369 for (self.globals.globals.keys(), self.globals.globals.values()) |decl_index, global| {
370 try self.addEntryPointDeps(decl_index, &seen, &interface);
371 try section.emit(self.gpa, .OpFunctionCall, .{
372 .id_result_type = void_ty_id,
373 .id_result = self.allocId(),
374 .function = global.initializer_id,
375 });
376 }
377
378 try section.emit(self.gpa, .OpReturn, {});
379 try section.emit(self.gpa, .OpFunctionEnd, {});
380
381 try entry_points.emit(self.gpa, .OpEntryPoint, .{
382 // TODO: Rusticl does not support this because its poorly defined.
383 // Do we need to generate a workaround here?
384 .execution_model = .Kernel,
385 .entry_point = init_id,
386 .name = "zig global initializer",
387 .interface = interface.items,
388 });
389
390 try self.sections.execution_modes.emit(self.gpa, .OpExecutionMode, .{
391 .entry_point = init_id,
392 .mode = .Initializer,
393 });
394
395 return section;
396}
397
328/// Emit this module as a spir-v binary.398/// Emit this module as a spir-v binary.
329pub fn flush(self: *Module, file: std.fs.File) !void {399pub fn flush(self: *Module, file: std.fs.File) !void {
330 // See SPIR-V Spec section 2.3, "Physical Layout of a SPIR-V Module and Instruction"400 // See SPIR-V Spec section 2.3, "Physical Layout of a SPIR-V Module and Instruction"
331401
332 const header = [_]Word{
333 spec.magic_number,
334 // TODO: From cpu features
335 // Emit SPIR-V 1.4 for now. This is the highest version that Intel's CPU OpenCL supports.
336 (1 << 16) | (4 << 8),
337 0, // TODO: Register Zig compiler magic number.
338 self.idBound(),
339 0, // Schema (currently reserved for future use)
340 };
341
342 // TODO: Perform topological sort on the globals.402 // TODO: Perform topological sort on the globals.
343 var globals = try self.orderGlobals();403 var globals = try self.orderGlobals();
344 defer globals.deinit(self.gpa);404 defer globals.deinit(self.gpa);
...@@ -349,6 +409,19 @@ pub fn flush(self: *Module, file: std.fs.File) !void {...@@ -349,6 +409,19 @@ pub fn flush(self: *Module, file: std.fs.File) !void {
349 var types_constants = try self.cache.materialize(self);409 var types_constants = try self.cache.materialize(self);
350 defer types_constants.deinit(self.gpa);410 defer types_constants.deinit(self.gpa);
351411
412 var init_func = try self.initializer(&entry_points);
413 defer init_func.deinit(self.gpa);
414
415 const header = [_]Word{
416 spec.magic_number,
417 // TODO: From cpu features
418 // Emit SPIR-V 1.4 for now. This is the highest version that Intel's CPU OpenCL supports.
419 (1 << 16) | (4 << 8),
420 0, // TODO: Register Zig compiler magic number.
421 self.idBound(),
422 0, // Schema (currently reserved for future use)
423 };
424
352 // Note: needs to be kept in order according to section 2.3!425 // Note: needs to be kept in order according to section 2.3!
353 const buffers = &[_][]const Word{426 const buffers = &[_][]const Word{
354 &header,427 &header,
...@@ -363,6 +436,7 @@ pub fn flush(self: *Module, file: std.fs.File) !void {...@@ -363,6 +436,7 @@ pub fn flush(self: *Module, file: std.fs.File) !void {
363 self.sections.types_globals_constants.toWords(),436 self.sections.types_globals_constants.toWords(),
364 globals.toWords(),437 globals.toWords(),
365 self.sections.functions.toWords(),438 self.sections.functions.toWords(),
439 init_func.toWords(),
366 };440 };
367441
368 var iovc_buffers: [buffers.len]std.os.iovec_const = undefined;442 var iovc_buffers: [buffers.len]std.os.iovec_const = undefined;
...@@ -524,6 +598,7 @@ pub fn allocDecl(self: *Module, kind: DeclKind) !Decl.Index {...@@ -524,6 +598,7 @@ pub fn allocDecl(self: *Module, kind: DeclKind) !Decl.Index {
524 .result_id = undefined,598 .result_id = undefined,
525 .begin_inst = undefined,599 .begin_inst = undefined,
526 .end_inst = undefined,600 .end_inst = undefined,
601 .initializer_id = undefined,
527 }),602 }),
528 }603 }
529604
...@@ -553,10 +628,14 @@ pub fn beginGlobal(self: *Module) u32 {...@@ -553,10 +628,14 @@ pub fn beginGlobal(self: *Module) u32 {
553 return @as(u32, @intCast(self.globals.section.instructions.items.len));628 return @as(u32, @intCast(self.globals.section.instructions.items.len));
554}629}
555630
556pub fn endGlobal(self: *Module, global_index: Decl.Index, begin_inst: u32) void {631pub fn endGlobal(self: *Module, global_index: Decl.Index, begin_inst: u32, result_id: IdRef, initializer_id: IdRef) void {
557 const global = self.globalPtr(global_index).?;632 const global = self.globalPtr(global_index).?;
558 global.begin_inst = begin_inst;633 global.* = .{
559 global.end_inst = @as(u32, @intCast(self.globals.section.instructions.items.len));634 .result_id = result_id,
635 .begin_inst = begin_inst,
636 .end_inst = @intCast(self.globals.section.instructions.items.len),
637 .initializer_id = initializer_id,
638 };
560}639}
561640
562pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8) !void {641pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8) !void {
...@@ -566,18 +645,20 @@ pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8...@@ -566,18 +645,20 @@ pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8
566 });645 });
567}646}
568647
569pub fn debugName(self: *Module, target: IdResult, comptime fmt: []const u8, args: anytype) !void {648pub fn debugName(self: *Module, target: IdResult, name: []const u8) !void {
570 const name = try std.fmt.allocPrint(self.gpa, fmt, args);
571 defer self.gpa.free(name);
572 try self.sections.debug_names.emit(self.gpa, .OpName, .{649 try self.sections.debug_names.emit(self.gpa, .OpName, .{
573 .target = target,650 .target = target,
574 .name = name,651 .name = name,
575 });652 });
576}653}
577654
578pub fn memberDebugName(self: *Module, target: IdResult, member: u32, comptime fmt: []const u8, args: anytype) !void {655pub fn debugNameFmt(self: *Module, target: IdResult, comptime fmt: []const u8, args: anytype) !void {
579 const name = try std.fmt.allocPrint(self.gpa, fmt, args);656 const name = try std.fmt.allocPrint(self.gpa, fmt, args);
580 defer self.gpa.free(name);657 defer self.gpa.free(name);
658 try self.debugName(target, name);
659}
660
661pub fn memberDebugName(self: *Module, target: IdResult, member: u32, name: []const u8) !void {
581 try self.sections.debug_names.emit(self.gpa, .OpMemberName, .{662 try self.sections.debug_names.emit(self.gpa, .OpMemberName, .{
582 .type = target,663 .type = target,
583 .member = member,664 .member = member,
src/link/SpirV.zig+6-1
...@@ -110,6 +110,8 @@ pub fn updateFunc(self: *SpirV, module: *Module, func_index: InternPool.Index, a...@@ -110,6 +110,8 @@ pub fn updateFunc(self: *SpirV, module: *Module, func_index: InternPool.Index, a
110 }110 }
111111
112 const func = module.funcInfo(func_index);112 const func = module.funcInfo(func_index);
113 const decl = module.declPtr(func.owner_decl);
114 log.debug("lowering function {s}", .{module.intern_pool.stringToSlice(decl.name)});
113115
114 var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &self.spv, &self.decl_link);116 var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &self.spv, &self.decl_link);
115 defer decl_gen.deinit();117 defer decl_gen.deinit();
...@@ -124,6 +126,9 @@ pub fn updateDecl(self: *SpirV, module: *Module, decl_index: Module.Decl.Index)...@@ -124,6 +126,9 @@ pub fn updateDecl(self: *SpirV, module: *Module, decl_index: Module.Decl.Index)
124 @panic("Attempted to compile for architecture that was disabled by build configuration");126 @panic("Attempted to compile for architecture that was disabled by build configuration");
125 }127 }
126128
129 const decl = module.declPtr(decl_index);
130 log.debug("lowering declaration {s}", .{module.intern_pool.stringToSlice(decl.name)});
131
127 var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &self.spv, &self.decl_link);132 var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &self.spv, &self.decl_link);
128 defer decl_gen.deinit();133 defer decl_gen.deinit();
129134
...@@ -212,7 +217,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No...@@ -212,7 +217,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
212fn writeCapabilities(spv: *SpvModule, target: std.Target) !void {217fn writeCapabilities(spv: *SpvModule, target: std.Target) !void {
213 // TODO: Integrate with a hypothetical feature system218 // TODO: Integrate with a hypothetical feature system
214 const caps: []const spec.Capability = switch (target.os.tag) {219 const caps: []const spec.Capability = switch (target.os.tag) {
215 .opencl => &.{ .Kernel, .Addresses, .Int8, .Int16, .Int64, .GenericPointer },220 .opencl => &.{ .Kernel, .Addresses, .Int8, .Int16, .Int64, .Float64, .GenericPointer },
216 .glsl450 => &.{.Shader},221 .glsl450 => &.{.Shader},
217 .vulkan => &.{.Shader},222 .vulkan => &.{.Shader},
218 else => unreachable, // TODO223 else => unreachable, // TODO
test/behavior/array.zig+2-21
...@@ -21,7 +21,6 @@ test "arrays" {...@@ -21,7 +21,6 @@ test "arrays" {
21 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;21 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2524
26 var array: [5]u32 = undefined;25 var array: [5]u32 = undefined;
2726
...@@ -49,7 +48,6 @@ fn getArrayLen(a: []const u32) usize {...@@ -49,7 +48,6 @@ fn getArrayLen(a: []const u32) usize {
49test "array concat with undefined" {48test "array concat with undefined" {
50 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
52 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5351
54 const S = struct {52 const S = struct {
55 fn doTheTest() !void {53 fn doTheTest() !void {
...@@ -89,7 +87,6 @@ test "array concat with tuple" {...@@ -89,7 +87,6 @@ test "array concat with tuple" {
8987
90test "array init with concat" {88test "array init with concat" {
91 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO89 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9390
94 const a = 'a';91 const a = 'a';
95 var i: [4]u8 = [2]u8{ a, 'b' } ++ [2]u8{ 'c', 'd' };92 var i: [4]u8 = [2]u8{ a, 'b' } ++ [2]u8{ 'c', 'd' };
...@@ -99,7 +96,6 @@ test "array init with concat" {...@@ -99,7 +96,6 @@ test "array init with concat" {
99test "array init with mult" {96test "array init with mult" {
100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;97 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO98 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10399
104 const a = 'a';100 const a = 'a';
105 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;101 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
...@@ -141,7 +137,6 @@ test "array literal with specified size" {...@@ -141,7 +137,6 @@ test "array literal with specified size" {
141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;137 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
143 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
145140
146 var array = [2]u8{ 1, 2 };141 var array = [2]u8{ 1, 2 };
147 try expect(array[0] == 1);142 try expect(array[0] == 1);
...@@ -163,7 +158,6 @@ test "array len field" {...@@ -163,7 +158,6 @@ test "array len field" {
163test "array with sentinels" {158test "array with sentinels" {
164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;159 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO160 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
167161
168 const S = struct {162 const S = struct {
169 fn doTheTest(is_ct: bool) !void {163 fn doTheTest(is_ct: bool) !void {
...@@ -201,7 +195,6 @@ test "nested arrays of strings" {...@@ -201,7 +195,6 @@ test "nested arrays of strings" {
201 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;195 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
202 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;196 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
203 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO197 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
204 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
205198
206 const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };199 const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
207 for (array_of_strings, 0..) |s, i| {200 for (array_of_strings, 0..) |s, i| {
...@@ -231,7 +224,6 @@ test "nested arrays of integers" {...@@ -231,7 +224,6 @@ test "nested arrays of integers" {
231test "implicit comptime in array type size" {224test "implicit comptime in array type size" {
232 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO226 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
235227
236 var arr: [plusOne(10)]bool = undefined;228 var arr: [plusOne(10)]bool = undefined;
237 try expect(arr.len == 11);229 try expect(arr.len == 11);
...@@ -244,7 +236,6 @@ fn plusOne(x: u32) u32 {...@@ -244,7 +236,6 @@ fn plusOne(x: u32) u32 {
244test "single-item pointer to array indexing and slicing" {236test "single-item pointer to array indexing and slicing" {
245 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;237 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
246 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
247 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
248239
249 try testSingleItemPtrArrayIndexSlice();240 try testSingleItemPtrArrayIndexSlice();
250 try comptime testSingleItemPtrArrayIndexSlice();241 try comptime testSingleItemPtrArrayIndexSlice();
...@@ -288,7 +279,6 @@ test "anonymous list literal syntax" {...@@ -288,7 +279,6 @@ test "anonymous list literal syntax" {
288 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;279 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
289 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;280 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
290 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO281 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
291 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
292282
293 const S = struct {283 const S = struct {
294 fn doTheTest() !void {284 fn doTheTest() !void {
...@@ -326,7 +316,6 @@ test "read/write through global variable array of struct fields initialized via...@@ -326,7 +316,6 @@ test "read/write through global variable array of struct fields initialized via
326 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
327 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO317 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
328 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO318 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
329 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
330319
331 const S = struct {320 const S = struct {
332 fn doTheTest() !void {321 fn doTheTest() !void {
...@@ -366,7 +355,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {...@@ -366,7 +355,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
366test "comptime evaluating function that takes array by value" {355test "comptime evaluating function that takes array by value" {
367 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;356 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
368 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
369 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
370358
371 const arr = [_]u8{ 1, 2 };359 const arr = [_]u8{ 1, 2 };
372 const x = comptime testArrayByValAtComptime(arr);360 const x = comptime testArrayByValAtComptime(arr);
...@@ -378,7 +366,6 @@ test "comptime evaluating function that takes array by value" {...@@ -378,7 +366,6 @@ test "comptime evaluating function that takes array by value" {
378test "runtime initialize array elem and then implicit cast to slice" {366test "runtime initialize array elem and then implicit cast to slice" {
379 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;367 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO368 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
382369
383 var two: i32 = 2;370 var two: i32 = 2;
384 const x: []const i32 = &[_]i32{two};371 const x: []const i32 = &[_]i32{two};
...@@ -388,7 +375,6 @@ test "runtime initialize array elem and then implicit cast to slice" {...@@ -388,7 +375,6 @@ test "runtime initialize array elem and then implicit cast to slice" {
388test "array literal as argument to function" {375test "array literal as argument to function" {
389 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;376 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
390 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO377 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
391 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
392378
393 const S = struct {379 const S = struct {
394 fn entry(two: i32) !void {380 fn entry(two: i32) !void {
...@@ -417,7 +403,6 @@ test "double nested array to const slice cast in array literal" {...@@ -417,7 +403,6 @@ test "double nested array to const slice cast in array literal" {
417 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;403 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
418 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
419 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
420 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
421406
422 const S = struct {407 const S = struct {
423 fn entry(two: i32) !void {408 fn entry(two: i32) !void {
...@@ -479,7 +464,6 @@ test "anonymous literal in array" {...@@ -479,7 +464,6 @@ test "anonymous literal in array" {
479 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;464 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
480 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO465 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
481 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO466 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
482 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
483467
484 const S = struct {468 const S = struct {
485 const Foo = struct {469 const Foo = struct {
...@@ -504,7 +488,6 @@ test "anonymous literal in array" {...@@ -504,7 +488,6 @@ test "anonymous literal in array" {
504test "access the null element of a null terminated array" {488test "access the null element of a null terminated array" {
505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;489 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO490 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
508491
509 const S = struct {492 const S = struct {
510 fn doTheTest() !void {493 fn doTheTest() !void {
...@@ -522,7 +505,6 @@ test "type deduction for array subscript expression" {...@@ -522,7 +505,6 @@ test "type deduction for array subscript expression" {
522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
523 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO506 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
524 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
525 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
526508
527 const S = struct {509 const S = struct {
528 fn doTheTest() !void {510 fn doTheTest() !void {
...@@ -620,7 +602,6 @@ test "type coercion of pointer to anon struct literal to pointer to array" {...@@ -620,7 +602,6 @@ test "type coercion of pointer to anon struct literal to pointer to array" {
620 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO602 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
621 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO603 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
622 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO604 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
623 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
624605
625 const S = struct {606 const S = struct {
626 const U = union {607 const U = union {
...@@ -659,7 +640,6 @@ test "tuple to array handles sentinel" {...@@ -659,7 +640,6 @@ test "tuple to array handles sentinel" {
659 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO640 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
660 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO641 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
661 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO642 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
662 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
663643
664 const S = struct {644 const S = struct {
665 const a = .{ 1, 2, 3 };645 const a = .{ 1, 2, 3 };
...@@ -703,7 +683,6 @@ test "array of array agregate init" {...@@ -703,7 +683,6 @@ test "array of array agregate init" {
703 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO683 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
704 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
705 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
706 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
707686
708 var a = [1]u32{11} ** 10;687 var a = [1]u32{11} ** 10;
709 var b = [1][10]u32{a} ** 2;688 var b = [1][10]u32{a} ** 2;
...@@ -777,6 +756,8 @@ test "array init with no result pointer sets field result types" {...@@ -777,6 +756,8 @@ test "array init with no result pointer sets field result types" {
777}756}
778757
779test "runtime side-effects in comptime-known array init" {758test "runtime side-effects in comptime-known array init" {
759 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
760
780 var side_effects: u4 = 0;761 var side_effects: u4 = 0;
781 const init = [4]u4{762 const init = [4]u4{
782 blk: {763 blk: {
test/behavior/basic.zig+1-8
...@@ -330,7 +330,6 @@ const FnPtrWrapper = struct {...@@ -330,7 +330,6 @@ const FnPtrWrapper = struct {
330330
331test "const ptr from var variable" {331test "const ptr from var variable" {
332 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;332 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
333 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
334333
335 var x: u64 = undefined;334 var x: u64 = undefined;
336 var y: u64 = undefined;335 var y: u64 = undefined;
...@@ -581,7 +580,7 @@ test "comptime cast fn to ptr" {...@@ -581,7 +580,7 @@ test "comptime cast fn to ptr" {
581}580}
582581
583test "equality compare fn ptrs" {582test "equality compare fn ptrs" {
584 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // Test passes but should not583 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
585584
586 var a = &emptyFn;585 var a = &emptyFn;
587 try expect(a == a);586 try expect(a == a);
...@@ -607,7 +606,6 @@ test "self reference through fn ptr field" {...@@ -607,7 +606,6 @@ test "self reference through fn ptr field" {
607606
608test "global variable initialized to global variable array element" {607test "global variable initialized to global variable array element" {
609 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO608 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
610 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
611609
612 try expect(global_ptr == &gdt[0]);610 try expect(global_ptr == &gdt[0]);
613}611}
...@@ -639,7 +637,6 @@ test "global constant is loaded with a runtime-known index" {...@@ -639,7 +637,6 @@ test "global constant is loaded with a runtime-known index" {
639637
640test "multiline string literal is null terminated" {638test "multiline string literal is null terminated" {
641 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;639 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
642 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
643640
644 const s1 =641 const s1 =
645 \\one642 \\one
...@@ -711,7 +708,6 @@ test "comptime manyptr concatenation" {...@@ -711,7 +708,6 @@ test "comptime manyptr concatenation" {
711 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;708 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
712 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;709 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
713 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
714 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
715711
716 const s = "epic";712 const s = "epic";
717 const actual = manyptrConcat(s);713 const actual = manyptrConcat(s);
...@@ -1027,7 +1023,6 @@ comptime {...@@ -1027,7 +1023,6 @@ comptime {
10271023
1028test "switch inside @as gets correct type" {1024test "switch inside @as gets correct type" {
1029 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1025 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1030 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10311026
1032 var a: u32 = 0;1027 var a: u32 = 0;
1033 var b: [2]u32 = undefined;1028 var b: [2]u32 = undefined;
...@@ -1136,8 +1131,6 @@ test "orelse coercion as function argument" {...@@ -1136,8 +1131,6 @@ test "orelse coercion as function argument" {
1136}1131}
11371132
1138test "runtime-known globals initialized with undefined" {1133test "runtime-known globals initialized with undefined" {
1139 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1140
1141 const S = struct {1134 const S = struct {
1142 var array: [10]u32 = [_]u32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };1135 var array: [10]u32 = [_]u32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
1143 var vp: [*]u32 = undefined;1136 var vp: [*]u32 = undefined;
test/behavior/bitcast.zig+4
...@@ -271,6 +271,8 @@ test "comptime bitcast used in expression has the correct type" {...@@ -271,6 +271,8 @@ test "comptime bitcast used in expression has the correct type" {
271}271}
272272
273test "bitcast passed as tuple element" {273test "bitcast passed as tuple element" {
274 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
275
274 const S = struct {276 const S = struct {
275 fn foo(args: anytype) !void {277 fn foo(args: anytype) !void {
276 try comptime expect(@TypeOf(args[0]) == f32);278 try comptime expect(@TypeOf(args[0]) == f32);
...@@ -281,6 +283,8 @@ test "bitcast passed as tuple element" {...@@ -281,6 +283,8 @@ test "bitcast passed as tuple element" {
281}283}
282284
283test "triple level result location with bitcast sandwich passed as tuple element" {285test "triple level result location with bitcast sandwich passed as tuple element" {
286 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
287
284 const S = struct {288 const S = struct {
285 fn foo(args: anytype) !void {289 fn foo(args: anytype) !void {
286 try comptime expect(@TypeOf(args[0]) == f64);290 try comptime expect(@TypeOf(args[0]) == f64);
test/behavior/bugs/10138.zig-1
...@@ -5,7 +5,6 @@ test "registers get overwritten when ignoring return" {...@@ -5,7 +5,6 @@ test "registers get overwritten when ignoring return" {
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7 if (builtin.cpu.arch != .x86_64 or builtin.os.tag != .linux) return error.SkipZigTest;7 if (builtin.cpu.arch != .x86_64 or builtin.os.tag != .linux) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
98
10 const fd = open();9 const fd = open();
11 _ = write(fd, "a", 1);10 _ = write(fd, "a", 1);
test/behavior/bugs/10970.zig-1
...@@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" {...@@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" {
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
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 var cond = true;11 var cond = true;
13 const opt = while (cond) {12 const opt = while (cond) {
test/behavior/bugs/11100.zig-2
...@@ -9,7 +9,5 @@ pub fn do() bool {...@@ -9,7 +9,5 @@ pub fn do() bool {
9}9}
1010
11test "bug" {11test "bug" {
12 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13
14 try std.testing.expect(!do());12 try std.testing.expect(!do());
15}13}
test/behavior/bugs/11165.zig-2
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
22
3test "bytes" {3test "bytes" {
4 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO4 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
65
7 const S = struct {6 const S = struct {
8 a: u32,7 a: u32,
...@@ -24,7 +23,6 @@ test "bytes" {...@@ -24,7 +23,6 @@ test "bytes" {
2423
25test "aggregate" {24test "aggregate" {
26 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2826
29 const S = struct {27 const S = struct {
30 a: u32,28 a: u32,
test/behavior/bugs/11816.zig-1
...@@ -4,7 +4,6 @@ const builtin = @import("builtin");...@@ -4,7 +4,6 @@ const builtin = @import("builtin");
4test {4test {
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
87
9 var x: u32 = 3;8 var x: u32 = 3;
10 const val: usize = while (true) switch (x) {9 const val: usize = while (true) switch (x) {
test/behavior/bugs/12025.zig-2
...@@ -1,8 +1,6 @@...@@ -1,8 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3test {3test {
4 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5
6 comptime var st = .{4 comptime var st = .{
7 .foo = &1,5 .foo = &1,
8 .bar = &2,6 .bar = &2,
test/behavior/bugs/12033.zig-2
...@@ -2,8 +2,6 @@ const std = @import("std");...@@ -2,8 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4test {4test {
5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6
7 const string = "Hello!\x00World!";5 const string = "Hello!\x00World!";
8 try std.testing.expect(@TypeOf(string) == *const [13:0]u8);6 try std.testing.expect(@TypeOf(string) == *const [13:0]u8);
97
test/behavior/bugs/12043.zig-2
...@@ -7,8 +7,6 @@ fn foo(x: anytype) void {...@@ -7,8 +7,6 @@ fn foo(x: anytype) void {
7 ok = x;7 ok = x;
8}8}
9test {9test {
10 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11
12 const x = &foo;10 const x = &foo;
13 x(true);11 x(true);
14 try expect(ok);12 try expect(ok);
test/behavior/bugs/12119.zig-1
...@@ -9,7 +9,6 @@ test {...@@ -9,7 +9,6 @@ test {
9 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1312
14 const zerox32: u8x32 = [_]u8{0} ** 32;13 const zerox32: u8x32 = [_]u8{0} ** 32;
15 const bigsum: u32x8 = @as(u32x8, @bitCast(zerox32));14 const bigsum: u32x8 = @as(u32x8, @bitCast(zerox32));
test/behavior/bugs/12891.zig-8
...@@ -7,29 +7,21 @@ test "issue12891" {...@@ -7,29 +7,21 @@ test "issue12891" {
7 try std.testing.expect(i < f);7 try std.testing.expect(i < f);
8}8}
9test "nan" {9test "nan" {
10 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11
12 const f = comptime std.math.nan(f64);10 const f = comptime std.math.nan(f64);
13 var i: usize = 0;11 var i: usize = 0;
14 try std.testing.expect(!(f < i));12 try std.testing.expect(!(f < i));
15}13}
16test "inf" {14test "inf" {
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18
19 const f = comptime std.math.inf(f64);15 const f = comptime std.math.inf(f64);
20 var i: usize = 0;16 var i: usize = 0;
21 try std.testing.expect(f > i);17 try std.testing.expect(f > i);
22}18}
23test "-inf < 0" {19test "-inf < 0" {
24 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
25
26 const f = comptime -std.math.inf(f64);20 const f = comptime -std.math.inf(f64);
27 var i: usize = 0;21 var i: usize = 0;
28 try std.testing.expect(f < i);22 try std.testing.expect(f < i);
29}23}
30test "inf >= 1" {24test "inf >= 1" {
31 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
32
33 const f = comptime std.math.inf(f64);25 const f = comptime std.math.inf(f64);
34 var i: usize = 1;26 var i: usize = 1;
35 try std.testing.expect(f >= i);27 try std.testing.expect(f >= i);
test/behavior/bugs/12928.zig-4
...@@ -11,8 +11,6 @@ const B = extern struct {...@@ -11,8 +11,6 @@ const B = extern struct {
11};11};
1212
13test {13test {
14 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15
16 var a: *A = undefined;14 var a: *A = undefined;
17 try expect(@TypeOf(&a.value.a) == *volatile u32);15 try expect(@TypeOf(&a.value.a) == *volatile u32);
18 try expect(@TypeOf(&a.value.b) == *volatile i32);16 try expect(@TypeOf(&a.value.b) == *volatile i32);
...@@ -26,8 +24,6 @@ const D = extern union {...@@ -26,8 +24,6 @@ const D = extern union {
26 b: i32,24 b: i32,
27};25};
28test {26test {
29 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
30
31 var c: *C = undefined;27 var c: *C = undefined;
32 try expect(@TypeOf(&c.value.a) == *volatile u32);28 try expect(@TypeOf(&c.value.a) == *volatile u32);
33 try expect(@TypeOf(&c.value.b) == *volatile i32);29 try expect(@TypeOf(&c.value.b) == *volatile i32);
test/behavior/bugs/12984.zig-1
...@@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void);...@@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void);
14test "simple test" {14test "simple test" {
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1817
19 var c: CustomDraw = undefined;18 var c: CustomDraw = undefined;
20 _ = c;19 _ = c;
test/behavior/bugs/13113.zig-1
...@@ -10,7 +10,6 @@ test {...@@ -10,7 +10,6 @@ test {
10 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1413
15 const foo = Foo{14 const foo = Foo{
16 .a = 1,15 .a = 1,
test/behavior/bugs/13159.zig-1
...@@ -11,7 +11,6 @@ const Bar = packed struct {...@@ -11,7 +11,6 @@ const Bar = packed struct {
1111
12test {12test {
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 foo = Bar.Baz.fizz;15 var foo = Bar.Baz.fizz;
17 try expect(foo == .fizz);16 try expect(foo == .fizz);
test/behavior/bugs/13285.zig-1
...@@ -6,7 +6,6 @@ const Crasher = struct {...@@ -6,7 +6,6 @@ const Crasher = struct {
66
7test {7test {
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
109
11 var a: Crasher = undefined;10 var a: Crasher = undefined;
12 var crasher_ptr = &a;11 var crasher_ptr = &a;
test/behavior/bugs/14854.zig-2
...@@ -2,8 +2,6 @@ const testing = @import("std").testing;...@@ -2,8 +2,6 @@ const testing = @import("std").testing;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4test {4test {
5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6
7 try testing.expect(getGeneric(u8, getU8) == 123);5 try testing.expect(getGeneric(u8, getU8) == 123);
8}6}
97
test/behavior/bugs/1500.zig-2
...@@ -6,8 +6,6 @@ const A = struct {...@@ -6,8 +6,6 @@ const A = struct {
6const B = *const fn (A) void;6const B = *const fn (A) void;
77
8test "allow these dependencies" {8test "allow these dependencies" {
9 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10
11 var a: A = undefined;9 var a: A = undefined;
12 var b: B = undefined;10 var b: B = undefined;
13 if (false) {11 if (false) {
test/behavior/bugs/15778.zig-2
...@@ -6,7 +6,6 @@ test {...@@ -6,7 +6,6 @@ test {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
10 const a = @Vector(0, i32){};9 const a = @Vector(0, i32){};
11 const b = @Vector(0, i32){};10 const b = @Vector(0, i32){};
12 _ = a + b;11 _ = a + b;
...@@ -18,7 +17,6 @@ test {...@@ -18,7 +17,6 @@ test {
18 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO18 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO19 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
22 const a = @Vector(0, f32){};20 const a = @Vector(0, f32){};
23 const b = @Vector(0, f32){};21 const b = @Vector(0, f32){};
24 _ = a - b;22 _ = a - b;
test/behavior/bugs/2622.zig-1
...@@ -7,7 +7,6 @@ test "reslice of undefined global var slice" {...@@ -7,7 +7,6 @@ test "reslice of undefined global var slice" {
7 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
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_spirv64) return error.SkipZigTest;
1110
12 var mem: [100]u8 = [_]u8{0} ** 100;11 var mem: [100]u8 = [_]u8{0} ** 100;
13 buf = &mem;12 buf = &mem;
test/behavior/bugs/3779.zig-2
...@@ -8,7 +8,6 @@ const ptr_tag_name: [*:0]const u8 = tag_name;...@@ -8,7 +8,6 @@ const ptr_tag_name: [*:0]const u8 = tag_name;
8test "@tagName() returns a string literal" {8test "@tagName() returns a string literal" {
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) 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 try std.testing.expect(*const [13:0]u8 == @TypeOf(tag_name));12 try std.testing.expect(*const [13:0]u8 == @TypeOf(tag_name));
14 try std.testing.expect(std.mem.eql(u8, "TestEnumValue", tag_name));13 try std.testing.expect(std.mem.eql(u8, "TestEnumValue", tag_name));
...@@ -22,7 +21,6 @@ const ptr_error_name: [*:0]const u8 = error_name;...@@ -22,7 +21,6 @@ const ptr_error_name: [*:0]const u8 = error_name;
22test "@errorName() returns a string literal" {21test "@errorName() returns a string literal" {
23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2624
27 try std.testing.expect(*const [13:0]u8 == @TypeOf(error_name));25 try std.testing.expect(*const [13:0]u8 == @TypeOf(error_name));
28 try std.testing.expect(std.mem.eql(u8, "TestErrorCode", error_name));26 try std.testing.expect(std.mem.eql(u8, "TestErrorCode", error_name));
test/behavior/bugs/4954.zig-1
...@@ -8,7 +8,6 @@ test "crash" {...@@ -8,7 +8,6 @@ test "crash" {
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 var buf: [4096]u8 = undefined;12 var buf: [4096]u8 = undefined;
14 f(&buf);13 f(&buf);
test/behavior/bugs/5398.zig-1
...@@ -22,7 +22,6 @@ test "assignment of field with padding" {...@@ -22,7 +22,6 @@ test "assignment of field with padding" {
22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
24 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2625
27 renderable = Renderable{26 renderable = Renderable{
28 .mesh = Mesh{ .id = 0 },27 .mesh = Mesh{ .id = 0 },
test/behavior/bugs/5487.zig+1
...@@ -13,5 +13,6 @@ test "crash" {...@@ -13,5 +13,6 @@ test "crash" {
13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
16 _ = io.multiWriter(.{writer()});17 _ = io.multiWriter(.{writer()});
17}18}
test/behavior/bugs/6456.zig-1
...@@ -13,7 +13,6 @@ const text =...@@ -13,7 +13,6 @@ const text =
13test "issue 6456" {13test "issue 6456" {
14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1716
18 comptime {17 comptime {
19 var fields: []const StructField = &[0]StructField{};18 var fields: []const StructField = &[0]StructField{};
test/behavior/bugs/656.zig-1
...@@ -14,7 +14,6 @@ test "optional if after an if in a switch prong of a switch with 2 prongs in an...@@ -14,7 +14,6 @@ test "optional if after an if in a switch prong of a switch with 2 prongs in an
14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_arm) 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 try foo(false, true);18 try foo(false, true);
20}19}
test/behavior/bugs/7047.zig-2
...@@ -15,8 +15,6 @@ fn S(comptime query: U) type {...@@ -15,8 +15,6 @@ fn S(comptime query: U) type {
15}15}
1616
17test "compiler doesn't consider equal unions with different 'type' payload" {17test "compiler doesn't consider equal unions with different 'type' payload" {
18 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19
20 const s1 = S(U{ .T = u32 }).tag();18 const s1 = S(U{ .T = u32 }).tag();
21 try std.testing.expectEqual(u32, s1);19 try std.testing.expectEqual(u32, s1);
2220
test/behavior/bugs/7187.zig-2
...@@ -3,8 +3,6 @@ const builtin = @import("builtin");...@@ -3,8 +3,6 @@ const builtin = @import("builtin");
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5test "miscompilation with bool return type" {5test "miscompilation with bool return type" {
6 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7
8 var x: usize = 1;6 var x: usize = 1;
9 var y: bool = getFalse();7 var y: bool = getFalse();
10 _ = y;8 _ = y;
test/behavior/bugs/8277.zig-2
...@@ -2,8 +2,6 @@ const std = @import("std");...@@ -2,8 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4test "@sizeOf reified union zero-size payload fields" {4test "@sizeOf reified union zero-size payload fields" {
5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6
7 comptime {5 comptime {
8 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union {}))));6 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union {}))));
9 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union { a: void }))));7 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union { a: void }))));
test/behavior/bugs/828.zig-1
...@@ -31,7 +31,6 @@ fn constCount(comptime cb: *const CountBy, comptime unused: u32) void {...@@ -31,7 +31,6 @@ fn constCount(comptime cb: *const CountBy, comptime unused: u32) void {
3131
32test "comptime struct return should not return the same instance" {32test "comptime struct return should not return the same instance" {
33 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;33 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
34 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3534
36 //the first parameter must be passed by reference to trigger the bug35 //the first parameter must be passed by reference to trigger the bug
37 //a second parameter is required to trigger the bug36 //a second parameter is required to trigger the bug
test/behavior/byval_arg_var.zig-1
...@@ -5,7 +5,6 @@ var result: []const u8 = "wrong";...@@ -5,7 +5,6 @@ var result: []const u8 = "wrong";
55
6test "pass string literal byvalue to a generic var param" {6test "pass string literal byvalue to a generic var param" {
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 start();9 start();
11 blowUpStack(10);10 blowUpStack(10);
test/behavior/call.zig-1
...@@ -334,7 +334,6 @@ test "inline call preserves tail call" {...@@ -334,7 +334,6 @@ test "inline call preserves tail call" {
334test "inline call doesn't re-evaluate non generic struct" {334test "inline call doesn't re-evaluate non generic struct" {
335 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO335 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
336 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO336 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
337 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
338337
339 const S = struct {338 const S = struct {
340 fn foo(f: struct { a: u8, b: u8 }) !void {339 fn foo(f: struct { a: u8, b: u8 }) !void {
test/behavior/call_tail.zig+1
...@@ -46,6 +46,7 @@ test "arguments pointed to on stack into tailcall" {...@@ -46,6 +46,7 @@ test "arguments pointed to on stack into tailcall" {
46 }46 }
47 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;47 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
48 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;48 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
49 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
4950
50 var data = [_]u64{ 1, 6, 2, 7, 1, 9, 3 };51 var data = [_]u64{ 1, 6, 2, 7, 1, 9, 3 };
51 base = @intFromPtr(&data);52 base = @intFromPtr(&data);
test/behavior/cast.zig+2-35
...@@ -403,7 +403,6 @@ test "peer type unsigned int to signed" {...@@ -403,7 +403,6 @@ test "peer type unsigned int to signed" {
403test "expected [*c]const u8, found [*:0]const u8" {403test "expected [*c]const u8, found [*:0]const u8" {
404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
406 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
407406
408 var a: [*:0]const u8 = "hello";407 var a: [*:0]const u8 = "hello";
409 var b: [*c]const u8 = a;408 var b: [*c]const u8 = a;
...@@ -445,7 +444,6 @@ test "implicitly cast from T to anyerror!?T" {...@@ -445,7 +444,6 @@ test "implicitly cast from T to anyerror!?T" {
445 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;444 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
446 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;445 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
447 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO446 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
448 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
449447
450 try castToOptionalTypeError(1);448 try castToOptionalTypeError(1);
451 try comptime castToOptionalTypeError(1);449 try comptime castToOptionalTypeError(1);
...@@ -521,7 +519,6 @@ fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {...@@ -521,7 +519,6 @@ fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
521test "implicit cast from *const [N]T to []const T" {519test "implicit cast from *const [N]T to []const T" {
522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO520 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
523 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
524 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
525522
526 try testCastConstArrayRefToConstSlice();523 try testCastConstArrayRefToConstSlice();
527 try comptime testCastConstArrayRefToConstSlice();524 try comptime testCastConstArrayRefToConstSlice();
...@@ -547,7 +544,6 @@ fn testCastConstArrayRefToConstSlice() !void {...@@ -547,7 +544,6 @@ fn testCastConstArrayRefToConstSlice() !void {
547test "peer type resolution: error and [N]T" {544test "peer type resolution: error and [N]T" {
548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO546 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
550 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
551547
552 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));548 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
553 try comptime expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));549 try comptime expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
...@@ -709,7 +705,6 @@ test "peer type resolution: error set supersets" {...@@ -709,7 +705,6 @@ test "peer type resolution: error set supersets" {
709 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO705 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
710 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO706 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
711 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO707 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
712 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
713708
714 const a: error{ One, Two } = undefined;709 const a: error{ One, Two } = undefined;
715 const b: error{One} = undefined;710 const b: error{One} = undefined;
...@@ -739,7 +734,6 @@ test "peer type resolution: disjoint error sets" {...@@ -739,7 +734,6 @@ test "peer type resolution: disjoint error sets" {
739 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO734 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
740 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO735 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
741 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO736 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
742 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
743737
744 const a: error{ One, Two } = undefined;738 const a: error{ One, Two } = undefined;
745 const b: error{Three} = undefined;739 const b: error{Three} = undefined;
...@@ -769,7 +763,6 @@ test "peer type resolution: error union and error set" {...@@ -769,7 +763,6 @@ test "peer type resolution: error union and error set" {
769 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO763 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
770 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO764 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
771 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO765 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
772 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
773766
774 const a: error{Three} = undefined;767 const a: error{Three} = undefined;
775 const b: error{ One, Two }!u32 = undefined;768 const b: error{ One, Two }!u32 = undefined;
...@@ -803,7 +796,6 @@ test "peer type resolution: error union after non-error" {...@@ -803,7 +796,6 @@ test "peer type resolution: error union after non-error" {
803 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO796 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
804 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO797 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
805 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO798 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
806 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
807799
808 const a: u32 = undefined;800 const a: u32 = undefined;
809 const b: error{ One, Two }!u32 = undefined;801 const b: error{ One, Two }!u32 = undefined;
...@@ -863,7 +855,6 @@ test "peer cast *[0]T to []const T" {...@@ -863,7 +855,6 @@ test "peer cast *[0]T to []const T" {
863855
864test "peer cast *[N]T to [*]T" {856test "peer cast *[N]T to [*]T" {
865 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO857 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
866 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
867858
868 var array = [4:99]i32{ 1, 2, 3, 4 };859 var array = [4:99]i32{ 1, 2, 3, 4 };
869 var dest: [*]i32 = undefined;860 var dest: [*]i32 = undefined;
...@@ -930,7 +921,6 @@ test "peer cast [N:x]T to [N]T" {...@@ -930,7 +921,6 @@ test "peer cast [N:x]T to [N]T" {
930test "peer cast *[N:x]T to *[N]T" {921test "peer cast *[N:x]T to *[N]T" {
931 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO922 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
932 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO923 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
933 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
934924
935 const S = struct {925 const S = struct {
936 fn doTheTest() !void {926 fn doTheTest() !void {
...@@ -946,7 +936,6 @@ test "peer cast *[N:x]T to *[N]T" {...@@ -946,7 +936,6 @@ test "peer cast *[N:x]T to *[N]T" {
946test "peer cast [*:x]T to [*]T" {936test "peer cast [*:x]T to [*]T" {
947 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO937 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
948 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO938 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
949 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
950939
951 const S = struct {940 const S = struct {
952 fn doTheTest() !void {941 fn doTheTest() !void {
...@@ -967,7 +956,6 @@ test "peer cast [:x]T to [*:x]T" {...@@ -967,7 +956,6 @@ test "peer cast [:x]T to [*:x]T" {
967 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
968 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO957 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
969 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO958 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
970 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
971959
972 const S = struct {960 const S = struct {
973 fn doTheTest() !void {961 fn doTheTest() !void {
...@@ -988,7 +976,6 @@ test "peer cast [:x]T to [*:x]T" {...@@ -988,7 +976,6 @@ test "peer cast [:x]T to [*:x]T" {
988test "peer type resolution implicit cast to return type" {976test "peer type resolution implicit cast to return type" {
989 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;977 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
990 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO978 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
991 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
992979
993 const S = struct {980 const S = struct {
994 fn doTheTest() !void {981 fn doTheTest() !void {
...@@ -1009,7 +996,6 @@ test "peer type resolution implicit cast to return type" {...@@ -1009,7 +996,6 @@ test "peer type resolution implicit cast to return type" {
1009test "peer type resolution implicit cast to variable type" {996test "peer type resolution implicit cast to variable type" {
1010 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;997 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1011 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO998 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1012 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1013999
1014 const S = struct {1000 const S = struct {
1015 fn doTheTest() !void {1001 fn doTheTest() !void {
...@@ -1034,7 +1020,6 @@ test "variable initialization uses result locations properly with regards to the...@@ -1034,7 +1020,6 @@ test "variable initialization uses result locations properly with regards to the
1034test "cast between C pointer with different but compatible types" {1020test "cast between C pointer with different but compatible types" {
1035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1036 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1022 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1037 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10381023
1039 const S = struct {1024 const S = struct {
1040 fn foo(arg: [*]c_ushort) u16 {1025 fn foo(arg: [*]c_ushort) u16 {
...@@ -1052,7 +1037,6 @@ test "cast between C pointer with different but compatible types" {...@@ -1052,7 +1037,6 @@ test "cast between C pointer with different but compatible types" {
1052test "peer type resolve string lit with sentinel-terminated mutable slice" {1037test "peer type resolve string lit with sentinel-terminated mutable slice" {
1053 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1038 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1054 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1039 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1055 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10561040
1057 var array: [4:0]u8 = undefined;1041 var array: [4:0]u8 = undefined;
1058 array[4] = 0; // TODO remove this when #4372 is solved1042 array[4] = 0; // TODO remove this when #4372 is solved
...@@ -1062,8 +1046,6 @@ test "peer type resolve string lit with sentinel-terminated mutable slice" {...@@ -1062,8 +1046,6 @@ test "peer type resolve string lit with sentinel-terminated mutable slice" {
1062}1046}
10631047
1064test "peer type resolve array pointers, one of them const" {1048test "peer type resolve array pointers, one of them const" {
1065 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1066
1067 var array1: [4]u8 = undefined;1049 var array1: [4]u8 = undefined;
1068 const array2: [5]u8 = undefined;1050 const array2: [5]u8 = undefined;
1069 try comptime expect(@TypeOf(&array1, &array2) == []const u8);1051 try comptime expect(@TypeOf(&array1, &array2) == []const u8);
...@@ -1071,8 +1053,6 @@ test "peer type resolve array pointers, one of them const" {...@@ -1071,8 +1053,6 @@ test "peer type resolve array pointers, one of them const" {
1071}1053}
10721054
1073test "peer type resolve array pointer and unknown pointer" {1055test "peer type resolve array pointer and unknown pointer" {
1074 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1075
1076 const const_array: [4]u8 = undefined;1056 const const_array: [4]u8 = undefined;
1077 var array: [4]u8 = undefined;1057 var array: [4]u8 = undefined;
1078 var const_ptr: [*]const u8 = undefined;1058 var const_ptr: [*]const u8 = undefined;
...@@ -1092,8 +1072,6 @@ test "peer type resolve array pointer and unknown pointer" {...@@ -1092,8 +1072,6 @@ test "peer type resolve array pointer and unknown pointer" {
1092}1072}
10931073
1094test "comptime float casts" {1074test "comptime float casts" {
1095 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1096
1097 const a = @as(comptime_float, @floatFromInt(1));1075 const a = @as(comptime_float, @floatFromInt(1));
1098 try expect(a == 1);1076 try expect(a == 1);
1099 try expect(@TypeOf(a) == comptime_float);1077 try expect(@TypeOf(a) == comptime_float);
...@@ -1140,8 +1118,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {...@@ -1140,8 +1118,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
1140}1118}
11411119
1142test "compile time int to ptr of function" {1120test "compile time int to ptr of function" {
1143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1144
1145 try foobar(FUNCTION_CONSTANT);1121 try foobar(FUNCTION_CONSTANT);
1146}1122}
11471123
...@@ -1156,6 +1132,7 @@ fn foobar(func: PFN_void) !void {...@@ -1156,6 +1132,7 @@ fn foobar(func: PFN_void) !void {
11561132
1157test "cast function with an opaque parameter" {1133test "cast function with an opaque parameter" {
1158 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;1134 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1135 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11591136
1160 if (builtin.zig_backend == .stage2_c) {1137 if (builtin.zig_backend == .stage2_c) {
1161 // https://github.com/ziglang/zig/issues/168451138 // https://github.com/ziglang/zig/issues/16845
...@@ -1340,8 +1317,6 @@ test "*const [N]null u8 to ?[]const u8" {...@@ -1340,8 +1317,6 @@ test "*const [N]null u8 to ?[]const u8" {
1340}1317}
13411318
1342test "cast between [*c]T and ?[*:0]T on fn parameter" {1319test "cast between [*c]T and ?[*:0]T on fn parameter" {
1343 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1344
1345 const S = struct {1320 const S = struct {
1346 const Handler = ?fn ([*c]const u8) callconv(.C) void;1321 const Handler = ?fn ([*c]const u8) callconv(.C) void;
1347 fn addCallback(comptime handler: Handler) void {1322 fn addCallback(comptime handler: Handler) void {
...@@ -1381,7 +1356,6 @@ test "cast between *[N]void and []void" {...@@ -1381,7 +1356,6 @@ test "cast between *[N]void and []void" {
1381test "peer resolve arrays of different size to const slice" {1356test "peer resolve arrays of different size to const slice" {
1382 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1357 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1383 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1358 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1384 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13851359
1386 try expect(mem.eql(u8, boolToStr(true), "true"));1360 try expect(mem.eql(u8, boolToStr(true), "true"));
1387 try expect(mem.eql(u8, boolToStr(false), "false"));1361 try expect(mem.eql(u8, boolToStr(false), "false"));
...@@ -1485,7 +1459,6 @@ test "cast compatible optional types" {...@@ -1485,7 +1459,6 @@ test "cast compatible optional types" {
1485test "coerce undefined single-item pointer of array to error union of slice" {1459test "coerce undefined single-item pointer of array to error union of slice" {
1486 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1460 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1461 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1488 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14891462
1490 const a = @as([*]u8, undefined)[0..0];1463 const a = @as([*]u8, undefined)[0..0];
1491 var b: error{a}![]const u8 = a;1464 var b: error{a}![]const u8 = a;
...@@ -1495,7 +1468,6 @@ test "coerce undefined single-item pointer of array to error union of slice" {...@@ -1495,7 +1468,6 @@ test "coerce undefined single-item pointer of array to error union of slice" {
14951468
1496test "pointer to empty struct literal to mutable slice" {1469test "pointer to empty struct literal to mutable slice" {
1497 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1470 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1498 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14991471
1500 var x: []i32 = &.{};1472 var x: []i32 = &.{};
1501 try expect(x.len == 0);1473 try expect(x.len == 0);
...@@ -1584,7 +1556,6 @@ test "bitcast packed struct with u0" {...@@ -1584,7 +1556,6 @@ test "bitcast packed struct with u0" {
15841556
1585test "optional pointer coerced to optional allowzero pointer" {1557test "optional pointer coerced to optional allowzero pointer" {
1586 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1558 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1587 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15881559
1589 var p: ?*u32 = undefined;1560 var p: ?*u32 = undefined;
1590 var q: ?*allowzero u32 = undefined;1561 var q: ?*allowzero u32 = undefined;
...@@ -1594,8 +1565,6 @@ test "optional pointer coerced to optional allowzero pointer" {...@@ -1594,8 +1565,6 @@ test "optional pointer coerced to optional allowzero pointer" {
1594}1565}
15951566
1596test "single item pointer to pointer to array to slice" {1567test "single item pointer to pointer to array to slice" {
1597 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1598
1599 var x: i32 = 1234;1568 var x: i32 = 1234;
1600 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);1569 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);
1601 const z1 = @as([]const i32, @as(*[1]i32, &x));1570 const z1 = @as([]const i32, @as(*[1]i32, &x));
...@@ -1631,8 +1600,6 @@ test "@volatileCast without a result location" {...@@ -1631,8 +1600,6 @@ test "@volatileCast without a result location" {
1631}1600}
16321601
1633test "coercion from single-item pointer to @as to slice" {1602test "coercion from single-item pointer to @as to slice" {
1634 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1635
1636 var x: u32 = 1;1603 var x: u32 = 1;
16371604
1638 // Why the following line gets a compile error?1605 // Why the following line gets a compile error?
...@@ -2294,7 +2261,6 @@ test "cast builtins can wrap result in error union" {...@@ -2294,7 +2261,6 @@ test "cast builtins can wrap result in error union" {
2294 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO2261 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2295 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO2262 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2296 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2263 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2297 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
22982264
2299 const S = struct {2265 const S = struct {
2300 const MyEnum = enum(u32) { _ };2266 const MyEnum = enum(u32) { _ };
...@@ -2501,6 +2467,7 @@ test "@intFromBool on vector" {...@@ -2501,6 +2467,7 @@ test "@intFromBool on vector" {
2501test "numeric coercions with undefined" {2467test "numeric coercions with undefined" {
2502 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;2468 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
2503 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;2469 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2470 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
25042471
2505 const from: i32 = undefined;2472 const from: i32 = undefined;
2506 var to: f32 = from;2473 var to: f32 = from;
test/behavior/cast_int.zig-1
...@@ -19,7 +19,6 @@ test "coerce i8 to i32 and @intCast back" {...@@ -19,7 +19,6 @@ test "coerce i8 to i32 and @intCast back" {
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO21 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2322
24 var x: i8 = -5;23 var x: i8 = -5;
25 var y: i32 = -5;24 var y: i32 = -5;
test/behavior/comptime_memory.zig+2
...@@ -425,6 +425,8 @@ test "mutate entire slice at comptime" {...@@ -425,6 +425,8 @@ test "mutate entire slice at comptime" {
425}425}
426426
427test "dereference undefined pointer to zero-bit type" {427test "dereference undefined pointer to zero-bit type" {
428 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
429
428 const p0: *void = undefined;430 const p0: *void = undefined;
429 try testing.expectEqual({}, p0.*);431 try testing.expectEqual({}, p0.*);
430432
test/behavior/defer.zig-2
...@@ -5,8 +5,6 @@ const expectEqual = std.testing.expectEqual;...@@ -5,8 +5,6 @@ const expectEqual = std.testing.expectEqual;
5const expectError = std.testing.expectError;5const expectError = std.testing.expectError;
66
7test "break and continue inside loop inside defer expression" {7test "break and continue inside loop inside defer expression" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9
10 testBreakContInDefer(10);8 testBreakContInDefer(10);
11 comptime testBreakContInDefer(10);9 comptime testBreakContInDefer(10);
12}10}
test/behavior/empty_union.zig-3
...@@ -9,8 +9,6 @@ test "switch on empty enum" {...@@ -9,8 +9,6 @@ test "switch on empty enum" {
9}9}
1010
11test "switch on empty enum with a specified tag type" {11test "switch on empty enum with a specified tag type" {
12 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13
14 const E = enum(u8) {};12 const E = enum(u8) {};
15 var e: E = undefined;13 var e: E = undefined;
16 switch (e) {}14 switch (e) {}
...@@ -18,7 +16,6 @@ test "switch on empty enum with a specified tag type" {...@@ -18,7 +16,6 @@ test "switch on empty enum with a specified tag type" {
1816
19test "switch on empty auto numbered tagged union" {17test "switch on empty auto numbered tagged union" {
20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2219
23 const U = union(enum(u8)) {};20 const U = union(enum(u8)) {};
24 var u: U = undefined;21 var u: U = undefined;
test/behavior/enum.zig-4
...@@ -935,7 +935,6 @@ const Bar = enum { A, B, C, D };...@@ -935,7 +935,6 @@ const Bar = enum { A, B, C, D };
935test "enum literal casting to error union with payload enum" {935test "enum literal casting to error union with payload enum" {
936 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;936 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
937 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO937 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
938 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
939938
940 var bar: error{B}!Bar = undefined;939 var bar: error{B}!Bar = undefined;
941 bar = .B; // should never cast to the error set940 bar = .B; // should never cast to the error set
...@@ -947,7 +946,6 @@ test "constant enum initialization with differing sizes" {...@@ -947,7 +946,6 @@ test "constant enum initialization with differing sizes" {
947 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;946 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
948 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;947 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
949 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO948 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
950 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
951949
952 try test3_1(test3_foo);950 try test3_1(test3_foo);
953 try test3_2(test3_bar);951 try test3_2(test3_bar);
...@@ -1054,7 +1052,6 @@ test "enum literal casting to optional" {...@@ -1054,7 +1052,6 @@ test "enum literal casting to optional" {
1054 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1052 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1055 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1053 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1056 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1054 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1057 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10581055
1059 var bar: ?Bar = undefined;1056 var bar: ?Bar = undefined;
1060 bar = .B;1057 bar = .B;
...@@ -1141,7 +1138,6 @@ test "tag name functions are unique" {...@@ -1141,7 +1138,6 @@ test "tag name functions are unique" {
1141test "size of enum with only one tag which has explicit integer tag type" {1138test "size of enum with only one tag which has explicit integer tag type" {
1142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1139 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1143 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11451141
1146 const E = enum(u8) { nope = 10 };1142 const E = enum(u8) { nope = 10 };
1147 const S0 = struct { e: E };1143 const S0 = struct { e: E };
test/behavior/error.zig+1-15
...@@ -30,7 +30,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {...@@ -30,7 +30,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
3030
31test "error binary operator" {31test "error binary operator" {
32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3433
35 const a = errBinaryOperatorG(true) catch 3;34 const a = errBinaryOperatorG(true) catch 3;
36 const b = errBinaryOperatorG(false) catch 3;35 const b = errBinaryOperatorG(false) catch 3;
...@@ -62,14 +61,12 @@ pub fn baz() anyerror!i32 {...@@ -62,14 +61,12 @@ pub fn baz() anyerror!i32 {
6261
63test "error wrapping" {62test "error wrapping" {
64 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO63 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
65 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6664
67 try expect((baz() catch unreachable) == 15);65 try expect((baz() catch unreachable) == 15);
68}66}
6967
70test "unwrap simple value from error" {68test "unwrap simple value from error" {
71 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7370
74 const i = unwrapSimpleValueFromErrorDo() catch unreachable;71 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
75 try expect(i == 13);72 try expect(i == 13);
...@@ -80,7 +77,6 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize {...@@ -80,7 +77,6 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize {
8077
81test "error return in assignment" {78test "error return in assignment" {
82 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
83 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8480
85 doErrReturnInAssignment() catch unreachable;81 doErrReturnInAssignment() catch unreachable;
86}82}
...@@ -103,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {...@@ -103,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {
103test "widen cast integer payload of error union function call" {99test "widen cast integer payload of error union function call" {
104 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
105 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
107102
108 const S = struct {103 const S = struct {
109 fn errorable() !u64 {104 fn errorable() !u64 {
...@@ -150,7 +145,6 @@ test "implicit cast to optional to error union to return result loc" {...@@ -150,7 +145,6 @@ test "implicit cast to optional to error union to return result loc" {
150}145}
151146
152test "fn returning empty error set can be passed as fn returning any error" {147test "fn returning empty error set can be passed as fn returning any error" {
153 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
154 entry();148 entry();
155 comptime entry();149 comptime entry();
156}150}
...@@ -243,7 +237,6 @@ fn testExplicitErrorSetCast(set1: Set1) !void {...@@ -243,7 +237,6 @@ fn testExplicitErrorSetCast(set1: Set1) !void {
243237
244test "comptime test error for empty error set" {238test "comptime test error for empty error set" {
245 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
246 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
247240
248 try testComptimeTestErrorEmptySet(1234);241 try testComptimeTestErrorEmptySet(1234);
249 try comptime testComptimeTestErrorEmptySet(1234);242 try comptime testComptimeTestErrorEmptySet(1234);
...@@ -279,7 +272,6 @@ test "inferred empty error set comptime catch" {...@@ -279,7 +272,6 @@ test "inferred empty error set comptime catch" {
279}272}
280273
281test "error inference with an empty set" {274test "error inference with an empty set" {
282 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
283 const S = struct {275 const S = struct {
284 const Struct = struct {276 const Struct = struct {
285 pub fn func() (error{})!usize {277 pub fn func() (error{})!usize {
...@@ -334,7 +326,6 @@ fn quux_1() !i32 {...@@ -334,7 +326,6 @@ fn quux_1() !i32 {
334326
335test "error: Zero sized error set returned with value payload crash" {327test "error: Zero sized error set returned with value payload crash" {
336 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO328 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
337 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
338329
339 _ = try foo3(0);330 _ = try foo3(0);
340 _ = try comptime foo3(0);331 _ = try comptime foo3(0);
...@@ -434,7 +425,6 @@ test "nested error union function call in optional unwrap" {...@@ -434,7 +425,6 @@ test "nested error union function call in optional unwrap" {
434test "return function call to error set from error union function" {425test "return function call to error set from error union function" {
435 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
436 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
437 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
438428
439 const S = struct {429 const S = struct {
440 fn errorable() anyerror!i32 {430 fn errorable() anyerror!i32 {
...@@ -670,7 +660,6 @@ test "peer type resolution of two different error unions" {...@@ -670,7 +660,6 @@ test "peer type resolution of two different error unions" {
670}660}
671661
672test "coerce error set to the current inferred error set" {662test "coerce error set to the current inferred error set" {
673 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
674 const S = struct {663 const S = struct {
675 fn foo() !void {664 fn foo() !void {
676 var a = false;665 var a = false;
...@@ -833,7 +822,6 @@ test "alignment of wrapping an error union payload" {...@@ -833,7 +822,6 @@ test "alignment of wrapping an error union payload" {
833822
834test "compare error union and error set" {823test "compare error union and error set" {
835 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO824 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
836 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
837825
838 var a: anyerror = error.Foo;826 var a: anyerror = error.Foo;
839 var b: anyerror!u32 = error.Bar;827 var b: anyerror!u32 = error.Bar;
...@@ -862,8 +850,6 @@ fn non_errorable() void {...@@ -862,8 +850,6 @@ fn non_errorable() void {
862}850}
863851
864test "catch within a function that calls no errorable functions" {852test "catch within a function that calls no errorable functions" {
865 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
866
867 non_errorable();853 non_errorable();
868}854}
869855
...@@ -895,7 +881,6 @@ test "field access of anyerror results in smaller error set" {...@@ -895,7 +881,6 @@ test "field access of anyerror results in smaller error set" {
895test "optional error union return type" {881test "optional error union return type" {
896 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO882 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
897 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO883 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
898 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
899884
900 const S = struct {885 const S = struct {
901 fn foo() ?anyerror!u32 {886 fn foo() ?anyerror!u32 {
...@@ -942,6 +927,7 @@ test "returning an error union containing a type with no runtime bits" {...@@ -942,6 +927,7 @@ test "returning an error union containing a type with no runtime bits" {
942test "try used in recursive function with inferred error set" {927test "try used in recursive function with inferred error set" {
943 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO928 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
944 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO929 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
930 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
945931
946 const Value = union(enum) {932 const Value = union(enum) {
947 values: []const @This(),933 values: []const @This(),
test/behavior/eval.zig+1-35
...@@ -5,8 +5,6 @@ const expect = std.testing.expect;...@@ -5,8 +5,6 @@ const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;5const expectEqual = std.testing.expectEqual;
66
7test "compile time recursion" {7test "compile time recursion" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9
10 try expect(some_data.len == 21);8 try expect(some_data.len == 21);
11}9}
12var some_data: [@as(usize, @intCast(fibonacci(7)))]u8 = undefined;10var some_data: [@as(usize, @intCast(fibonacci(7)))]u8 = undefined;
...@@ -74,7 +72,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {...@@ -74,7 +72,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
74test "constant expressions" {72test "constant expressions" {
75 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO73 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO74 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7875
79 var array: [array_size]u8 = undefined;76 var array: [array_size]u8 = undefined;
80 try expect(@sizeOf(@TypeOf(array)) == 20);77 try expect(@sizeOf(@TypeOf(array)) == 20);
...@@ -143,7 +140,6 @@ test "pointer to type" {...@@ -143,7 +140,6 @@ test "pointer to type" {
143test "a type constructed in a global expression" {140test "a type constructed in a global expression" {
144 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
147143
148 var l: List = undefined;144 var l: List = undefined;
149 l.array[0] = 10;145 l.array[0] = 10;
...@@ -202,8 +198,6 @@ test "@setEvalBranchQuota" {...@@ -202,8 +198,6 @@ test "@setEvalBranchQuota" {
202}198}
203199
204test "constant struct with negation" {200test "constant struct with negation" {
205 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
206
207 try expect(vertices[0].x == @as(f32, -0.6));201 try expect(vertices[0].x == @as(f32, -0.6));
208}202}
209const Vertex = struct {203const Vertex = struct {
...@@ -308,8 +302,6 @@ fn performFn(comptime prefix_char: u8, start_value: i32) i32 {...@@ -308,8 +302,6 @@ fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
308}302}
309303
310test "comptime iterate over fn ptr list" {304test "comptime iterate over fn ptr list" {
311 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
312
313 try expect(performFn('t', 1) == 6);305 try expect(performFn('t', 1) == 6);
314 try expect(performFn('o', 0) == 1);306 try expect(performFn('o', 0) == 1);
315 try expect(performFn('w', 99) == 99);307 try expect(performFn('w', 99) == 99);
...@@ -348,7 +340,6 @@ fn doesAlotT(comptime T: type, value: usize) T {...@@ -348,7 +340,6 @@ fn doesAlotT(comptime T: type, value: usize) T {
348test "@setEvalBranchQuota at same scope as generic function call" {340test "@setEvalBranchQuota at same scope as generic function call" {
349 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO342 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
351 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
352343
353 try expect(doesAlotT(u32, 2) == 2);344 try expect(doesAlotT(u32, 2) == 2);
354}345}
...@@ -385,8 +376,6 @@ test "zero extend from u0 to u1" {...@@ -385,8 +376,6 @@ test "zero extend from u0 to u1" {
385}376}
386377
387test "return 0 from function that has u0 return type" {378test "return 0 from function that has u0 return type" {
388 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
389
390 const S = struct {379 const S = struct {
391 fn foo_zero() u0 {380 fn foo_zero() u0 {
392 return 0;381 return 0;
...@@ -417,8 +406,6 @@ var st_init_str_foo = StInitStrFoo{...@@ -417,8 +406,6 @@ var st_init_str_foo = StInitStrFoo{
417};406};
418407
419test "inline for with same type but different values" {408test "inline for with same type but different values" {
420 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
421
422 var res: usize = 0;409 var res: usize = 0;
423 inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| {410 inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| {
424 var a: T = undefined;411 var a: T = undefined;
...@@ -544,7 +531,6 @@ test "runtime 128 bit integer division" {...@@ -544,7 +531,6 @@ test "runtime 128 bit integer division" {
544test "@tagName of @typeInfo" {531test "@tagName of @typeInfo" {
545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO532 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
546 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO533 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
547 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
548534
549 const str = @tagName(@typeInfo(u8));535 const str = @tagName(@typeInfo(u8));
550 try expect(std.mem.eql(u8, str, "Int"));536 try expect(std.mem.eql(u8, str, "Int"));
...@@ -554,7 +540,6 @@ test "static eval list init" {...@@ -554,7 +540,6 @@ test "static eval list init" {
554 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO540 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
555 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO541 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
556 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO542 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
557 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
558543
559 try expect(static_vec3.data[2] == 1.0);544 try expect(static_vec3.data[2] == 1.0);
560 try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);545 try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
...@@ -586,7 +571,6 @@ test "inlined loop has array literal with elided runtime scope on first iteratio...@@ -586,7 +571,6 @@ test "inlined loop has array literal with elided runtime scope on first iteratio
586test "ptr to local array argument at comptime" {571test "ptr to local array argument at comptime" {
587 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
588 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO573 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
589 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
590574
591 comptime {575 comptime {
592 var bytes: [10]u8 = undefined;576 var bytes: [10]u8 = undefined;
...@@ -623,7 +607,6 @@ const hi1 = "hi";...@@ -623,7 +607,6 @@ const hi1 = "hi";
623const hi2 = hi1;607const hi2 = hi1;
624test "const global shares pointer with other same one" {608test "const global shares pointer with other same one" {
625 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO609 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
626 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
627610
628 try assertEqualPtrs(&hi1[0], &hi2[0]);611 try assertEqualPtrs(&hi1[0], &hi2[0]);
629 try comptime expect(&hi1[0] == &hi2[0]);612 try comptime expect(&hi1[0] == &hi2[0]);
...@@ -659,8 +642,6 @@ pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {...@@ -659,8 +642,6 @@ pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
659}642}
660643
661test "comptime function with mutable pointer is not memoized" {644test "comptime function with mutable pointer is not memoized" {
662 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
663
664 comptime {645 comptime {
665 var x: i32 = 1;646 var x: i32 = 1;
666 const ptr = &x;647 const ptr = &x;
...@@ -729,6 +710,7 @@ fn loopNTimes(comptime n: usize) void {...@@ -729,6 +710,7 @@ fn loopNTimes(comptime n: usize) void {
729}710}
730711
731test "variable inside inline loop that has different types on different iterations" {712test "variable inside inline loop that has different types on different iterations" {
713 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
732 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });714 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });
733}715}
734716
...@@ -752,7 +734,6 @@ test "array concatenation of function calls" {...@@ -752,7 +734,6 @@ test "array concatenation of function calls" {
752 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;734 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
753 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;735 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
754 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO736 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
755 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
756737
757 var a = oneItem(3) ++ oneItem(4);738 var a = oneItem(3) ++ oneItem(4);
758 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 }));739 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 }));
...@@ -762,7 +743,6 @@ test "array multiplication of function calls" {...@@ -762,7 +743,6 @@ test "array multiplication of function calls" {
762 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;743 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
763 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;744 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
764 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO745 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
765 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
766746
767 var a = oneItem(3) ** scalar(2);747 var a = oneItem(3) ** scalar(2);
768 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 }));748 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 }));
...@@ -851,7 +831,6 @@ test "array multiplication sets the sentinel - value" {...@@ -851,7 +831,6 @@ test "array multiplication sets the sentinel - value" {
851 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;831 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
852 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;832 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
853 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO833 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
854 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
855834
856 var a = [2:7]u3{ 1, 6 };835 var a = [2:7]u3{ 1, 6 };
857 var b = a ** 2;836 var b = a ** 2;
...@@ -868,7 +847,6 @@ test "array multiplication sets the sentinel - pointer" {...@@ -868,7 +847,6 @@ test "array multiplication sets the sentinel - pointer" {
868 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;847 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
869 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;848 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
870 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO849 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
871 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
872850
873 var a = [2:7]u3{ 1, 6 };851 var a = [2:7]u3{ 1, 6 };
874 var b = &a ** 2;852 var b = &a ** 2;
...@@ -1003,7 +981,6 @@ test "closure capture type of runtime-known var" {...@@ -1003,7 +981,6 @@ test "closure capture type of runtime-known var" {
1003981
1004test "comptime break passing through runtime condition converted to runtime break" {982test "comptime break passing through runtime condition converted to runtime break" {
1005 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO983 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1006 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1007984
1008 const S = struct {985 const S = struct {
1009 fn doTheTest() !void {986 fn doTheTest() !void {
...@@ -1037,7 +1014,6 @@ test "comptime break to outer loop passing through runtime condition converted t...@@ -1037,7 +1014,6 @@ test "comptime break to outer loop passing through runtime condition converted t
1037 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1014 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1038 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1039 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1016 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1040 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10411017
1042 const S = struct {1018 const S = struct {
1043 fn doTheTest() !void {1019 fn doTheTest() !void {
...@@ -1109,7 +1085,6 @@ test "comptime break operand passing through runtime switch converted to runtime...@@ -1109,7 +1085,6 @@ test "comptime break operand passing through runtime switch converted to runtime
1109test "no dependency loop for alignment of self struct" {1085test "no dependency loop for alignment of self struct" {
1110 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1086 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1087 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1112 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11131088
1114 const S = struct {1089 const S = struct {
1115 fn doTheTest() !void {1090 fn doTheTest() !void {
...@@ -1147,7 +1122,6 @@ test "no dependency loop for alignment of self struct" {...@@ -1147,7 +1122,6 @@ test "no dependency loop for alignment of self struct" {
1147test "no dependency loop for alignment of self bare union" {1122test "no dependency loop for alignment of self bare union" {
1148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1124 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1150 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11511125
1152 const S = struct {1126 const S = struct {
1153 fn doTheTest() !void {1127 fn doTheTest() !void {
...@@ -1185,7 +1159,6 @@ test "no dependency loop for alignment of self bare union" {...@@ -1185,7 +1159,6 @@ test "no dependency loop for alignment of self bare union" {
1185test "no dependency loop for alignment of self tagged union" {1159test "no dependency loop for alignment of self tagged union" {
1186 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1188 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11891162
1190 const S = struct {1163 const S = struct {
1191 fn doTheTest() !void {1164 fn doTheTest() !void {
...@@ -1376,7 +1349,6 @@ test "lazy value is resolved as slice operand" {...@@ -1376,7 +1349,6 @@ test "lazy value is resolved as slice operand" {
1376 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1349 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1377 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1350 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1378 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1351 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1379 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13801352
1381 const A = struct { a: u32 };1353 const A = struct { a: u32 };
1382 var a: [512]u64 = undefined;1354 var a: [512]u64 = undefined;
...@@ -1434,7 +1406,6 @@ test "inline for inside a runtime condition" {...@@ -1434,7 +1406,6 @@ test "inline for inside a runtime condition" {
14341406
1435test "continue in inline for inside a comptime switch" {1407test "continue in inline for inside a comptime switch" {
1436 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1408 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1437 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14381409
1439 const arr = .{ 1, 2, 3 };1410 const arr = .{ 1, 2, 3 };
1440 var count: u8 = 0;1411 var count: u8 = 0;
...@@ -1500,7 +1471,6 @@ test "continue nested inline for loop in named block expr" {...@@ -1500,7 +1471,6 @@ test "continue nested inline for loop in named block expr" {
15001471
1501test "x and false is comptime-known false" {1472test "x and false is comptime-known false" {
1502 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1503 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15041474
1505 const T = struct {1475 const T = struct {
1506 var x: u32 = 0;1476 var x: u32 = 0;
...@@ -1528,7 +1498,6 @@ test "x and false is comptime-known false" {...@@ -1528,7 +1498,6 @@ test "x and false is comptime-known false" {
15281498
1529test "x or true is comptime-known true" {1499test "x or true is comptime-known true" {
1530 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1531 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15321501
1533 const T = struct {1502 const T = struct {
1534 var x: u32 = 0;1503 var x: u32 = 0;
...@@ -1558,7 +1527,6 @@ test "non-optional and optional array elements concatenated" {...@@ -1558,7 +1527,6 @@ test "non-optional and optional array elements concatenated" {
1558 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1527 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1559 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1528 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1560 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1529 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1561 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15621530
1563 const array = [1]u8{'A'} ++ [1]?u8{null};1531 const array = [1]u8{'A'} ++ [1]?u8{null};
1564 var index: usize = 0;1532 var index: usize = 0;
...@@ -1647,8 +1615,6 @@ test "result of nested switch assigned to variable" {...@@ -1647,8 +1615,6 @@ test "result of nested switch assigned to variable" {
1647}1615}
16481616
1649test "inline for loop of functions returning error unions" {1617test "inline for loop of functions returning error unions" {
1650 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1651
1652 const T1 = struct {1618 const T1 = struct {
1653 fn v() error{}!usize {1619 fn v() error{}!usize {
1654 return 1;1620 return 1;
test/behavior/floatop.zig-3
...@@ -736,7 +736,6 @@ test "@ceil" {...@@ -736,7 +736,6 @@ test "@ceil" {
736 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO736 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
737 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO737 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO738 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
739 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
740739
741 try comptime testCeil();740 try comptime testCeil();
742 try testCeil();741 try testCeil();
...@@ -1053,7 +1052,6 @@ test "negation f128" {...@@ -1053,7 +1052,6 @@ test "negation f128" {
1053test "eval @setFloatMode at compile-time" {1052test "eval @setFloatMode at compile-time" {
1054 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1053 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1055 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1054 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1056 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10571055
1058 const result = comptime fnWithFloatMode();1056 const result = comptime fnWithFloatMode();
1059 try expect(result == 1234.0);1057 try expect(result == 1234.0);
...@@ -1089,7 +1087,6 @@ test "comptime fixed-width float non-zero divided by zero produces signed Inf" {...@@ -1089,7 +1087,6 @@ test "comptime fixed-width float non-zero divided by zero produces signed Inf" {
1089 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1087 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1090 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1088 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1091 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1089 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1092 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10931090
1094 inline for (.{ f16, f32, f64, f80, f128 }) |F| {1091 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
1095 const pos = @as(F, 1) / @as(F, 0);1092 const pos = @as(F, 1) / @as(F, 0);
test/behavior/fn.zig+2-12
...@@ -20,8 +20,6 @@ fn testLocVars(b: i32) void {...@@ -20,8 +20,6 @@ fn testLocVars(b: i32) void {
20}20}
2121
22test "mutable local variables" {22test "mutable local variables" {
23 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
24
25 var zero: i32 = 0;23 var zero: i32 = 0;
26 try expect(zero == 0);24 try expect(zero == 0);
2725
...@@ -53,8 +51,6 @@ test "weird function name" {...@@ -53,8 +51,6 @@ test "weird function name" {
53}51}
5452
55test "assign inline fn to const variable" {53test "assign inline fn to const variable" {
56 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
57
58 const a = inlineFn;54 const a = inlineFn;
59 a();55 a();
60}56}
...@@ -190,7 +186,6 @@ test "function with complex callconv and return type expressions" {...@@ -190,7 +186,6 @@ test "function with complex callconv and return type expressions" {
190186
191test "pass by non-copying value" {187test "pass by non-copying value" {
192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO188 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
193 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
194189
195 try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);190 try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
196}191}
...@@ -218,7 +213,6 @@ fn addPointCoordsVar(pt: anytype) !i32 {...@@ -218,7 +213,6 @@ fn addPointCoordsVar(pt: anytype) !i32 {
218213
219test "pass by non-copying value as method" {214test "pass by non-copying value as method" {
220 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO215 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
221 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
222216
223 var pt = Point2{ .x = 1, .y = 2 };217 var pt = Point2{ .x = 1, .y = 2 };
224 try expect(pt.addPointCoords() == 3);218 try expect(pt.addPointCoords() == 3);
...@@ -235,7 +229,6 @@ const Point2 = struct {...@@ -235,7 +229,6 @@ const Point2 = struct {
235229
236test "pass by non-copying value as method, which is generic" {230test "pass by non-copying value as method, which is generic" {
237 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO231 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
238 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
239232
240 var pt = Point3{ .x = 1, .y = 2 };233 var pt = Point3{ .x = 1, .y = 2 };
241 try expect(pt.addPointCoords(i32) == 3);234 try expect(pt.addPointCoords(i32) == 3);
...@@ -253,7 +246,6 @@ const Point3 = struct {...@@ -253,7 +246,6 @@ const Point3 = struct {
253246
254test "pass by non-copying value as method, at comptime" {247test "pass by non-copying value as method, at comptime" {
255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
257249
258 comptime {250 comptime {
259 var pt = Point2{ .x = 1, .y = 2 };251 var pt = Point2{ .x = 1, .y = 2 };
...@@ -396,8 +388,6 @@ test "function call with anon list literal - 2D" {...@@ -396,8 +388,6 @@ test "function call with anon list literal - 2D" {
396}388}
397389
398test "ability to give comptime types and non comptime types to same parameter" {390test "ability to give comptime types and non comptime types to same parameter" {
399 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
400
401 const S = struct {391 const S = struct {
402 fn doTheTest() !void {392 fn doTheTest() !void {
403 var x: i32 = 1;393 var x: i32 = 1;
...@@ -415,8 +405,6 @@ test "ability to give comptime types and non comptime types to same parameter" {...@@ -415,8 +405,6 @@ test "ability to give comptime types and non comptime types to same parameter" {
415}405}
416406
417test "function with inferred error set but returning no error" {407test "function with inferred error set but returning no error" {
418 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
419
420 const S = struct {408 const S = struct {
421 fn foo() !void {}409 fn foo() !void {}
422 };410 };
...@@ -583,6 +571,8 @@ test "lazy values passed to anytype parameter" {...@@ -583,6 +571,8 @@ test "lazy values passed to anytype parameter" {
583}571}
584572
585test "pass and return comptime-only types" {573test "pass and return comptime-only types" {
574 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
575
586 const S = struct {576 const S = struct {
587 fn returnNull(comptime x: @Type(.Null)) @Type(.Null) {577 fn returnNull(comptime x: @Type(.Null)) @Type(.Null) {
588 return x;578 return x;
test/behavior/for.zig-4
...@@ -257,7 +257,6 @@ test "for loop with else branch" {...@@ -257,7 +257,6 @@ test "for loop with else branch" {
257test "count over fixed range" {257test "count over fixed range" {
258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
260 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
261260
262 var sum: usize = 0;261 var sum: usize = 0;
263 for (0..6) |i| {262 for (0..6) |i| {
...@@ -270,7 +269,6 @@ test "count over fixed range" {...@@ -270,7 +269,6 @@ test "count over fixed range" {
270test "two counters" {269test "two counters" {
271 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
272 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO271 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
273 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
274272
275 var sum: usize = 0;273 var sum: usize = 0;
276 for (0..10, 10..20) |i, j| {274 for (0..10, 10..20) |i, j| {
...@@ -318,7 +316,6 @@ test "slice and two counters, one is offset and one is runtime" {...@@ -318,7 +316,6 @@ test "slice and two counters, one is offset and one is runtime" {
318 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO317 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO318 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
322319
323 const slice: []const u8 = "blah";320 const slice: []const u8 = "blah";
324 var start: usize = 0;321 var start: usize = 0;
...@@ -406,7 +403,6 @@ test "inline for with slice as the comptime-known" {...@@ -406,7 +403,6 @@ test "inline for with slice as the comptime-known" {
406 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO403 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
407 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
410406
411 const comptime_slice = "hello";407 const comptime_slice = "hello";
412 var runtime_i: usize = 3;408 var runtime_i: usize = 3;
test/behavior/generics.zig+1-14
...@@ -55,7 +55,6 @@ test "fn with comptime args" {...@@ -55,7 +55,6 @@ test "fn with comptime args" {
55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
57 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO57 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5958
60 try expect(gimmeTheBigOne(1234, 5678) == 5678);59 try expect(gimmeTheBigOne(1234, 5678) == 5678);
61 try expect(shouldCallSameInstance(34, 12) == 34);60 try expect(shouldCallSameInstance(34, 12) == 34);
...@@ -66,7 +65,6 @@ test "anytype params" {...@@ -66,7 +65,6 @@ test "anytype params" {
66 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;65 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
67 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
68 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7068
71 try expect(max_i32(12, 34) == 34);69 try expect(max_i32(12, 34) == 34);
72 try expect(max_f64(1.2, 3.4) == 3.4);70 try expect(max_f64(1.2, 3.4) == 3.4);
...@@ -91,7 +89,6 @@ fn max_f64(a: f64, b: f64) f64 {...@@ -91,7 +89,6 @@ fn max_f64(a: f64, b: f64) f64 {
91test "type constructed by comptime function call" {89test "type constructed by comptime function call" {
92 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;90 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
93 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO91 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
94 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9592
96 var l: SimpleList(10) = undefined;93 var l: SimpleList(10) = undefined;
97 l.array[0] = 10;94 l.array[0] = 10;
...@@ -115,7 +112,6 @@ test "function with return type type" {...@@ -115,7 +112,6 @@ test "function with return type type" {
115 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
116 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
117 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO114 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
118 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
119115
120 var list: List(i32) = undefined;116 var list: List(i32) = undefined;
121 var list2: List(i32) = undefined;117 var list2: List(i32) = undefined;
...@@ -147,8 +143,6 @@ fn GenericDataThing(comptime count: isize) type {...@@ -147,8 +143,6 @@ fn GenericDataThing(comptime count: isize) type {
147}143}
148144
149test "use generic param in generic param" {145test "use generic param in generic param" {
150 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
151
152 try expect(aGenericFn(i32, 3, 4) == 7);146 try expect(aGenericFn(i32, 3, 4) == 7);
153}147}
154fn aGenericFn(comptime T: type, comptime a: T, b: T) T {148fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
...@@ -178,7 +172,6 @@ test "generic fn keeps non-generic parameter types" {...@@ -178,7 +172,6 @@ test "generic fn keeps non-generic parameter types" {
178 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;172 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;173 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
180 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO174 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
182175
183 const A = 128;176 const A = 128;
184177
...@@ -254,7 +247,6 @@ test "generic function instantiation turns into comptime call" {...@@ -254,7 +247,6 @@ test "generic function instantiation turns into comptime call" {
254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
255 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO248 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO249 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
257 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
258250
259 const S = struct {251 const S = struct {
260 fn doTheTest() !void {252 fn doTheTest() !void {
...@@ -288,6 +280,7 @@ test "generic function instantiation turns into comptime call" {...@@ -288,6 +280,7 @@ test "generic function instantiation turns into comptime call" {
288280
289test "generic function with void and comptime parameter" {281test "generic function with void and comptime parameter" {
290 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO282 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
291284
292 const S = struct { x: i32 };285 const S = struct { x: i32 };
293 const namespace = struct {286 const namespace = struct {
...@@ -304,7 +297,6 @@ test "generic function with void and comptime parameter" {...@@ -304,7 +297,6 @@ test "generic function with void and comptime parameter" {
304test "anonymous struct return type referencing comptime parameter" {297test "anonymous struct return type referencing comptime parameter" {
305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO299 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
308300
309 const S = struct {301 const S = struct {
310 pub fn extraData(comptime T: type, index: usize) struct { data: T, end: usize } {302 pub fn extraData(comptime T: type, index: usize) struct { data: T, end: usize } {
...@@ -405,8 +397,6 @@ test "generic struct as parameter type" {...@@ -405,8 +397,6 @@ test "generic struct as parameter type" {
405}397}
406398
407test "slice as parameter type" {399test "slice as parameter type" {
408 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
409
410 const S = struct {400 const S = struct {
411 fn internComptimeString(comptime str: []const u8) *const []const u8 {401 fn internComptimeString(comptime str: []const u8) *const []const u8 {
412 return &struct {402 return &struct {
...@@ -421,8 +411,6 @@ test "slice as parameter type" {...@@ -421,8 +411,6 @@ test "slice as parameter type" {
421}411}
422412
423test "null sentinel pointer passed as generic argument" {413test "null sentinel pointer passed as generic argument" {
424 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
425
426 const S = struct {414 const S = struct {
427 fn doTheTest(a: anytype) !void {415 fn doTheTest(a: anytype) !void {
428 try std.testing.expect(@intFromPtr(a) == 8);416 try std.testing.expect(@intFromPtr(a) == 8);
...@@ -433,7 +421,6 @@ test "null sentinel pointer passed as generic argument" {...@@ -433,7 +421,6 @@ test "null sentinel pointer passed as generic argument" {
433421
434test "generic function passed as comptime argument" {422test "generic function passed as comptime argument" {
435 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO423 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
436 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
437424
438 const S = struct {425 const S = struct {
439 fn doMath(comptime f: fn (type, i32, i32) error{Overflow}!i32, a: i32, b: i32) !void {426 fn doMath(comptime f: fn (type, i32, i32) error{Overflow}!i32, a: i32, b: i32) !void {
test/behavior/inline_switch.zig-3
...@@ -47,7 +47,6 @@ test "inline switch unions" {...@@ -47,7 +47,6 @@ test "inline switch unions" {
47 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5150
52 var x: U = .a;51 var x: U = .a;
53 switch (x) {52 switch (x) {
...@@ -141,8 +140,6 @@ test "inline else int all values" {...@@ -141,8 +140,6 @@ test "inline else int all values" {
141}140}
142141
143test "inline switch capture is set when switch operand is comptime known" {142test "inline switch capture is set when switch operand is comptime known" {
144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
145
146 const U2 = union(enum) {143 const U2 = union(enum) {
147 a: u32,144 a: u32,
148 };145 };
test/behavior/math.zig+2-3
...@@ -1020,7 +1020,6 @@ test "@subWithOverflow" {...@@ -1020,7 +1020,6 @@ test "@subWithOverflow" {
1020 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1020 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1021 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1022 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1022 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1023 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10241023
1025 {1024 {
1026 var a: u8 = 1;1025 var a: u8 = 1;
...@@ -1146,8 +1145,6 @@ test "overflow arithmetic with u0 values" {...@@ -1146,8 +1145,6 @@ test "overflow arithmetic with u0 values" {
1146}1145}
11471146
1148test "allow signed integer division/remainder when values are comptime-known and positive or exact" {1147test "allow signed integer division/remainder when values are comptime-known and positive or exact" {
1149 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1150
1151 try expect(5 / 3 == 1);1148 try expect(5 / 3 == 1);
1152 try expect(-5 / -3 == 1);1149 try expect(-5 / -3 == 1);
1153 try expect(-6 / 3 == -2);1150 try expect(-6 / 3 == -2);
...@@ -1289,6 +1286,8 @@ fn testShrExact(x: u8) !void {...@@ -1289,6 +1286,8 @@ fn testShrExact(x: u8) !void {
1289}1286}
12901287
1291test "shift left/right on u0 operand" {1288test "shift left/right on u0 operand" {
1289 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1290
1292 const S = struct {1291 const S = struct {
1293 fn doTheTest() !void {1292 fn doTheTest() !void {
1294 var x: u0 = 0;1293 var x: u0 = 0;
test/behavior/maximum_minimum.zig-2
...@@ -200,7 +200,6 @@ test "@min/@max on comptime_int" {...@@ -200,7 +200,6 @@ test "@min/@max on comptime_int" {
200 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO200 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
201 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO201 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
204203
205 const min = @min(1, 2, -2, -1);204 const min = @min(1, 2, -2, -1);
206 const max = @max(1, 2, -2, -1);205 const max = @max(1, 2, -2, -1);
...@@ -257,7 +256,6 @@ test "@min/@max notices bounds from types when comptime-known value is undef" {...@@ -257,7 +256,6 @@ test "@min/@max notices bounds from types when comptime-known value is undef" {
257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO256 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO257 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
260 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
261259
262 var x: u32 = 1_000_000;260 var x: u32 = 1_000_000;
263 const y: u16 = undefined;261 const y: u16 = undefined;
test/behavior/optional.zig+2
...@@ -500,6 +500,8 @@ test "cast slice to const slice nested in error union and optional" {...@@ -500,6 +500,8 @@ test "cast slice to const slice nested in error union and optional" {
500}500}
501501
502test "variable of optional of noreturn" {502test "variable of optional of noreturn" {
503 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
504
503 var null_opv: ?noreturn = null;505 var null_opv: ?noreturn = null;
504 try std.testing.expectEqual(@as(?noreturn, null), null_opv);506 try std.testing.expectEqual(@as(?noreturn, null), null_opv);
505}507}
test/behavior/pointers.zig-9
...@@ -125,7 +125,6 @@ fn testDerefPtrOneVal() !void {...@@ -125,7 +125,6 @@ fn testDerefPtrOneVal() !void {
125}125}
126126
127test "peer type resolution with C pointers" {127test "peer type resolution with C pointers" {
128 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
129 var ptr_one: *u8 = undefined;128 var ptr_one: *u8 = undefined;
130 var ptr_many: [*]u8 = undefined;129 var ptr_many: [*]u8 = undefined;
131 var ptr_c: [*c]u8 = undefined;130 var ptr_c: [*c]u8 = undefined;
...@@ -141,7 +140,6 @@ test "peer type resolution with C pointers" {...@@ -141,7 +140,6 @@ test "peer type resolution with C pointers" {
141}140}
142141
143test "peer type resolution with C pointer and const pointer" {142test "peer type resolution with C pointer and const pointer" {
144 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
145 var ptr_c: [*c]u8 = undefined;143 var ptr_c: [*c]u8 = undefined;
146 const ptr_const: u8 = undefined;144 const ptr_const: u8 = undefined;
147 try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8);145 try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8);
...@@ -314,7 +312,6 @@ test "allow any sentinel" {...@@ -314,7 +312,6 @@ test "allow any sentinel" {
314test "pointer sentinel with enums" {312test "pointer sentinel with enums" {
315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO314 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
317 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
318315
319 const S = struct {316 const S = struct {
320 const Number = enum {317 const Number = enum {
...@@ -336,7 +333,6 @@ test "pointer sentinel with optional element" {...@@ -336,7 +333,6 @@ test "pointer sentinel with optional element" {
336 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO334 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO335 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
340336
341 const S = struct {337 const S = struct {
342 fn doTheTest() !void {338 fn doTheTest() !void {
...@@ -353,7 +349,6 @@ test "pointer sentinel with +inf" {...@@ -353,7 +349,6 @@ test "pointer sentinel with +inf" {
353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO349 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
354 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO350 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
355 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO351 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
356 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
357352
358 const S = struct {353 const S = struct {
359 fn doTheTest() !void {354 fn doTheTest() !void {
...@@ -374,7 +369,6 @@ test "pointer to array at fixed address" {...@@ -374,7 +369,6 @@ test "pointer to array at fixed address" {
374}369}
375370
376test "pointer arithmetic affects the alignment" {371test "pointer arithmetic affects the alignment" {
377 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
378 {372 {
379 var ptr: [*]align(8) u32 = undefined;373 var ptr: [*]align(8) u32 = undefined;
380 var x: usize = 1;374 var x: usize = 1;
...@@ -430,7 +424,6 @@ test "indexing array with sentinel returns correct type" {...@@ -430,7 +424,6 @@ test "indexing array with sentinel returns correct type" {
430test "element pointer to slice" {424test "element pointer to slice" {
431 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO425 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
432 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO426 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
434427
435 const S = struct {428 const S = struct {
436 fn doTheTest() !void {429 fn doTheTest() !void {
...@@ -453,7 +446,6 @@ test "element pointer to slice" {...@@ -453,7 +446,6 @@ test "element pointer to slice" {
453test "element pointer arithmetic to slice" {446test "element pointer arithmetic to slice" {
454 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO447 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
455 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO448 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
456 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
457449
458 const S = struct {450 const S = struct {
459 fn doTheTest() !void {451 fn doTheTest() !void {
...@@ -478,7 +470,6 @@ test "element pointer arithmetic to slice" {...@@ -478,7 +470,6 @@ test "element pointer arithmetic to slice" {
478470
479test "array slicing to slice" {471test "array slicing to slice" {
480 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO472 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
481 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
482473
483 const S = struct {474 const S = struct {
484 fn doTheTest() !void {475 fn doTheTest() !void {
test/behavior/slice.zig-11
...@@ -29,7 +29,6 @@ comptime {...@@ -29,7 +29,6 @@ comptime {
2929
30test "slicing" {30test "slicing" {
31 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3332
34 var array: [20]i32 = undefined;33 var array: [20]i32 = undefined;
3534
...@@ -122,7 +121,6 @@ test "slice of type" {...@@ -122,7 +121,6 @@ test "slice of type" {
122121
123test "generic malloc free" {122test "generic malloc free" {
124 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
125 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
126124
127 const a = memAlloc(u8, 10) catch unreachable;125 const a = memAlloc(u8, 10) catch unreachable;
128 memFree(u8, a);126 memFree(u8, a);
...@@ -303,7 +301,6 @@ test "slice type with custom alignment" {...@@ -303,7 +301,6 @@ test "slice type with custom alignment" {
303301
304test "obtaining a null terminated slice" {302test "obtaining a null terminated slice" {
305 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
307304
308 // here we have a normal array305 // here we have a normal array
309 var buf: [50]u8 = undefined;306 var buf: [50]u8 = undefined;
...@@ -346,7 +343,6 @@ test "empty array to slice" {...@@ -346,7 +343,6 @@ test "empty array to slice" {
346test "@ptrCast slice to pointer" {343test "@ptrCast slice to pointer" {
347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO345 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
349 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
350346
351 const S = struct {347 const S = struct {
352 fn doTheTest() !void {348 fn doTheTest() !void {
...@@ -572,7 +568,6 @@ test "slice syntax resulting in pointer-to-array" {...@@ -572,7 +568,6 @@ test "slice syntax resulting in pointer-to-array" {
572test "slice pointer-to-array null terminated" {568test "slice pointer-to-array null terminated" {
573 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
574 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO570 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
575 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
576571
577 comptime {572 comptime {
578 var array = [5:0]u8{ 1, 2, 3, 4, 5 };573 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
...@@ -626,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {...@@ -626,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {
626 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
627 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
628 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO623 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
629 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
630624
631 const S = struct {625 const S = struct {
632 const U = union {626 const U = union {
...@@ -714,7 +708,6 @@ test "slice sentinel access at comptime" {...@@ -714,7 +708,6 @@ test "slice sentinel access at comptime" {
714test "slicing array with sentinel as end index" {708test "slicing array with sentinel as end index" {
715 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;709 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
716 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
717 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
718711
719 const S = struct {712 const S = struct {
720 fn do() !void {713 fn do() !void {
...@@ -733,7 +726,6 @@ test "slicing array with sentinel as end index" {...@@ -733,7 +726,6 @@ test "slicing array with sentinel as end index" {
733test "slicing slice with sentinel as end index" {726test "slicing slice with sentinel as end index" {
734 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;727 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
735 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO728 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
736 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
737729
738 const S = struct {730 const S = struct {
739 fn do() !void {731 fn do() !void {
...@@ -762,8 +754,6 @@ test "slice len modification at comptime" {...@@ -762,8 +754,6 @@ test "slice len modification at comptime" {
762}754}
763755
764test "slice field ptr const" {756test "slice field ptr const" {
765 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
766
767 const const_slice: []const u8 = "string";757 const const_slice: []const u8 = "string";
768758
769 const const_ptr_const_slice = &const_slice;759 const const_ptr_const_slice = &const_slice;
...@@ -777,7 +767,6 @@ test "slice field ptr const" {...@@ -777,7 +767,6 @@ test "slice field ptr const" {
777767
778test "slice field ptr var" {768test "slice field ptr var" {
779 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO769 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
780 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
781770
782 var var_slice: []const u8 = "string";771 var var_slice: []const u8 = "string";
783772
test/behavior/struct.zig+11-14
...@@ -109,7 +109,6 @@ fn testMutation(foo: *StructFoo) void {...@@ -109,7 +109,6 @@ fn testMutation(foo: *StructFoo) void {
109109
110test "struct byval assign" {110test "struct byval assign" {
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 var foo1: StructFoo = undefined;113 var foo1: StructFoo = undefined;
115 var foo2: StructFoo = undefined;114 var foo2: StructFoo = undefined;
...@@ -129,14 +128,14 @@ test "call struct static method" {...@@ -129,14 +128,14 @@ test "call struct static method" {
129const should_be_11 = StructWithNoFields.add(5, 6);128const should_be_11 = StructWithNoFields.add(5, 6);
130129
131test "invoke static method in global scope" {130test "invoke static method in global scope" {
132 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
133
134 try expect(should_be_11 == 11);131 try expect(should_be_11 == 11);
135}132}
136133
137const empty_global_instance = StructWithNoFields{};134const empty_global_instance = StructWithNoFields{};
138135
139test "return empty struct instance" {136test "return empty struct instance" {
137 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
138
140 _ = returnEmptyStructInstance();139 _ = returnEmptyStructInstance();
141}140}
142fn returnEmptyStructInstance() StructWithNoFields {141fn returnEmptyStructInstance() StructWithNoFields {
...@@ -253,7 +252,6 @@ test "usingnamespace within struct scope" {...@@ -253,7 +252,6 @@ test "usingnamespace within struct scope" {
253test "struct field init with catch" {252test "struct field init with catch" {
254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;253 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO254 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
257255
258 const S = struct {256 const S = struct {
259 fn doTheTest() !void {257 fn doTheTest() !void {
...@@ -331,6 +329,7 @@ const VoidStructFieldsFoo = struct {...@@ -331,6 +329,7 @@ const VoidStructFieldsFoo = struct {
331329
332test "return empty struct from fn" {330test "return empty struct from fn" {
333 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO331 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
332 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
334333
335 _ = testReturnEmptyStructFromFn();334 _ = testReturnEmptyStructFromFn();
336}335}
...@@ -364,8 +363,6 @@ test "self-referencing struct via array member" {...@@ -364,8 +363,6 @@ test "self-referencing struct via array member" {
364}363}
365364
366test "empty struct method call" {365test "empty struct method call" {
367 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
368
369 const es = EmptyStruct{};366 const es = EmptyStruct{};
370 try expect(es.method() == 1234);367 try expect(es.method() == 1234);
371}368}
...@@ -550,7 +547,6 @@ test "implicit cast packed struct field to const ptr" {...@@ -550,7 +547,6 @@ test "implicit cast packed struct field to const ptr" {
550547
551test "zero-bit field in packed struct" {548test "zero-bit field in packed struct" {
552 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
553 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
554550
555 const S = packed struct {551 const S = packed struct {
556 x: u10,552 x: u10,
...@@ -893,6 +889,8 @@ test "anonymous struct literal syntax" {...@@ -893,6 +889,8 @@ test "anonymous struct literal syntax" {
893}889}
894890
895test "fully anonymous struct" {891test "fully anonymous struct" {
892 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
893
896 const S = struct {894 const S = struct {
897 fn doTheTest() !void {895 fn doTheTest() !void {
898 try dump(.{896 try dump(.{
...@@ -915,6 +913,8 @@ test "fully anonymous struct" {...@@ -915,6 +913,8 @@ test "fully anonymous struct" {
915}913}
916914
917test "fully anonymous list literal" {915test "fully anonymous list literal" {
916 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
917
918 const S = struct {918 const S = struct {
919 fn doTheTest() !void {919 fn doTheTest() !void {
920 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });920 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
...@@ -942,8 +942,6 @@ test "tuple assigned to variable" {...@@ -942,8 +942,6 @@ test "tuple assigned to variable" {
942}942}
943943
944test "comptime struct field" {944test "comptime struct field" {
945 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
946
947 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO945 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
948 if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO946 if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO
949947
...@@ -981,7 +979,6 @@ test "struct with union field" {...@@ -981,7 +979,6 @@ test "struct with union field" {
981 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO979 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
982 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO980 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
983 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO981 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
984 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
985982
986 const Value = struct {983 const Value = struct {
987 ref: u32 = 2,984 ref: u32 = 2,
...@@ -1432,8 +1429,6 @@ test "struct field has a pointer to an aligned version of itself" {...@@ -1432,8 +1429,6 @@ test "struct field has a pointer to an aligned version of itself" {
1432}1429}
14331430
1434test "struct has only one reference" {1431test "struct has only one reference" {
1435 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1436
1437 const S = struct {1432 const S = struct {
1438 fn optionalStructParam(_: ?struct { x: u8 }) void {}1433 fn optionalStructParam(_: ?struct { x: u8 }) void {}
1439 fn errorUnionStructParam(_: error{}!struct { x: u8 }) void {}1434 fn errorUnionStructParam(_: error{}!struct { x: u8 }) void {}
...@@ -1503,7 +1498,6 @@ test "discarded struct initialization works as expected" {...@@ -1503,7 +1498,6 @@ test "discarded struct initialization works as expected" {
15031498
1504test "function pointer in struct returns the struct" {1499test "function pointer in struct returns the struct" {
1505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1506 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15071501
1508 const A = struct {1502 const A = struct {
1509 const A = @This();1503 const A = @This();
...@@ -1553,7 +1547,6 @@ test "optional field init with tuple" {...@@ -1553,7 +1547,6 @@ test "optional field init with tuple" {
15531547
1554test "if inside struct init inside if" {1548test "if inside struct init inside if" {
1555 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1549 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1556 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15571550
1558 const MyStruct = struct { x: u32 };1551 const MyStruct = struct { x: u32 };
1559 const b: u32 = 5;1552 const b: u32 = 5;
...@@ -1715,6 +1708,8 @@ test "extern struct field pointer has correct alignment" {...@@ -1715,6 +1708,8 @@ test "extern struct field pointer has correct alignment" {
1715}1708}
17161709
1717test "packed struct field in anonymous struct" {1710test "packed struct field in anonymous struct" {
1711 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1712
1718 const T = packed struct {1713 const T = packed struct {
1719 f1: bool = false,1714 f1: bool = false,
1720 };1715 };
...@@ -1740,6 +1735,8 @@ test "struct init with no result pointer sets field result types" {...@@ -1740,6 +1735,8 @@ test "struct init with no result pointer sets field result types" {
1740}1735}
17411736
1742test "runtime side-effects in comptime-known struct init" {1737test "runtime side-effects in comptime-known struct init" {
1738 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1739
1743 var side_effects: u4 = 0;1740 var side_effects: u4 = 0;
1744 const S = struct { a: u4, b: u4, c: u4, d: u4 };1741 const S = struct { a: u4, b: u4, c: u4, d: u4 };
1745 const init = S{1742 const init = S{
test/behavior/switch.zig+2-10
...@@ -232,7 +232,6 @@ test "switch prong with variable" {...@@ -232,7 +232,6 @@ test "switch prong with variable" {
232 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO232 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
233 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO233 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO234 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
235 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
236235
237 try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });236 try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
238 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });237 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
...@@ -257,7 +256,6 @@ test "switch on enum using pointer capture" {...@@ -257,7 +256,6 @@ test "switch on enum using pointer capture" {
257 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO256 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
258 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
260 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
261259
262 try testSwitchEnumPtrCapture();260 try testSwitchEnumPtrCapture();
263 try comptime testSwitchEnumPtrCapture();261 try comptime testSwitchEnumPtrCapture();
...@@ -318,7 +316,6 @@ test "switch on union with some prongs capturing" {...@@ -318,7 +316,6 @@ test "switch on union with some prongs capturing" {
318 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO316 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
319 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO317 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO318 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
322319
323 const X = union(enum) {320 const X = union(enum) {
324 a,321 a,
...@@ -355,7 +352,6 @@ test "switch on const enum with var" {...@@ -355,7 +352,6 @@ test "switch on const enum with var" {
355test "anon enum literal used in switch on union enum" {352test "anon enum literal used in switch on union enum" {
356 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO354 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
358 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
359355
360 const Foo = union(enum) {356 const Foo = union(enum) {
361 a: i32,357 a: i32,
...@@ -394,7 +390,6 @@ fn switchWithUnreachable(x: i32) i32 {...@@ -394,7 +390,6 @@ fn switchWithUnreachable(x: i32) i32 {
394390
395test "capture value of switch with all unreachable prongs" {391test "capture value of switch with all unreachable prongs" {
396 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO392 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
398393
399 const x = return_a_number() catch |err| switch (err) {394 const x = return_a_number() catch |err| switch (err) {
400 else => unreachable,395 else => unreachable,
...@@ -408,7 +403,6 @@ fn return_a_number() anyerror!i32 {...@@ -408,7 +403,6 @@ fn return_a_number() anyerror!i32 {
408403
409test "switch on integer with else capturing expr" {404test "switch on integer with else capturing expr" {
410 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
411 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
412406
413 const S = struct {407 const S = struct {
414 fn doTheTest() !void {408 fn doTheTest() !void {
...@@ -498,7 +492,6 @@ test "switch prongs with error set cases make a new error set type for capture v...@@ -498,7 +492,6 @@ test "switch prongs with error set cases make a new error set type for capture v
498492
499test "return result loc and then switch with range implicit casted to error union" {493test "return result loc and then switch with range implicit casted to error union" {
500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO494 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
502495
503 const S = struct {496 const S = struct {
504 fn doTheTest() !void {497 fn doTheTest() !void {
...@@ -539,7 +532,6 @@ test "switch prongs with cases with identical payload types" {...@@ -539,7 +532,6 @@ test "switch prongs with cases with identical payload types" {
539 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO532 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO533 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO534 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
542 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
543535
544 const Union = union(enum) {536 const Union = union(enum) {
545 A: usize,537 A: usize,
...@@ -706,8 +698,6 @@ test "switch item sizeof" {...@@ -706,8 +698,6 @@ test "switch item sizeof" {
706}698}
707699
708test "comptime inline switch" {700test "comptime inline switch" {
709 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
710
711 const U = union(enum) { a: type, b: type };701 const U = union(enum) { a: type, b: type };
712 const value = comptime blk: {702 const value = comptime blk: {
713 var u: U = .{ .a = u32 };703 var u: U = .{ .a = u32 };
...@@ -799,6 +789,8 @@ test "inline switch range that includes the maximum value of the switched type"...@@ -799,6 +789,8 @@ test "inline switch range that includes the maximum value of the switched type"
799}789}
800790
801test "nested break ignores switch conditions and breaks instead" {791test "nested break ignores switch conditions and breaks instead" {
792 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
793
802 const S = struct {794 const S = struct {
803 fn register_to_address(ident: []const u8) !u8 {795 fn register_to_address(ident: []const u8) !u8 {
804 const reg: u8 = if (std.mem.eql(u8, ident, "zero")) 0x00 else blk: {796 const reg: u8 = if (std.mem.eql(u8, ident, "zero")) 0x00 else blk: {
test/behavior/this.zig-1
...@@ -27,7 +27,6 @@ test "this refer to module call private fn" {...@@ -27,7 +27,6 @@ test "this refer to module call private fn" {
27test "this refer to container" {27test "this refer to container" {
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3130
32 var pt: Point(i32) = undefined;31 var pt: Point(i32) = undefined;
33 pt.x = 12;32 pt.x = 12;
test/behavior/translate_c_macros.zig+2
...@@ -233,6 +233,8 @@ test "@typeInfo on @cImport result" {...@@ -233,6 +233,8 @@ test "@typeInfo on @cImport result" {
233}233}
234234
235test "Macro that uses Long type concatenation casting" {235test "Macro that uses Long type concatenation casting" {
236 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
237
236 try expect((@TypeOf(h.X)) == c_long);238 try expect((@TypeOf(h.X)) == c_long);
237 try expectEqual(h.X, @as(c_long, 10));239 try expectEqual(h.X, @as(c_long, 10));
238}240}
test/behavior/try.zig-2
...@@ -24,8 +24,6 @@ fn returnsTen() anyerror!i32 {...@@ -24,8 +24,6 @@ fn returnsTen() anyerror!i32 {
24}24}
2525
26test "try without vars" {26test "try without vars" {
27 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
28
29 const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2);27 const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2);
30 try expect(result1 == 2);28 try expect(result1 == 2);
3129
test/behavior/tuple.zig-3
...@@ -289,7 +289,6 @@ test "coerce tuple to tuple" {...@@ -289,7 +289,6 @@ test "coerce tuple to tuple" {
289 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO289 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
293292
294 const T = std.meta.Tuple(&.{u8});293 const T = std.meta.Tuple(&.{u8});
295 const S = struct {294 const S = struct {
...@@ -304,7 +303,6 @@ test "tuple type with void field" {...@@ -304,7 +303,6 @@ test "tuple type with void field" {
304 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO304 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO305 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
308306
309 const T = std.meta.Tuple(&[_]type{void});307 const T = std.meta.Tuple(&[_]type{void});
310 const x = T{{}};308 const x = T{{}};
...@@ -343,7 +341,6 @@ test "zero sized struct in tuple handled correctly" {...@@ -343,7 +341,6 @@ test "zero sized struct in tuple handled correctly" {
343test "tuple type with void field and a runtime field" {341test "tuple type with void field and a runtime field" {
344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO342 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
345 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO343 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
346 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
347344
348 const T = std.meta.Tuple(&[_]type{ usize, void });345 const T = std.meta.Tuple(&[_]type{ usize, void });
349 var t: T = .{ 5, {} };346 var t: T = .{ 5, {} };
test/behavior/type_info.zig-5
...@@ -160,7 +160,6 @@ test "type info: error set, error union info, anyerror" {...@@ -160,7 +160,6 @@ test "type info: error set, error union info, anyerror" {
160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
164163
165 try testErrorSet();164 try testErrorSet();
166 try comptime testErrorSet();165 try comptime testErrorSet();
...@@ -192,7 +191,6 @@ test "type info: error set single value" {...@@ -192,7 +191,6 @@ test "type info: error set single value" {
192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO192 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO193 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
195 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
196194
197 const TestSet = error.One;195 const TestSet = error.One;
198196
...@@ -206,7 +204,6 @@ test "type info: error set merged" {...@@ -206,7 +204,6 @@ test "type info: error set merged" {
206 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;204 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
207 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
208 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO206 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
209 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
210207
211 const TestSet = error{ One, Two } || error{Three};208 const TestSet = error{ One, Two } || error{Three};
212209
...@@ -222,7 +219,6 @@ test "type info: enum info" {...@@ -222,7 +219,6 @@ test "type info: enum info" {
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;219 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
226222
227 try testEnum();223 try testEnum();
228 try comptime testEnum();224 try comptime testEnum();
...@@ -533,7 +529,6 @@ test "Struct.is_tuple for anon list literal" {...@@ -533,7 +529,6 @@ test "Struct.is_tuple for anon list literal" {
533529
534test "Struct.is_tuple for anon struct literal" {530test "Struct.is_tuple for anon struct literal" {
535 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO531 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
536 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
537532
538 const info = @typeInfo(@TypeOf(.{ .a = 0 }));533 const info = @typeInfo(@TypeOf(.{ .a = 0 }));
539 try expect(!info.Struct.is_tuple);534 try expect(!info.Struct.is_tuple);
test/behavior/type_info_only_pub_decls.zig+3
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const other = struct {3const other = struct {
3 const std = @import("std");4 const std = @import("std");
...@@ -14,6 +15,8 @@ const other = struct {...@@ -14,6 +15,8 @@ const other = struct {
14};15};
1516
16test {17test {
18 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19
17 const ti = @typeInfo(other);20 const ti = @typeInfo(other);
18 const decls = ti.Struct.decls;21 const decls = ti.Struct.decls;
1922
test/behavior/undefined.zig-2
...@@ -48,7 +48,6 @@ test "assign undefined to struct" {...@@ -48,7 +48,6 @@ test "assign undefined to struct" {
48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5251
53 comptime {52 comptime {
54 var foo: Foo = undefined;53 var foo: Foo = undefined;
...@@ -66,7 +65,6 @@ test "assign undefined to struct with method" {...@@ -66,7 +65,6 @@ test "assign undefined to struct with method" {
66 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;65 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
67 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
68 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7068
71 comptime {69 comptime {
72 var foo: Foo = undefined;70 var foo: Foo = undefined;
test/behavior/underscore.zig-1
...@@ -8,7 +8,6 @@ test "ignore lval with underscore" {...@@ -8,7 +8,6 @@ test "ignore lval with underscore" {
88
9test "ignore lval with underscore (while loop)" {9test "ignore lval with underscore (while loop)" {
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 while (optionalReturnError()) |_| {12 while (optionalReturnError()) |_| {
14 while (optionalReturnError()) |_| {13 while (optionalReturnError()) |_| {
test/behavior/union.zig+2-28
...@@ -14,7 +14,6 @@ test "basic unions with floats" {...@@ -14,7 +14,6 @@ test "basic unions with floats" {
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 var foo = FooWithFloats{ .int = 1 };18 var foo = FooWithFloats{ .int = 1 };
20 try expect(foo.int == 1);19 try expect(foo.int == 1);
...@@ -30,7 +29,6 @@ test "init union with runtime value - floats" {...@@ -30,7 +29,6 @@ test "init union with runtime value - floats" {
30 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;29 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
31 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;30 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3432
35 var foo: FooWithFloats = undefined;33 var foo: FooWithFloats = undefined;
3634
...@@ -42,7 +40,6 @@ test "basic unions" {...@@ -42,7 +40,6 @@ test "basic unions" {
42 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;40 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
43 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO41 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
44 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO42 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
4643
47 var foo = Foo{ .int = 1 };44 var foo = Foo{ .int = 1 };
48 try expect(foo.int == 1);45 try expect(foo.int == 1);
...@@ -61,7 +58,6 @@ test "init union with runtime value" {...@@ -61,7 +58,6 @@ test "init union with runtime value" {
61 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
62 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
64 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6561
66 var foo: Foo = undefined;62 var foo: Foo = undefined;
6763
...@@ -172,7 +168,6 @@ test "constant tagged union with payload" {...@@ -172,7 +168,6 @@ test "constant tagged union with payload" {
172 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;168 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
173 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;169 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
174 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
175 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
176171
177 var empty = TaggedUnionWithPayload{ .Empty = {} };172 var empty = TaggedUnionWithPayload{ .Empty = {} };
178 var full = TaggedUnionWithPayload{ .Full = 13 };173 var full = TaggedUnionWithPayload{ .Full = 13 };
...@@ -342,7 +337,6 @@ test "constant packed union" {...@@ -342,7 +337,6 @@ test "constant packed union" {
342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
343 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;338 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
344 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO339 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
345 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
346340
347 try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }});341 try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }});
348}342}
...@@ -453,7 +447,6 @@ test "global union with single field is correctly initialized" {...@@ -453,7 +447,6 @@ test "global union with single field is correctly initialized" {
453 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;447 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
454 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;448 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
455 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO449 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
456 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
457450
458 glbl = Foo1{451 glbl = Foo1{
459 .f = @typeInfo(Foo1).Union.fields[0].type{ .x = 123 },452 .f = @typeInfo(Foo1).Union.fields[0].type{ .x = 123 },
...@@ -500,7 +493,6 @@ test "union initializer generates padding only if needed" {...@@ -500,7 +493,6 @@ test "union initializer generates padding only if needed" {
500 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;493 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
501 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;494 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
502 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO495 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
503 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
504496
505 const U = union(enum) {497 const U = union(enum) {
506 A: u24,498 A: u24,
...@@ -513,7 +505,6 @@ test "union initializer generates padding only if needed" {...@@ -513,7 +505,6 @@ test "union initializer generates padding only if needed" {
513test "runtime tag name with single field" {505test "runtime tag name with single field" {
514 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
516 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
517508
518 const U = union(enum) {509 const U = union(enum) {
519 A: i32,510 A: i32,
...@@ -590,7 +581,6 @@ test "tagged union as return value" {...@@ -590,7 +581,6 @@ test "tagged union as return value" {
590 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
591 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;582 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
592 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO583 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
593 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
594584
595 switch (returnAnInt(13)) {585 switch (returnAnInt(13)) {
596 TaggedFoo.One => |value| try expect(value == 13),586 TaggedFoo.One => |value| try expect(value == 13),
...@@ -635,7 +625,6 @@ test "union(enum(u32)) with specified and unspecified tag values" {...@@ -635,7 +625,6 @@ test "union(enum(u32)) with specified and unspecified tag values" {
635 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;625 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
636 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;626 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
637 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO627 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
638 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
639628
640 try comptime expect(Tag(Tag(MultipleChoice2)) == u32);629 try comptime expect(Tag(Tag(MultipleChoice2)) == u32);
641 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });630 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
...@@ -673,7 +662,6 @@ test "switch on union with only 1 field" {...@@ -673,7 +662,6 @@ test "switch on union with only 1 field" {
673 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO662 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
674 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO663 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
675 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO664 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
676 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
677665
678 var r: PartialInst = undefined;666 var r: PartialInst = undefined;
679 r = PartialInst.Compiled;667 r = PartialInst.Compiled;
...@@ -702,7 +690,6 @@ const PartialInstWithPayload = union(enum) {...@@ -702,7 +690,6 @@ const PartialInstWithPayload = union(enum) {
702690
703test "union with only 1 field casted to its enum type which has enum value specified" {691test "union with only 1 field casted to its enum type which has enum value specified" {
704 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO692 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
705 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
706693
707 const Literal = union(enum) {694 const Literal = union(enum) {
708 Number: f64,695 Number: f64,
...@@ -787,7 +774,6 @@ test "return union init with void payload" {...@@ -787,7 +774,6 @@ test "return union init with void payload" {
787 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;774 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
788 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;775 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
789 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO776 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
790 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
791777
792 const S = struct {778 const S = struct {
793 fn entry() !void {779 fn entry() !void {
...@@ -841,7 +827,6 @@ test "@unionInit can modify a union type" {...@@ -841,7 +827,6 @@ test "@unionInit can modify a union type" {
841 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO827 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
842 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO828 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
843 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO829 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
844 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
845830
846 const UnionInitEnum = union(enum) {831 const UnionInitEnum = union(enum) {
847 Boolean: bool,832 Boolean: bool,
...@@ -865,7 +850,6 @@ test "@unionInit can modify a pointer value" {...@@ -865,7 +850,6 @@ test "@unionInit can modify a pointer value" {
865 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO850 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
866 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO851 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
867 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO852 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
868 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
869853
870 const UnionInitEnum = union(enum) {854 const UnionInitEnum = union(enum) {
871 Boolean: bool,855 Boolean: bool,
...@@ -922,7 +906,6 @@ test "anonymous union literal syntax" {...@@ -922,7 +906,6 @@ test "anonymous union literal syntax" {
922 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO906 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
923 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO907 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
924 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO908 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
925 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
926909
927 const S = struct {910 const S = struct {
928 const Number = union {911 const Number = union {
...@@ -1014,7 +997,6 @@ test "cast from pointer to anonymous struct to pointer to union" {...@@ -1014,7 +997,6 @@ test "cast from pointer to anonymous struct to pointer to union" {
1014 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO997 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO998 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1016 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO999 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1017 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10181000
1019 const S = struct {1001 const S = struct {
1020 const U = union(enum) {1002 const U = union(enum) {
...@@ -1046,7 +1028,6 @@ test "switching on non exhaustive union" {...@@ -1046,7 +1028,6 @@ test "switching on non exhaustive union" {
1046 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1028 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1047 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1029 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1048 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1030 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1049 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10501031
1051 const S = struct {1032 const S = struct {
1052 const E = enum(u8) {1033 const E = enum(u8) {
...@@ -1179,7 +1160,6 @@ test "union with no result loc initiated with a runtime value" {...@@ -1179,7 +1160,6 @@ test "union with no result loc initiated with a runtime value" {
1179 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1180 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1161 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1182 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11831163
1184 const U = union {1164 const U = union {
1185 a: u32,1165 a: u32,
...@@ -1196,7 +1176,6 @@ test "union with a large struct field" {...@@ -1196,7 +1176,6 @@ test "union with a large struct field" {
1196 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1176 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1197 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1177 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1198 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1178 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1199 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12001179
1201 const S = struct {1180 const S = struct {
1202 a: [8]usize,1181 a: [8]usize,
...@@ -1230,7 +1209,6 @@ test "union tag is set when initiated as a temporary value at runtime" {...@@ -1230,7 +1209,6 @@ test "union tag is set when initiated as a temporary value at runtime" {
1230 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1209 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1231 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1211 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1233 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12341212
1235 const U = union(enum) {1213 const U = union(enum) {
1236 a,1214 a,
...@@ -1268,7 +1246,6 @@ test "return an extern union from C calling convention" {...@@ -1268,7 +1246,6 @@ test "return an extern union from C calling convention" {
1268 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1246 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1271 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12721249
1273 const namespace = struct {1250 const namespace = struct {
1274 const S = extern struct {1251 const S = extern struct {
...@@ -1299,7 +1276,6 @@ test "noreturn field in union" {...@@ -1299,7 +1276,6 @@ test "noreturn field in union" {
1299 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1276 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1300 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1277 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1301 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1278 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1302 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13031279
1304 const U = union(enum) {1280 const U = union(enum) {
1305 a: u32,1281 a: u32,
...@@ -1351,7 +1327,6 @@ test "@unionInit uses tag value instead of field index" {...@@ -1351,7 +1327,6 @@ test "@unionInit uses tag value instead of field index" {
1351 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1327 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1352 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1353 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1329 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1354 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13551330
1356 const E = enum(u8) {1331 const E = enum(u8) {
1357 b = 255,1332 b = 255,
...@@ -1480,7 +1455,6 @@ test "no dependency loop when function pointer in union returns the union" {...@@ -1480,7 +1455,6 @@ test "no dependency loop when function pointer in union returns the union" {
1480test "union reassignment can use previous value" {1455test "union reassignment can use previous value" {
1481 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1482 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1457 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1483 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14841458
1485 const U = union {1459 const U = union {
1486 a: u32,1460 a: u32,
...@@ -1532,7 +1506,6 @@ test "reinterpreting enum value inside packed union" {...@@ -1532,7 +1506,6 @@ test "reinterpreting enum value inside packed union" {
15321506
1533test "access the tag of a global tagged union" {1507test "access the tag of a global tagged union" {
1534 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1508 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1535 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15361509
1537 const U = union(enum) {1510 const U = union(enum) {
1538 a,1511 a,
...@@ -1544,7 +1517,6 @@ test "access the tag of a global tagged union" {...@@ -1544,7 +1517,6 @@ test "access the tag of a global tagged union" {
15441517
1545test "coerce enum literal to union in result loc" {1518test "coerce enum literal to union in result loc" {
1546 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1519 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1547 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15481520
1549 const U = union(enum) {1521 const U = union(enum) {
1550 a,1522 a,
...@@ -1669,6 +1641,8 @@ test "packed union field pointer has correct alignment" {...@@ -1669,6 +1641,8 @@ test "packed union field pointer has correct alignment" {
1669}1641}
16701642
1671test "union with 128 bit integer" {1643test "union with 128 bit integer" {
1644 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1645
1672 const ValueTag = enum { int, other };1646 const ValueTag = enum { int, other };
16731647
1674 const Value3 = union(ValueTag) {1648 const Value3 = union(ValueTag) {
test/behavior/var_args.zig+9
...@@ -14,6 +14,8 @@ fn add(args: anytype) i32 {...@@ -14,6 +14,8 @@ 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
17 try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);19 try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
18 try expect(add(.{@as(i32, 1234)}) == 1234);20 try expect(add(.{@as(i32, 1234)}) == 1234);
19 try expect(add(.{}) == 0);21 try expect(add(.{}) == 0);
...@@ -24,12 +26,15 @@ fn readFirstVarArg(args: anytype) void {...@@ -24,12 +26,15 @@ fn readFirstVarArg(args: anytype) void {
24}26}
2527
26test "send void arg to var args" {28test "send void arg to var args" {
29 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
30
27 readFirstVarArg(.{{}});31 readFirstVarArg(.{{}});
28}32}
2933
30test "pass args directly" {34test "pass args directly" {
31 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO35 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
32 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;
3338
34 try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);39 try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
35 try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);40 try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
...@@ -82,11 +87,15 @@ fn foo2(args: anytype) bool {...@@ -82,11 +87,15 @@ fn foo2(args: anytype) bool {
82}87}
8388
84test "array of var args functions" {89test "array of var args functions" {
90 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
91
85 try expect(foos[0](.{}));92 try expect(foos[0](.{}));
86 try expect(!foos[1](.{}));93 try expect(!foos[1](.{}));
87}94}
8895
89test "pass zero length array to var args param" {96test "pass zero length array to var args param" {
97 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
98
90 doNothingWithFirstArg(.{""});99 doNothingWithFirstArg(.{""});
91}100}
92101
test/behavior/vector.zig-2
...@@ -240,7 +240,6 @@ test "peer type resolution with coercible element types" {...@@ -240,7 +240,6 @@ test "peer type resolution with coercible element types" {
240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
243 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
244243
245 const S = struct {244 const S = struct {
246 fn doTheTest() !void {245 fn doTheTest() !void {
...@@ -1469,7 +1468,6 @@ test "boolean vector with 2 or more booleans" {...@@ -1469,7 +1468,6 @@ test "boolean vector with 2 or more booleans" {
1469 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1468 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1470 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1469 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1471 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1470 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1472 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
14731471
1474 // TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>:1472 // TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>:
1475 if (!(builtin.os.tag == .linux and builtin.cpu.arch == .x86_64)) return;1473 if (!(builtin.os.tag == .linux and builtin.cpu.arch == .x86_64)) return;
test/behavior/while.zig-15
...@@ -50,8 +50,6 @@ test "while with continue expression" {...@@ -50,8 +50,6 @@ test "while with continue expression" {
50}50}
5151
52test "while with else" {52test "while with else" {
53 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
54
55 var sum: i32 = 0;53 var sum: i32 = 0;
56 var i: i32 = 0;54 var i: i32 = 0;
57 var got_else: i32 = 0;55 var got_else: i32 = 0;
...@@ -79,8 +77,6 @@ fn getNumberOrNull() ?i32 {...@@ -79,8 +77,6 @@ fn getNumberOrNull() ?i32 {
79}77}
8078
81test "continue outer while loop" {79test "continue outer while loop" {
82 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
83
84 testContinueOuter();80 testContinueOuter();
85 comptime testContinueOuter();81 comptime testContinueOuter();
86}82}
...@@ -127,7 +123,6 @@ test "while copies its payload" {...@@ -127,7 +123,6 @@ test "while copies its payload" {
127123
128test "continue and break" {124test "continue and break" {
129 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;125 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
130 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
131126
132 try runContinueAndBreakTest();127 try runContinueAndBreakTest();
133 try expect(continue_and_break_counter == 8);128 try expect(continue_and_break_counter == 8);
...@@ -149,7 +144,6 @@ fn runContinueAndBreakTest() !void {...@@ -149,7 +144,6 @@ fn runContinueAndBreakTest() !void {
149test "while with optional as condition" {144test "while with optional as condition" {
150 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
151 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO146 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
152 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
153147
154 numbers_left = 10;148 numbers_left = 10;
155 var sum: i32 = 0;149 var sum: i32 = 0;
...@@ -162,7 +156,6 @@ test "while with optional as condition" {...@@ -162,7 +156,6 @@ test "while with optional as condition" {
162test "while with optional as condition with else" {156test "while with optional as condition with else" {
163 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
164 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO158 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
166159
167 numbers_left = 10;160 numbers_left = 10;
168 var sum: i32 = 0;161 var sum: i32 = 0;
...@@ -223,7 +216,6 @@ test "while on optional with else result follow break prong" {...@@ -223,7 +216,6 @@ test "while on optional with else result follow break prong" {
223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;217 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
225 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
226 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
227219
228 const result = while (returnOptional(10)) |value| {220 const result = while (returnOptional(10)) |value| {
229 break value;221 break value;
...@@ -251,8 +243,6 @@ fn returnTrue() bool {...@@ -251,8 +243,6 @@ fn returnTrue() bool {
251}243}
252244
253test "return with implicit cast from while loop" {245test "return with implicit cast from while loop" {
254 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
255
256 returnWithImplicitCastFromWhileLoopTest() catch unreachable;246 returnWithImplicitCastFromWhileLoopTest() catch unreachable;
257}247}
258fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {248fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {
...@@ -263,7 +253,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {...@@ -263,7 +253,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {
263253
264test "while on error union with else result follow else prong" {254test "while on error union with else result follow else prong" {
265 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
266 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
267256
268 const result = while (returnError()) |value| {257 const result = while (returnError()) |value| {
269 break value;258 break value;
...@@ -273,7 +262,6 @@ test "while on error union with else result follow else prong" {...@@ -273,7 +262,6 @@ test "while on error union with else result follow else prong" {
273262
274test "while on error union with else result follow break prong" {263test "while on error union with else result follow break prong" {
275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO264 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
276 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
277265
278 const result = while (returnSuccess(10)) |value| {266 const result = while (returnSuccess(10)) |value| {
279 break value;267 break value;
...@@ -319,7 +307,6 @@ test "while error 2 break statements and an else" {...@@ -319,7 +307,6 @@ test "while error 2 break statements and an else" {
319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO307 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO308 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO309 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
322 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
323310
324 const S = struct {311 const S = struct {
325 fn entry(opt_t: anyerror!bool, f: bool) !void {312 fn entry(opt_t: anyerror!bool, f: bool) !void {
...@@ -345,8 +332,6 @@ test "continue inline while loop" {...@@ -345,8 +332,6 @@ test "continue inline while loop" {
345}332}
346333
347test "else continue outer while" {334test "else continue outer while" {
348 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
349
350 var i: usize = 0;335 var i: usize = 0;
351 while (true) {336 while (true) {
352 i += 1;337 i += 1;