| author | |
| committer | |
| log | b00287175c044682ea025805de05a6ac26a42771 |
| tree | 1c6ef32977a615238c231c79c020c16a8b98da5d |
| parent | 865b2e259bf78dbf1d4c1051b5fff68b90bca65f |
| parent | cff8ab88f5ffe24771aa9c6e839eef03bc22f3d2 |
| signature |
spirv gaming71 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; |
| 12 | const Air = @import("../Air.zig"); | 12 | const Air = @import("../Air.zig"); |
| 13 | const Zir = @import("../Zir.zig"); | 13 | const Zir = @import("../Zir.zig"); |
| 14 | const Liveness = @import("../Liveness.zig"); | 14 | const Liveness = @import("../Liveness.zig"); |
| 15 | const InternPool = @import("../InternPool.zig"); | ||
| 15 | 16 | ||
| 16 | const spec = @import("spirv/spec.zig"); | 17 | const spec = @import("spirv/spec.zig"); |
| 17 | const Opcode = spec.Opcode; | 18 | const Opcode = spec.Opcode; |
| ... | @@ -30,15 +31,26 @@ const SpvAssembler = @import("spirv/Assembler.zig"); | ... | @@ -30,15 +31,26 @@ const SpvAssembler = @import("spirv/Assembler.zig"); |
| 30 | 31 | ||
| 31 | const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef); | 32 | const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef); |
| 32 | 33 | ||
| 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. | ||
| 37 | const SpvTypeInfo = struct { | ||
| 38 | ty_ref: CacheRef, | ||
| 39 | }; | ||
| 40 | |||
| 41 | const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, SpvTypeInfo); | ||
| 42 | |||
| 33 | const IncomingBlock = struct { | 43 | const IncomingBlock = struct { |
| 34 | src_label_id: IdRef, | 44 | src_label_id: IdRef, |
| 35 | break_value_id: IdRef, | 45 | break_value_id: IdRef, |
| 36 | }; | 46 | }; |
| 37 | 47 | ||
| 38 | const BlockMap = std.AutoHashMapUnmanaged(Air.Inst.Index, struct { | 48 | const 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 | |||
| 53 | const BlockMap = std.AutoHashMapUnmanaged(Air.Inst.Index, *Block); | ||
| 42 | 54 | ||
| 43 | /// Maps Zig decl indices to linking SPIR-V linking information. | 55 | /// Maps Zig decl indices to linking SPIR-V linking information. |
| 44 | pub const DeclLinkMap = std.AutoHashMap(Module.Decl.Index, SpvModule.Decl.Index); | 56 | pub 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 = .{}, |
| 80 | 92 | ||
| 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 = .{}, |
| 90 | 111 | ||
| 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; |
| 190 | 216 | ||
| 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 | } |
| 213 | 241 | ||
| 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 | } |
| 399 | 427 | ||
| 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/1349 | 454 | // 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 can | 456 | // 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 well | 458 | 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 | }); | ||
| 411 | 464 | ||
| 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; |
| 414 | 467 | ||
| 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 | } |
| 432 | 484 | ||
| 433 | const IndirectConstantLowering = struct { | 485 | /// Construct a struct at runtime. |
| 434 | const undef = 0xAA; | 486 | /// result_ty_ref must be an array type. |
| 435 | 487 | /// 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 type | 491 | // 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. Includes | 495 | // 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 | } | ||
| 556 | 503 | ||
| 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); | ||
| 561 | 507 | ||
| 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 | } | ||
| 579 | 523 | ||
| 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); |
| 583 | 527 | 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); |
| 586 | 530 | 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 |
| 589 | 533 | // 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 and | 536 | }, |
| 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 dependency | 540 | 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(); | ||
| 602 | 541 | ||
| 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 | }; | ||
| 604 | 560 | ||
| 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 casts | 563 | 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 | }); |
| 613 | 569 | 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 | } |
| 1002 | 576 | ||
| 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. When | 578 | /// 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, which | 579 | /// 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; | ||
| 1012 | 588 | ||
| 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 | } |
| 1018 | 594 | ||
| 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 | } |
| 1023 | 599 | ||
| 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 values | 617 | => unreachable, // types, not values |
| 1042 | 618 | ||
| 1043 | .undef => unreachable, // handled above | 619 | .undef, .runtime_value => unreachable, // handled above |
| 1044 | .runtime_value => unreachable, // ??? | ||
| 1045 | 620 | ||
| 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 values | 635 | => unreachable, // non-runtime values |
| 1061 | 636 | ||
| 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 | }, |
| 1067 | 639 | ||
| 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 extra | 658 | .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) { |
| 1094 | 666 | .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); | ||
| 1105 | 793 | ||
| 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 dead | 832 | 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 | } |
| 1117 | 847 | ||
| 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 | } |
| 1140 | 880 | ||
| 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).?; |
| 1173 | 912 | ||
| 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 | } |
| 1177 | 916 | ||
| 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 | } |
| 1182 | 923 | ||
| 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; | ||
| 1185 | 931 | ||
| 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? |
| 1189 | 933 | ||
| 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 | } |
| 1195 | 939 | ||
| 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); |
| 1198 | 942 | 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 | } |
| 1212 | 945 | ||
| 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 | } |
| 1218 | 951 | ||
| 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 | } |
| 1224 | 957 | ||
| 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 | } |
| 1230 | 969 | ||
| 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.zig | 1026 | // 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); |
| 1290 | 1036 | ||
| 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 | } |
| 1352 | 1103 | ||
| 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 | } |
| 1378 | 1133 | ||
| 1379 | const name = ip.stringToSlice(try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod)); | 1134 | const ty_ref = try self.spv.resolve(.{ .struct_type = .{ |
| 1380 | 1135 | .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 | } |
| 1401 | 1157 | ||
| 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); |
| 1403 | 1161 | ||
| 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 | } |
| 1422 | 1183 | ||
| 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); |
| 1424 | 1187 | ||
| 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 | } |
| 1444 | 1207 | ||
| 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 | }, |
| 1450 | 1217 | ||
| 1451 | .Null, | 1218 | .Null, |
| ... | @@ -1509,6 +1276,85 @@ pub const DeclGen = struct { | ... | @@ -1509,6 +1276,85 @@ pub const DeclGen = struct { |
| 1509 | }; | 1276 | }; |
| 1510 | } | 1277 | } |
| 1511 | 1278 | ||
| 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 { |
| 1588 | 1434 | ||
| 1589 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; | 1435 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; |
| 1590 | 1436 | ||
| 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); |
| 1631 | 1479 | ||
| 1632 | const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module)); | 1480 | const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module)); |
| 1633 | 1481 | 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 | }); | ||
| 1638 | 1482 | ||
| 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 | } |
| 1652 | 1496 | ||
| 1653 | // TODO: integrate with variable(). | 1497 | // Currently, initializers for CrossWorkgroup variables is not implemented |
| 1498 | // in Mesa. Therefore we generate an initialization kernel instead. | ||
| 1654 | 1499 | ||
| 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 | }; |
| 1660 | 1513 | ||
| 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 | } |
| 1671 | 1556 | ||
| 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 | } |
| 1734 | 1619 | ||
| 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 | } |
| 1751 | 1634 | ||
| 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), |
| 1797 | 1678 | ||
| 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), | ||
| 1799 | 1681 | ||
| 1800 | .shuffle => try self.airShuffle(inst), | 1682 | .shuffle => try self.airShuffle(inst), |
| 1801 | 1683 | ||
| ... | @@ -1812,19 +1694,27 @@ pub const DeclGen = struct { | ... | @@ -1812,19 +1694,27 @@ pub const DeclGen = struct { |
| 1812 | 1694 | ||
| 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), |
| 1819 | 1701 | ||
| 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), | ||
| 1826 | 1713 | ||
| 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), |
| 1829 | 1719 | ||
| 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(), |
| 1861 | 1750 | ||
| 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), | ||
| 1864 | 1762 | ||
| 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), | ||
| 1867 | 1767 | ||
| 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: on | 1777 | // zig fmt: on |
| 1885 | 1778 | ||
| 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 | } |
| 2014 | 1907 | ||
| 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; |
| 2017 | 1916 | ||
| 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 { |
| 2044 | 1943 | ||
| 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 > lhs | 1969 | // - rhs is negative and value > lhs |
| 2069 | // - rhs is positive and value < lhs | 1970 | // - 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) | ||
| 2074 | 1983 | ||
| 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 | }); |
| 2083 | 1992 | ||
| 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 | }); |
| 2091 | 2000 | ||
| 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 | } |
| 2148 | 2057 | ||
| 2149 | /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective | 2058 | fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef { |
| 2150 | /// difference lies in whether the resulting type of the first dereference will be the | 2059 | const index_ty_ref = try self.intType(.unsigned, 32); |
| 2151 | /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain | 2060 | 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 | } |
| 2168 | 2084 | ||
| 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 array | 2127 | // 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 | } |
| 2503 | 2455 | ||
| 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 { |
| 2539 | 2567 | ||
| 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 | } |
| 2544 | 2572 | ||
| 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 type | 2580 | // 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 ptrAccessChain | 2584 | // 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 | } |
| 2576 | 2604 | ||
| 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); | ||
| 2585 | 2658 | ||
| 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 }); | ||
| 2592 | 2660 | ||
| 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 | } |
| 2595 | 2675 | ||
| 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); |
| 2599 | 2681 | ||
| 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; |
| 2603 | 2685 | ||
| 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; |
| 2606 | 2688 | ||
| 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 | } |
| 2611 | 2799 | ||
| 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; |
| 2618 | 2806 | ||
| 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); |
| 2623 | 2811 | ||
| 2624 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; | 2812 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; |
| 2625 | 2813 | ||
| 2626 | assert(struct_ty.zigTypeTag(mod) == .Struct); // Cannot do unions yet. | 2814 | switch (object_ty.zigTypeTag(mod)) { |
| 2627 | 2815 | .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 | } |
| 2630 | 2851 | ||
| 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, // TODO | 2865 | .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, // TODO | 2870 | .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 | } |
| 2653 | 2890 | ||
| ... | @@ -2726,50 +2963,50 @@ pub const DeclGen = struct { | ... | @@ -2726,50 +2963,50 @@ pub const DeclGen = struct { |
| 2726 | } | 2963 | } |
| 2727 | 2964 | ||
| 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 and | 2966 | // 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 up | 2967 | // 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 current | 2968 | // 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. |
| 2733 | 2972 | ||
| 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)); | ||
| 2753 | 2990 | ||
| 2754 | try self.genBody(body); | 2991 | try self.genBody(body); |
| 2755 | try self.beginSpvBlock(label_id); | ||
| 2756 | 2992 | ||
| 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; |
| 2760 | 3000 | ||
| 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); |
| 2767 | 3004 | ||
| 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); |
| 2771 | 3008 | ||
| 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 | } |
| 2775 | 3012 | ||
| ... | @@ -2778,17 +3015,24 @@ pub const DeclGen = struct { | ... | @@ -2778,17 +3015,24 @@ pub const DeclGen = struct { |
| 2778 | 3015 | ||
| 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).?; | ||
| 2783 | 3020 | ||
| 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 | } |
| 2790 | 3030 | ||
| 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 | } |
| 2793 | 3037 | ||
| 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 | } |
| 2819 | 3063 | ||
| 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; |
| 2839 | 3071 | ||
| 2840 | return try self.load(ptr_ty, operand); | 3072 | return try self.load(elem_ty, operand, ptr_ty.isVolatilePtr(mod)); |
| 2841 | } | 3073 | } |
| 2842 | 3074 | ||
| 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); | ||
| 2850 | 3081 | ||
| 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 | } |
| 2859 | 3084 | ||
| 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 | } |
| 2898 | 3124 | ||
| 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 | else | 3150 | else |
| 2925 | err_union_id; | 3151 | err_union_id; |
| 2926 | 3152 | ||
| 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 | } |
| 2990 | 3216 | ||
| 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; |
| 2993 | 3234 | ||
| ... | @@ -3003,20 +3244,35 @@ pub const DeclGen = struct { | ... | @@ -3003,20 +3244,35 @@ pub const DeclGen = struct { |
| 3003 | } | 3244 | } |
| 3004 | 3245 | ||
| 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 | } |
| 3017 | 3269 | ||
| 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 | } |
| 3021 | 3277 | ||
| 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 | } |
| 3083 | 3339 | ||
| 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; |
| 3086 | 3378 | ||
| ... | @@ -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 | } |
| 3240 | 3532 | ||
| 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 | }; |
| 98 | 100 | ||
| 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]; |
| 286 | 288 | ||
| 289 | if (seen.isSet(@intFromEnum(decl_index))) { | ||
| 290 | return; | ||
| 291 | } | ||
| 292 | |||
| 287 | seen.set(@intFromEnum(decl_index)); | 293 | seen.set(@intFromEnum(decl_index)); |
| 288 | 294 | ||
| 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 | } |
| 292 | 298 | ||
| 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 | } |
| 299 | 303 | ||
| ... | @@ -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 | } |
| 327 | 331 | ||
| 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 | ||
| 340 | fn 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. |
| 329 | pub fn flush(self: *Module, file: std.fs.File) !void { | 399 | pub 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" |
| 331 | 401 | ||
| 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); |
| 351 | 411 | ||
| 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 | }; |
| 367 | 441 | ||
| 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 | } |
| 529 | 604 | ||
| ... | @@ -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 | } |
| 555 | 630 | ||
| 556 | pub fn endGlobal(self: *Module, global_index: Decl.Index, begin_inst: u32) void { | 631 | pub 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 | } |
| 561 | 640 | ||
| 562 | pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8) !void { | 641 | pub 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 | } |
| 568 | 647 | ||
| 569 | pub fn debugName(self: *Module, target: IdResult, comptime fmt: []const u8, args: anytype) !void { | 648 | pub 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 | } |
| 577 | 654 | ||
| 578 | pub fn memberDebugName(self: *Module, target: IdResult, member: u32, comptime fmt: []const u8, args: anytype) !void { | 655 | pub 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 | |||
| 661 | pub 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 | } |
| 111 | 111 | ||
| 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)}); | ||
| 113 | 115 | ||
| 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 | } |
| 126 | 128 | ||
| 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(); |
| 129 | 134 | ||
| ... | @@ -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 |
| 212 | fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { | 217 | fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { |
| 213 | // TODO: Integrate with a hypothetical feature system | 218 | // 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, // TODO | 223 | 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; // TODO | 23 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 25 | 24 | ||
| 26 | var array: [5]u32 = undefined; | 25 | var array: [5]u32 = undefined; |
| 27 | 26 | ||
| ... | @@ -49,7 +48,6 @@ fn getArrayLen(a: []const u32) usize { | ... | @@ -49,7 +48,6 @@ fn getArrayLen(a: []const u32) usize { |
| 49 | test "array concat with undefined" { | 48 | test "array concat with undefined" { |
| 50 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 52 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 53 | 51 | ||
| 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" { |
| 89 | 87 | ||
| 90 | test "array init with concat" { | 88 | test "array init with concat" { |
| 91 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 89 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 92 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 93 | 90 | ||
| 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" { |
| 99 | test "array init with mult" { | 96 | test "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; // TODO | 98 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 102 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 103 | 99 | ||
| 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; // TODO | 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 144 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 145 | 140 | ||
| 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" { |
| 163 | test "array with sentinels" { | 158 | test "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; // TODO | 160 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 166 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 167 | 161 | ||
| 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; // TODO | 197 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 204 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 205 | 198 | ||
| 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" { |
| 231 | test "implicit comptime in array type size" { | 224 | test "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; // TODO | 226 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 234 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 235 | 227 | ||
| 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 { |
| 244 | test "single-item pointer to array indexing and slicing" { | 236 | test "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; // TODO | 238 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 247 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 248 | 239 | ||
| 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; // TODO | 281 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 291 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 292 | 282 | ||
| 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; // TODO | 317 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 328 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 318 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 329 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 330 | 319 | ||
| 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 { |
| 366 | test "comptime evaluating function that takes array by value" { | 355 | test "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; // TODO | 357 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 369 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 370 | 358 | ||
| 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" { |
| 378 | test "runtime initialize array elem and then implicit cast to slice" { | 366 | test "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; // TODO | 368 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 381 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 382 | 369 | ||
| 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" { |
| 388 | test "array literal as argument to function" { | 375 | test "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; // TODO | 377 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 391 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 392 | 378 | ||
| 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; // TODO | 404 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 419 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 420 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 421 | 406 | ||
| 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; // TODO | 465 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 481 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 466 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 482 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 483 | 467 | ||
| 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" { |
| 504 | test "access the null element of a null terminated array" { | 488 | test "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; // TODO | 490 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 507 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 508 | 491 | ||
| 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; // TODO | 506 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 524 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 507 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 525 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 526 | 508 | ||
| 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; // TODO | 602 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 621 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 603 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 622 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 604 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 623 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 624 | 605 | ||
| 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; // TODO | 640 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 660 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 641 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 661 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 642 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 662 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 663 | 643 | ||
| 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; // TODO | 683 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 704 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 684 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 705 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 685 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 706 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 707 | 686 | ||
| 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 | } |
| 778 | 757 | ||
| 779 | test "runtime side-effects in comptime-known array init" { | 758 | test "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 { |
| 330 | 330 | ||
| 331 | test "const ptr from var variable" { | 331 | test "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; | ||
| 334 | 333 | ||
| 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 | } |
| 582 | 581 | ||
| 583 | test "equality compare fn ptrs" { | 582 | test "equality compare fn ptrs" { |
| 584 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // Test passes but should not | 583 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 585 | 584 | ||
| 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" { |
| 607 | 606 | ||
| 608 | test "global variable initialized to global variable array element" { | 607 | test "global variable initialized to global variable array element" { |
| 609 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 608 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 610 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 611 | 609 | ||
| 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" { |
| 639 | 637 | ||
| 640 | test "multiline string literal is null terminated" { | 638 | test "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; | ||
| 643 | 640 | ||
| 644 | const s1 = | 641 | const s1 = |
| 645 | \\one | 642 | \\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; // TODO | 710 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 714 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 715 | 711 | ||
| 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 { |
| 1027 | 1023 | ||
| 1028 | test "switch inside @as gets correct type" { | 1024 | test "switch inside @as gets correct type" { |
| 1029 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1025 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1030 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1031 | 1026 | ||
| 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 | } |
| 1137 | 1132 | ||
| 1138 | test "runtime-known globals initialized with undefined" { | 1133 | test "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 | } |
| 272 | 272 | ||
| 273 | test "bitcast passed as tuple element" { | 273 | test "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 | } |
| 282 | 284 | ||
| 283 | test "triple level result location with bitcast sandwich passed as tuple element" { | 285 | test "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; | ||
| 9 | 8 | ||
| 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; // TODO | 9 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 11 | 10 | ||
| 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 | } |
| 10 | 10 | ||
| 11 | test "bug" { | 11 | test "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"); |
| 2 | 2 | ||
| 3 | test "bytes" { | 3 | test "bytes" { |
| 4 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 4 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 5 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 6 | 5 | ||
| 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" { |
| 24 | 23 | ||
| 25 | test "aggregate" { | 24 | test "aggregate" { |
| 26 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 25 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 27 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 28 | 26 | ||
| 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"); |
| 4 | test { | 4 | test { |
| 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 6 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 8 | 7 | ||
| 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 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | test { | 3 | test { |
| 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"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | test { | 4 | test { |
| 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); |
| 9 | 7 |
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 | } |
| 9 | test { | 9 | test { |
| 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; // TODO | 9 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 13 | 12 | ||
| 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 | } |
| 9 | test "nan" { | 9 | test "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 | } |
| 16 | test "inf" { | 14 | test "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 | } |
| 23 | test "-inf < 0" { | 19 | test "-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 | } |
| 30 | test "inf >= 1" { | 24 | test "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 | }; |
| 12 | 12 | ||
| 13 | test { | 13 | test { |
| 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 | }; |
| 28 | test { | 26 | test { |
| 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); |
| 14 | test "simple test" { | 14 | test "simple test" { |
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 18 | 17 | ||
| 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; // TODO | 10 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 13 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 14 | 13 | ||
| 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 { |
| 11 | 11 | ||
| 12 | test { | 12 | test { |
| 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 15 | 14 | ||
| 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 { |
| 6 | 6 | ||
| 7 | test { | 7 | test { |
| 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 10 | 9 | ||
| 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; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | test { | 4 | test { |
| 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 | } |
| 9 | 7 |
test/behavior/bugs/1500.zig-2| ... | @@ -6,8 +6,6 @@ const A = struct { | ... | @@ -6,8 +6,6 @@ const A = struct { |
| 6 | const B = *const fn (A) void; | 6 | const B = *const fn (A) void; |
| 7 | 7 | ||
| 8 | test "allow these dependencies" { | 8 | test "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; // TODO | 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 8 | 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; // TODO | 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 19 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 18 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 20 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 19 | 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; // TODO | 7 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 11 | 10 | ||
| 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; |
| 8 | test "@tagName() returns a string literal" { | 8 | test "@tagName() returns a string literal" { |
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 12 | 11 | ||
| 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; |
| 22 | test "@errorName() returns a string literal" { | 21 | test "@errorName() returns a string literal" { |
| 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 22 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 25 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 26 | 24 | ||
| 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; // TODO | 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 12 | 11 | ||
| 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; // TODO | 24 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 25 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 26 | 25 | ||
| 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; // TODO | 15 | 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 = |
| 13 | test "issue 6456" { | 13 | test "issue 6456" { |
| 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 17 | 16 | ||
| 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; // TODO | 16 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 18 | 17 | ||
| 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 | } |
| 16 | 16 | ||
| 17 | test "compiler doesn't consider equal unions with different 'type' payload" { | 17 | test "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); |
| 22 | 20 |
test/behavior/bugs/7187.zig-2| ... | @@ -3,8 +3,6 @@ const builtin = @import("builtin"); | ... | @@ -3,8 +3,6 @@ const builtin = @import("builtin"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | test "miscompilation with bool return type" { | 5 | test "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"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | test "@sizeOf reified union zero-size payload fields" { | 4 | test "@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 { |
| 31 | 31 | ||
| 32 | test "comptime struct return should not return the same instance" { | 32 | test "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; | ||
| 35 | 34 | ||
| 36 | //the first parameter must be passed by reference to trigger the bug | 35 | //the first parameter must be passed by reference to trigger the bug |
| 37 | //a second parameter is required to trigger the bug | 36 | //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"; |
| 5 | 5 | ||
| 6 | test "pass string literal byvalue to a generic var param" { | 6 | test "pass string literal byvalue to a generic var param" { |
| 7 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 9 | 8 | ||
| 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" { |
| 334 | test "inline call doesn't re-evaluate non generic struct" { | 334 | test "inline call doesn't re-evaluate non generic struct" { |
| 335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 336 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 336 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 337 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 338 | 337 | ||
| 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; | ||
| 49 | 50 | ||
| 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" { |
| 403 | test "expected [*c]const u8, found [*:0]const u8" { | 403 | test "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; // TODO | 405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 406 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 407 | 406 | ||
| 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; // TODO | 446 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 448 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 449 | 447 | ||
| 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 { |
| 521 | test "implicit cast from *const [N]T to []const T" { | 519 | test "implicit cast from *const [N]T to []const T" { |
| 522 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 520 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 523 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 521 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 524 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 525 | 522 | ||
| 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 { |
| 547 | test "peer type resolution: error and [N]T" { | 544 | test "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; // TODO | 546 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 550 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 551 | 547 | ||
| 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; // TODO | 705 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 710 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 706 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 711 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 707 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 712 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 713 | 708 | ||
| 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; // TODO | 734 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 740 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 735 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 741 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 736 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 742 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 743 | 737 | ||
| 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; // TODO | 763 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 770 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 764 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 771 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 765 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 772 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 773 | 766 | ||
| 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; // TODO | 796 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 804 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 797 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 805 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 798 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 806 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 807 | 799 | ||
| 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" { |
| 863 | 855 | ||
| 864 | test "peer cast *[N]T to [*]T" { | 856 | test "peer cast *[N]T to [*]T" { |
| 865 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 857 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 866 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 867 | 858 | ||
| 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" { |
| 930 | test "peer cast *[N:x]T to *[N]T" { | 921 | test "peer cast *[N:x]T to *[N]T" { |
| 931 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 922 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 932 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 923 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 933 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 934 | 924 | ||
| 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" { |
| 946 | test "peer cast [*:x]T to [*]T" { | 936 | test "peer cast [*:x]T to [*]T" { |
| 947 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 937 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 948 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 938 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 949 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 950 | 939 | ||
| 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; // TODO | 957 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 969 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 958 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 970 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 971 | 959 | ||
| 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" { |
| 988 | test "peer type resolution implicit cast to return type" { | 976 | test "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; // TODO | 978 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 991 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 992 | 979 | ||
| 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" { |
| 1009 | test "peer type resolution implicit cast to variable type" { | 996 | test "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; // TODO | 998 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1012 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1013 | 999 | ||
| 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 |
| 1034 | test "cast between C pointer with different but compatible types" { | 1020 | test "cast between C pointer with different but compatible types" { |
| 1035 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1021 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1036 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1022 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1037 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1038 | 1023 | ||
| 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" { |
| 1052 | test "peer type resolve string lit with sentinel-terminated mutable slice" { | 1037 | test "peer type resolve string lit with sentinel-terminated mutable slice" { |
| 1053 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1038 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1054 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1039 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1055 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1056 | 1040 | ||
| 1057 | var array: [4:0]u8 = undefined; | 1041 | var array: [4:0]u8 = undefined; |
| 1058 | array[4] = 0; // TODO remove this when #4372 is solved | 1042 | 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 | } |
| 1063 | 1047 | ||
| 1064 | test "peer type resolve array pointers, one of them const" { | 1048 | test "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 | } |
| 1072 | 1054 | ||
| 1073 | test "peer type resolve array pointer and unknown pointer" { | 1055 | test "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 | } |
| 1093 | 1073 | ||
| 1094 | test "comptime float casts" { | 1074 | test "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 | } |
| 1141 | 1119 | ||
| 1142 | test "compile time int to ptr of function" { | 1120 | test "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 | } |
| 1147 | 1123 | ||
| ... | @@ -1156,6 +1132,7 @@ fn foobar(func: PFN_void) !void { | ... | @@ -1156,6 +1132,7 @@ fn foobar(func: PFN_void) !void { |
| 1156 | 1132 | ||
| 1157 | test "cast function with an opaque parameter" { | 1133 | test "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; | ||
| 1159 | 1136 | ||
| 1160 | if (builtin.zig_backend == .stage2_c) { | 1137 | if (builtin.zig_backend == .stage2_c) { |
| 1161 | // https://github.com/ziglang/zig/issues/16845 | 1138 | // 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 | } |
| 1341 | 1318 | ||
| 1342 | test "cast between [*c]T and ?[*:0]T on fn parameter" { | 1319 | test "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" { |
| 1381 | test "peer resolve arrays of different size to const slice" { | 1356 | test "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; // TODO | 1358 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1384 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1385 | 1359 | ||
| 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" { |
| 1485 | test "coerce undefined single-item pointer of array to error union of slice" { | 1459 | test "coerce undefined single-item pointer of array to error union of slice" { |
| 1486 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1460 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1487 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1461 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1488 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1489 | 1462 | ||
| 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" { |
| 1495 | 1468 | ||
| 1496 | test "pointer to empty struct literal to mutable slice" { | 1469 | test "pointer to empty struct literal to mutable slice" { |
| 1497 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1470 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1498 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1499 | 1471 | ||
| 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" { |
| 1584 | 1556 | ||
| 1585 | test "optional pointer coerced to optional allowzero pointer" { | 1557 | test "optional pointer coerced to optional allowzero pointer" { |
| 1586 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1558 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1587 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1588 | 1559 | ||
| 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 | } |
| 1595 | 1566 | ||
| 1596 | test "single item pointer to pointer to array to slice" { | 1567 | test "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 | } |
| 1632 | 1601 | ||
| 1633 | test "coercion from single-item pointer to @as to slice" { | 1602 | test "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; |
| 1637 | 1604 | ||
| 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; // TODO | 2261 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 2295 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2262 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2296 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2263 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2297 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 2298 | 2264 | ||
| 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" { |
| 2501 | test "numeric coercions with undefined" { | 2467 | test "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; | ||
| 2504 | 2471 | ||
| 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; // TODO | 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 20 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 20 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 21 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 21 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 22 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 23 | 22 | ||
| 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 | } |
| 426 | 426 | ||
| 427 | test "dereference undefined pointer to zero-bit type" { | 427 | test "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.*); |
| 430 | 432 |
test/behavior/defer.zig-2| ... | @@ -5,8 +5,6 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -5,8 +5,6 @@ const expectEqual = std.testing.expectEqual; |
| 5 | const expectError = std.testing.expectError; | 5 | const expectError = std.testing.expectError; |
| 6 | 6 | ||
| 7 | test "break and continue inside loop inside defer expression" { | 7 | test "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 | } |
| 10 | 10 | ||
| 11 | test "switch on empty enum with a specified tag type" { | 11 | test "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" { |
| 18 | 16 | ||
| 19 | test "switch on empty auto numbered tagged union" { | 17 | test "switch on empty auto numbered tagged union" { |
| 20 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 18 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 21 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 22 | 19 | ||
| 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 }; |
| 935 | test "enum literal casting to error union with payload enum" { | 935 | test "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; // TODO | 937 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 938 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 939 | 938 | ||
| 940 | var bar: error{B}!Bar = undefined; | 939 | var bar: error{B}!Bar = undefined; |
| 941 | bar = .B; // should never cast to the error set | 940 | 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; // TODO | 948 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 950 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 951 | 949 | ||
| 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; // TODO | 1054 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1057 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1058 | 1055 | ||
| 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" { |
| 1141 | test "size of enum with only one tag which has explicit integer tag type" { | 1138 | test "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; // TODO | 1140 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1144 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1145 | 1141 | ||
| 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 { |
| 30 | 30 | ||
| 31 | test "error binary operator" { | 31 | test "error binary operator" { |
| 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 34 | 33 | ||
| 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 { |
| 62 | 61 | ||
| 63 | test "error wrapping" { | 62 | test "error wrapping" { |
| 64 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 63 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 65 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 66 | 64 | ||
| 67 | try expect((baz() catch unreachable) == 15); | 65 | try expect((baz() catch unreachable) == 15); |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | test "unwrap simple value from error" { | 68 | test "unwrap simple value from error" { |
| 71 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 72 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 73 | 70 | ||
| 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 { |
| 80 | 77 | ||
| 81 | test "error return in assignment" { | 78 | test "error return in assignment" { |
| 82 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 83 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 84 | 80 | ||
| 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" { |
| 103 | test "widen cast integer payload of error union function call" { | 99 | test "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; // TODO | 101 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 106 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 107 | 102 | ||
| 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 | } |
| 151 | 146 | ||
| 152 | test "fn returning empty error set can be passed as fn returning any error" { | 147 | test "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 { |
| 243 | 237 | ||
| 244 | test "comptime test error for empty error set" { | 238 | test "comptime test error for empty error set" { |
| 245 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 239 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 246 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 247 | 240 | ||
| 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 | } |
| 280 | 273 | ||
| 281 | test "error inference with an empty set" { | 274 | test "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 { |
| 334 | 326 | ||
| 335 | test "error: Zero sized error set returned with value payload crash" { | 327 | test "error: Zero sized error set returned with value payload crash" { |
| 336 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 328 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 337 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 338 | 329 | ||
| 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" { |
| 434 | test "return function call to error set from error union function" { | 425 | test "return function call to error set from error union function" { |
| 435 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 426 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 436 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 427 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 437 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 438 | 428 | ||
| 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 | } |
| 671 | 661 | ||
| 672 | test "coerce error set to the current inferred error set" { | 662 | test "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" { |
| 833 | 822 | ||
| 834 | test "compare error union and error set" { | 823 | test "compare error union and error set" { |
| 835 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 824 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 836 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 837 | 825 | ||
| 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 | } |
| 863 | 851 | ||
| 864 | test "catch within a function that calls no errorable functions" { | 852 | test "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 | } |
| 869 | 855 | ||
| ... | @@ -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" { |
| 895 | test "optional error union return type" { | 881 | test "optional error union return type" { |
| 896 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 882 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 897 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 883 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 898 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 899 | 884 | ||
| 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" { |
| 942 | test "try used in recursive function with inferred error set" { | 927 | test "try used in recursive function with inferred error set" { |
| 943 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 928 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 944 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 929 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 930 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 945 | 931 | ||
| 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; |
| 5 | const expectEqual = std.testing.expectEqual; | 5 | const expectEqual = std.testing.expectEqual; |
| 6 | 6 | ||
| 7 | test "compile time recursion" { | 7 | test "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 | } |
| 12 | var some_data: [@as(usize, @intCast(fibonacci(7)))]u8 = undefined; | 10 | var 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 { |
| 74 | test "constant expressions" { | 72 | test "constant expressions" { |
| 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 73 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 76 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 74 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 77 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 78 | 75 | ||
| 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" { |
| 143 | test "a type constructed in a global expression" { | 140 | test "a type constructed in a global expression" { |
| 144 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 141 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 146 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 147 | 143 | ||
| 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 | } |
| 203 | 199 | ||
| 204 | test "constant struct with negation" { | 200 | test "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 | } |
| 209 | const Vertex = struct { | 203 | const 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 | } |
| 309 | 303 | ||
| 310 | test "comptime iterate over fn ptr list" { | 304 | test "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 { |
| 348 | test "@setEvalBranchQuota at same scope as generic function call" { | 340 | test "@setEvalBranchQuota at same scope as generic function call" { |
| 349 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 341 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 350 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 342 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 351 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 352 | 343 | ||
| 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 | } |
| 386 | 377 | ||
| 387 | test "return 0 from function that has u0 return type" { | 378 | test "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 | }; |
| 418 | 407 | ||
| 419 | test "inline for with same type but different values" { | 408 | test "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" { |
| 544 | test "@tagName of @typeInfo" { | 531 | test "@tagName of @typeInfo" { |
| 545 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 532 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 546 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 533 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 547 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 548 | 534 | ||
| 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; // TODO | 540 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 555 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 541 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 556 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 542 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 557 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 558 | 543 | ||
| 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 |
| 586 | test "ptr to local array argument at comptime" { | 571 | test "ptr to local array argument at comptime" { |
| 587 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 572 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 588 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 573 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 589 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 590 | 574 | ||
| 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"; |
| 623 | const hi2 = hi1; | 607 | const hi2 = hi1; |
| 624 | test "const global shares pointer with other same one" { | 608 | test "const global shares pointer with other same one" { |
| 625 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 609 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 626 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 627 | 610 | ||
| 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 | } |
| 660 | 643 | ||
| 661 | test "comptime function with mutable pointer is not memoized" { | 644 | test "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 | } |
| 730 | 711 | ||
| 731 | test "variable inside inline loop that has different types on different iterations" { | 712 | test "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 | } |
| 734 | 716 | ||
| ... | @@ -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; // TODO | 736 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 755 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 756 | 737 | ||
| 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; // TODO | 745 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 765 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 766 | 746 | ||
| 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; // TODO | 833 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 854 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 855 | 834 | ||
| 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; // TODO | 849 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 871 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 872 | 850 | ||
| 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" { |
| 1003 | 981 | ||
| 1004 | test "comptime break passing through runtime condition converted to runtime break" { | 982 | test "comptime break passing through runtime condition converted to runtime break" { |
| 1005 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 983 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1006 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1007 | 984 | ||
| 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; // TODO | 1014 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1038 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1015 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1039 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1016 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1040 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1041 | 1017 | ||
| 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 |
| 1109 | test "no dependency loop for alignment of self struct" { | 1085 | test "no dependency loop for alignment of self struct" { |
| 1110 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1086 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1087 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1112 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1113 | 1088 | ||
| 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" { |
| 1147 | test "no dependency loop for alignment of self bare union" { | 1122 | test "no dependency loop for alignment of self bare union" { |
| 1148 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1123 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1124 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1150 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1151 | 1125 | ||
| 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" { |
| 1185 | test "no dependency loop for alignment of self tagged union" { | 1159 | test "no dependency loop for alignment of self tagged union" { |
| 1186 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1160 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1187 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1161 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1188 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1189 | 1162 | ||
| 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; // TODO | 1349 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1377 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1350 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1378 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1351 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1379 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1380 | 1352 | ||
| 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" { |
| 1434 | 1406 | ||
| 1435 | test "continue in inline for inside a comptime switch" { | 1407 | test "continue in inline for inside a comptime switch" { |
| 1436 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1408 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1437 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1438 | 1409 | ||
| 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" { |
| 1500 | 1471 | ||
| 1501 | test "x and false is comptime-known false" { | 1472 | test "x and false is comptime-known false" { |
| 1502 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1503 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1504 | 1474 | ||
| 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" { |
| 1528 | 1498 | ||
| 1529 | test "x or true is comptime-known true" { | 1499 | test "x or true is comptime-known true" { |
| 1530 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1500 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1531 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1532 | 1501 | ||
| 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; // TODO | 1527 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1559 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1528 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1560 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1529 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1561 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1562 | 1530 | ||
| 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 | } |
| 1648 | 1616 | ||
| 1649 | test "inline for loop of functions returning error unions" { | 1617 | test "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; // TODO | 736 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 737 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 737 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 738 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 738 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 739 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 740 | 739 | ||
| 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" { |
| 1053 | test "eval @setFloatMode at compile-time" { | 1052 | test "eval @setFloatMode at compile-time" { |
| 1054 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1053 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1055 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1054 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1056 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1057 | 1055 | ||
| 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; // TODO | 1087 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1090 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1088 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1091 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1089 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1092 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1093 | 1090 | ||
| 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 | } |
| 21 | 21 | ||
| 22 | test "mutable local variables" { | 22 | test "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); |
| 27 | 25 | ||
| ... | @@ -53,8 +51,6 @@ test "weird function name" { | ... | @@ -53,8 +51,6 @@ test "weird function name" { |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | test "assign inline fn to const variable" { | 53 | test "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" { |
| 190 | 186 | ||
| 191 | test "pass by non-copying value" { | 187 | test "pass by non-copying value" { |
| 192 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 188 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 193 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 194 | 189 | ||
| 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 { |
| 218 | 213 | ||
| 219 | test "pass by non-copying value as method" { | 214 | test "pass by non-copying value as method" { |
| 220 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 221 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 222 | 216 | ||
| 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 { |
| 235 | 229 | ||
| 236 | test "pass by non-copying value as method, which is generic" { | 230 | test "pass by non-copying value as method, which is generic" { |
| 237 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 231 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 238 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 239 | 232 | ||
| 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 { |
| 253 | 246 | ||
| 254 | test "pass by non-copying value as method, at comptime" { | 247 | test "pass by non-copying value as method, at comptime" { |
| 255 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 248 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 256 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 257 | 249 | ||
| 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 | } |
| 397 | 389 | ||
| 398 | test "ability to give comptime types and non comptime types to same parameter" { | 390 | test "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 | } |
| 416 | 406 | ||
| 417 | test "function with inferred error set but returning no error" { | 407 | test "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 | } |
| 584 | 572 | ||
| 585 | test "pass and return comptime-only types" { | 573 | test "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" { |
| 257 | test "count over fixed range" { | 257 | test "count over fixed range" { |
| 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 259 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 259 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 260 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 261 | 260 | ||
| 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" { |
| 270 | test "two counters" { | 269 | test "two counters" { |
| 271 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 270 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 272 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 271 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 273 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 274 | 272 | ||
| 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; // TODO | 316 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 319 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 317 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 320 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 318 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 321 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 322 | 319 | ||
| 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; // TODO | 403 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 407 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 404 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 408 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 405 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 409 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 410 | 406 | ||
| 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; // TODO | 57 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 59 | 58 | ||
| 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; // TODO | 67 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 69 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 70 | 68 | ||
| 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 { |
| 91 | test "type constructed by comptime function call" { | 89 | test "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; // TODO | 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 94 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 95 | 92 | ||
| 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; // TODO | 114 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 118 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 119 | 115 | ||
| 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 | } |
| 148 | 144 | ||
| 149 | test "use generic param in generic param" { | 145 | test "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 | } |
| 154 | fn aGenericFn(comptime T: type, comptime a: T, b: T) T { | 148 | fn 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; // TODO | 174 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 181 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 182 | 175 | ||
| 183 | const A = 128; | 176 | const A = 128; |
| 184 | 177 | ||
| ... | @@ -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; // TODO | 247 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 255 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 248 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 256 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 249 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 257 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 258 | 250 | ||
| 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" { |
| 288 | 280 | ||
| 289 | test "generic function with void and comptime parameter" { | 281 | test "generic function with void and comptime parameter" { |
| 290 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 282 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 283 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 291 | 284 | ||
| 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" { |
| 304 | test "anonymous struct return type referencing comptime parameter" { | 297 | test "anonymous struct return type referencing comptime parameter" { |
| 305 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 298 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 306 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 299 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 307 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 308 | 300 | ||
| 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 | } |
| 406 | 398 | ||
| 407 | test "slice as parameter type" { | 399 | test "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 | } |
| 422 | 412 | ||
| 423 | test "null sentinel pointer passed as generic argument" { | 413 | test "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" { |
| 433 | 421 | ||
| 434 | test "generic function passed as comptime argument" { | 422 | test "generic function passed as comptime argument" { |
| 435 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 423 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 436 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 437 | 424 | ||
| 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; // TODO | 47 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 48 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 48 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 49 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 51 | 50 | ||
| 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 | } |
| 142 | 141 | ||
| 143 | test "inline switch capture is set when switch operand is comptime known" { | 142 | test "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; // TODO | 1020 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1021 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1021 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1022 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1022 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1023 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1024 | 1023 | ||
| 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 | } |
| 1147 | 1146 | ||
| 1148 | test "allow signed integer division/remainder when values are comptime-known and positive or exact" { | 1147 | test "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 | } |
| 1290 | 1287 | ||
| 1291 | test "shift left/right on u0 operand" { | 1288 | test "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; // TODO | 200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 203 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 204 | 203 | ||
| 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; // TODO | 256 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 258 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 257 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 259 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 260 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 261 | 259 | ||
| 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 | } |
| 501 | 501 | ||
| 502 | test "variable of optional of noreturn" { | 502 | test "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 | } |
| 126 | 126 | ||
| 127 | test "peer type resolution with C pointers" { | 127 | test "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 | } |
| 142 | 141 | ||
| 143 | test "peer type resolution with C pointer and const pointer" { | 142 | test "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" { |
| 314 | test "pointer sentinel with enums" { | 312 | test "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; // TODO | 314 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 317 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 318 | 315 | ||
| 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; // TODO | 334 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 338 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 335 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 339 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 340 | 336 | ||
| 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; // TODO | 349 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 354 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 350 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 355 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 351 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 356 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 357 | 352 | ||
| 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 | } |
| 375 | 370 | ||
| 376 | test "pointer arithmetic affects the alignment" { | 371 | test "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" { |
| 430 | test "element pointer to slice" { | 424 | test "element pointer to slice" { |
| 431 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 425 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 432 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 426 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 433 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 434 | 427 | ||
| 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" { |
| 453 | test "element pointer arithmetic to slice" { | 446 | test "element pointer arithmetic to slice" { |
| 454 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 447 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 455 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 448 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 456 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 457 | 449 | ||
| 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" { |
| 478 | 470 | ||
| 479 | test "array slicing to slice" { | 471 | test "array slicing to slice" { |
| 480 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 472 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 481 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 482 | 473 | ||
| 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 { |
| 29 | 29 | ||
| 30 | test "slicing" { | 30 | test "slicing" { |
| 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 33 | 32 | ||
| 34 | var array: [20]i32 = undefined; | 33 | var array: [20]i32 = undefined; |
| 35 | 34 | ||
| ... | @@ -122,7 +121,6 @@ test "slice of type" { | ... | @@ -122,7 +121,6 @@ test "slice of type" { |
| 122 | 121 | ||
| 123 | test "generic malloc free" { | 122 | test "generic malloc free" { |
| 124 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 126 | 124 | ||
| 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" { |
| 303 | 301 | ||
| 304 | test "obtaining a null terminated slice" { | 302 | test "obtaining a null terminated slice" { |
| 305 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 303 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 306 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 307 | 304 | ||
| 308 | // here we have a normal array | 305 | // 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" { |
| 346 | test "@ptrCast slice to pointer" { | 343 | test "@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; // TODO | 345 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 349 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 350 | 346 | ||
| 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" { |
| 572 | test "slice pointer-to-array null terminated" { | 568 | test "slice pointer-to-array null terminated" { |
| 573 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 569 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 574 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 570 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 575 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 576 | 571 | ||
| 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; // TODO | 621 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 627 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 622 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 628 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 623 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 629 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 630 | 624 | ||
| 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" { |
| 714 | test "slicing array with sentinel as end index" { | 708 | test "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; // TODO | 710 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 717 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 718 | 711 | ||
| 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" { |
| 733 | test "slicing slice with sentinel as end index" { | 726 | test "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; // TODO | 728 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 736 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 737 | 729 | ||
| 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 | } |
| 763 | 755 | ||
| 764 | test "slice field ptr const" { | 756 | test "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"; |
| 768 | 758 | ||
| 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" { |
| 777 | 767 | ||
| 778 | test "slice field ptr var" { | 768 | test "slice field ptr var" { |
| 779 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 769 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 780 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 781 | 770 | ||
| 782 | var var_slice: []const u8 = "string"; | 771 | var var_slice: []const u8 = "string"; |
| 783 | 772 |
test/behavior/struct.zig+11-14| ... | @@ -109,7 +109,6 @@ fn testMutation(foo: *StructFoo) void { | ... | @@ -109,7 +109,6 @@ fn testMutation(foo: *StructFoo) void { |
| 109 | 109 | ||
| 110 | test "struct byval assign" { | 110 | test "struct byval assign" { |
| 111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 112 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 113 | 112 | ||
| 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" { |
| 129 | const should_be_11 = StructWithNoFields.add(5, 6); | 128 | const should_be_11 = StructWithNoFields.add(5, 6); |
| 130 | 129 | ||
| 131 | test "invoke static method in global scope" { | 130 | test "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 | } |
| 136 | 133 | ||
| 137 | const empty_global_instance = StructWithNoFields{}; | 134 | const empty_global_instance = StructWithNoFields{}; |
| 138 | 135 | ||
| 139 | test "return empty struct instance" { | 136 | test "return empty struct instance" { |
| 137 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 138 | |||
| 140 | _ = returnEmptyStructInstance(); | 139 | _ = returnEmptyStructInstance(); |
| 141 | } | 140 | } |
| 142 | fn returnEmptyStructInstance() StructWithNoFields { | 141 | fn returnEmptyStructInstance() StructWithNoFields { |
| ... | @@ -253,7 +252,6 @@ test "usingnamespace within struct scope" { | ... | @@ -253,7 +252,6 @@ test "usingnamespace within struct scope" { |
| 253 | test "struct field init with catch" { | 252 | test "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; // TODO | 254 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 256 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 257 | 255 | ||
| 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 { |
| 331 | 329 | ||
| 332 | test "return empty struct from fn" { | 330 | test "return empty struct from fn" { |
| 333 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 331 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 332 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 334 | 333 | ||
| 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 | } |
| 365 | 364 | ||
| 366 | test "empty struct method call" { | 365 | test "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" { |
| 550 | 547 | ||
| 551 | test "zero-bit field in packed struct" { | 548 | test "zero-bit field in packed struct" { |
| 552 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 549 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 553 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 554 | 550 | ||
| 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 | } |
| 894 | 890 | ||
| 895 | test "fully anonymous struct" { | 891 | test "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 | } |
| 916 | 914 | ||
| 917 | test "fully anonymous list literal" { | 915 | test "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 | } |
| 943 | 943 | ||
| 944 | test "comptime struct field" { | 944 | test "comptime struct field" { |
| 945 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 946 | |||
| 947 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 945 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 948 | if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO | 946 | if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO |
| 949 | 947 | ||
| ... | @@ -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; // TODO | 979 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 982 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 980 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 983 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 981 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 984 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 985 | 982 | ||
| 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 | } |
| 1433 | 1430 | ||
| 1434 | test "struct has only one reference" { | 1431 | test "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" { |
| 1503 | 1498 | ||
| 1504 | test "function pointer in struct returns the struct" { | 1499 | test "function pointer in struct returns the struct" { |
| 1505 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1500 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1506 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1507 | 1501 | ||
| 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" { |
| 1553 | 1547 | ||
| 1554 | test "if inside struct init inside if" { | 1548 | test "if inside struct init inside if" { |
| 1555 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1549 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1556 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1557 | 1550 | ||
| 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 | } |
| 1716 | 1709 | ||
| 1717 | test "packed struct field in anonymous struct" { | 1710 | test "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 | } |
| 1741 | 1736 | ||
| 1742 | test "runtime side-effects in comptime-known struct init" { | 1737 | test "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; // TODO | 232 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 233 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 233 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 234 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 234 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 235 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 236 | 235 | ||
| 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; // TODO | 256 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 258 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 257 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 259 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 260 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 261 | 259 | ||
| 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; // TODO | 316 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 319 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 317 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 320 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 318 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 321 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 322 | 319 | ||
| 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" { |
| 355 | test "anon enum literal used in switch on union enum" { | 352 | test "anon enum literal used in switch on union enum" { |
| 356 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 353 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 357 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 354 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 358 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 359 | 355 | ||
| 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 { |
| 394 | 390 | ||
| 395 | test "capture value of switch with all unreachable prongs" { | 391 | test "capture value of switch with all unreachable prongs" { |
| 396 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 392 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 397 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 398 | 393 | ||
| 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 { |
| 408 | 403 | ||
| 409 | test "switch on integer with else capturing expr" { | 404 | test "switch on integer with else capturing expr" { |
| 410 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 411 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 412 | 406 | ||
| 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 |
| 498 | 492 | ||
| 499 | test "return result loc and then switch with range implicit casted to error union" { | 493 | test "return result loc and then switch with range implicit casted to error union" { |
| 500 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 494 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 501 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 502 | 495 | ||
| 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; // TODO | 532 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 540 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 533 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 541 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 534 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 542 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 543 | 535 | ||
| 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 | } |
| 707 | 699 | ||
| 708 | test "comptime inline switch" { | 700 | test "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 | } |
| 800 | 790 | ||
| 801 | test "nested break ignores switch conditions and breaks instead" { | 791 | test "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" { |
| 27 | test "this refer to container" { | 27 | test "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; // TODO | 29 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 30 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 31 | 30 | ||
| 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 | } |
| 234 | 234 | ||
| 235 | test "Macro that uses Long type concatenation casting" { | 235 | test "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 | } |
| 25 | 25 | ||
| 26 | test "try without vars" { | 26 | test "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); |
| 31 | 29 |
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; // TODO | 289 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 290 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 290 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 291 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 291 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 292 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 293 | 292 | ||
| 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; // TODO | 303 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 305 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 304 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 306 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 305 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 307 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 308 | 306 | ||
| 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" { |
| 343 | test "tuple type with void field and a runtime field" { | 341 | test "tuple type with void field and a runtime field" { |
| 344 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 342 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 345 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 343 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 346 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 347 | 344 | ||
| 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; // TODO | 161 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 162 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 162 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 163 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 164 | 163 | ||
| 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; // TODO | 192 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 194 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 193 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 195 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 196 | 194 | ||
| 197 | const TestSet = error.One; | 195 | const TestSet = error.One; |
| 198 | 196 | ||
| ... | @@ -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; // TODO | 205 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 208 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 206 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 209 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 210 | 207 | ||
| 211 | const TestSet = error{ One, Two } || error{Three}; | 208 | const TestSet = error{ One, Two } || error{Three}; |
| 212 | 209 | ||
| ... | @@ -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; // TODO | 221 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 225 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 226 | 222 | ||
| 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" { |
| 533 | 529 | ||
| 534 | test "Struct.is_tuple for anon struct literal" { | 530 | test "Struct.is_tuple for anon struct literal" { |
| 535 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 531 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 536 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 537 | 532 | ||
| 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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | const other = struct { | 3 | const 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 | }; |
| 15 | 16 | ||
| 16 | test { | 17 | test { |
| 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; |
| 19 | 22 |
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; // TODO | 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 52 | 51 | ||
| 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; // TODO | 67 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 69 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 70 | 68 | ||
| 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" { |
| 8 | 8 | ||
| 9 | test "ignore lval with underscore (while loop)" { | 9 | test "ignore lval with underscore (while loop)" { |
| 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 12 | 11 | ||
| 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; // TODO | 16 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 18 | 17 | ||
| 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; // TODO | 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 34 | 32 | ||
| 35 | var foo: FooWithFloats = undefined; | 33 | var foo: FooWithFloats = undefined; |
| 36 | 34 | ||
| ... | @@ -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; // TODO | 41 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 44 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 42 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 45 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 46 | 43 | ||
| 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; // TODO | 60 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 64 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 65 | 61 | ||
| 66 | var foo: Foo = undefined; | 62 | var foo: Foo = undefined; |
| 67 | 63 | ||
| ... | @@ -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; // TODO | 170 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 175 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 176 | 171 | ||
| 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; // TODO | 339 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 345 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 346 | 340 | ||
| 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; // TODO | 449 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 456 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 457 | 450 | ||
| 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; // TODO | 495 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 503 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 504 | 496 | ||
| 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" { |
| 513 | test "runtime tag name with single field" { | 505 | test "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; // TODO | 507 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 516 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 517 | 508 | ||
| 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; // TODO | 583 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 593 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 594 | 584 | ||
| 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; // TODO | 627 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 638 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 639 | 628 | ||
| 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; // TODO | 662 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 674 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 663 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 675 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 664 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 676 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 677 | 665 | ||
| 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) { |
| 702 | 690 | ||
| 703 | test "union with only 1 field casted to its enum type which has enum value specified" { | 691 | test "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; // TODO | 692 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 705 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 706 | 693 | ||
| 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; // TODO | 776 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 790 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 791 | 777 | ||
| 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; // TODO | 827 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 842 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 828 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 843 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 829 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 844 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 845 | 830 | ||
| 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; // TODO | 850 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 866 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 851 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 867 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 852 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 868 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 869 | 853 | ||
| 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; // TODO | 906 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 923 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 907 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 924 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 908 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 925 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 926 | 909 | ||
| 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; // TODO | 997 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1015 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 998 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1016 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 999 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1017 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1018 | 1000 | ||
| 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; // TODO | 1028 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1047 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1029 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1048 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1030 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1049 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1050 | 1031 | ||
| 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; // TODO | 1160 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1180 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1161 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1181 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1162 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1182 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1183 | 1163 | ||
| 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; // TODO | 1176 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1197 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1177 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1198 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1178 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1199 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1200 | 1179 | ||
| 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; // TODO | 1209 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1231 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1210 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1232 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1211 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1233 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1234 | 1212 | ||
| 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; // TODO | 1246 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1269 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1247 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1270 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1248 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1271 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1272 | 1249 | ||
| 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; // TODO | 1276 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1300 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1301 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1278 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1302 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1303 | 1279 | ||
| 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; // TODO | 1327 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1352 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1328 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1353 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1329 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1354 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1355 | 1330 | ||
| 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" { |
| 1480 | test "union reassignment can use previous value" { | 1455 | test "union reassignment can use previous value" { |
| 1481 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1456 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1482 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1457 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1483 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1484 | 1458 | ||
| 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" { |
| 1532 | 1506 | ||
| 1533 | test "access the tag of a global tagged union" { | 1507 | test "access the tag of a global tagged union" { |
| 1534 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1508 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1535 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1536 | 1509 | ||
| 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" { |
| 1544 | 1517 | ||
| 1545 | test "coerce enum literal to union in result loc" { | 1518 | test "coerce enum literal to union in result loc" { |
| 1546 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1519 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1547 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1548 | 1520 | ||
| 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 | } |
| 1670 | 1642 | ||
| 1671 | test "union with 128 bit integer" { | 1643 | test "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 }; |
| 1673 | 1647 | ||
| 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 | } |
| 15 | 15 | ||
| 16 | test "add arbitrary args" { | 16 | test "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 | } |
| 25 | 27 | ||
| 26 | test "send void arg to var args" { | 28 | test "send void arg to var args" { |
| 29 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 30 | |||
| 27 | readFirstVarArg(.{{}}); | 31 | readFirstVarArg(.{{}}); |
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | test "pass args directly" { | 34 | test "pass args directly" { |
| 31 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 35 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 36 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 37 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 33 | 38 | ||
| 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 | } |
| 83 | 88 | ||
| 84 | test "array of var args functions" { | 89 | test "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 | } |
| 88 | 95 | ||
| 89 | test "pass zero length array to var args param" { | 96 | test "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 | } |
| 92 | 101 |
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; // TODO | 240 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 241 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 241 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 242 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 242 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 243 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 244 | 243 | ||
| 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; // TODO | 1468 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1470 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1469 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1471 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1470 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1472 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1473 | 1471 | ||
| 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 | } |
| 51 | 51 | ||
| 52 | test "while with else" { | 52 | test "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 | } |
| 80 | 78 | ||
| 81 | test "continue outer while loop" { | 79 | test "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" { |
| 127 | 123 | ||
| 128 | test "continue and break" { | 124 | test "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; | ||
| 131 | 126 | ||
| 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 { |
| 149 | test "while with optional as condition" { | 144 | test "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; // TODO | 146 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 152 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 153 | 147 | ||
| 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" { |
| 162 | test "while with optional as condition with else" { | 156 | test "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; // TODO | 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 165 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 166 | 159 | ||
| 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; // TODO | 218 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 226 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 227 | 219 | ||
| 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 | } |
| 252 | 244 | ||
| 253 | test "return with implicit cast from while loop" { | 245 | test "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 | } |
| 258 | fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { | 248 | fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { |
| ... | @@ -263,7 +253,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { | ... | @@ -263,7 +253,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { |
| 263 | 253 | ||
| 264 | test "while on error union with else result follow else prong" { | 254 | test "while on error union with else result follow else prong" { |
| 265 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 255 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 266 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 267 | 256 | ||
| 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" { |
| 273 | 262 | ||
| 274 | test "while on error union with else result follow break prong" { | 263 | test "while on error union with else result follow break prong" { |
| 275 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 264 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 276 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 277 | 265 | ||
| 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; // TODO | 307 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 320 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 308 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 321 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 309 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 322 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 323 | 310 | ||
| 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 | } |
| 346 | 333 | ||
| 347 | test "else continue outer while" { | 334 | test "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; |