authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-11 15:56:35-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-04-11 15:56:35-04:00
log65bd8d52c8260ad8b5d37285b1d29c1516676c01
treeb5502ab11d9fd376043ba9046fd7186b4de87faf
parent08a6c4ca9bf177702ba0c170818506e730abfa41
parent33ad2c949e0355b680d93c2e7c3ba58a9b2c506c
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #23061 from pavelverigo/stage2-wasm-misc

stage2-wasm: multiple fixes

19 files changed, 216 insertions(+), 169 deletions(-)

src/arch/wasm/CodeGen.zig+216-132
......@@ -759,6 +759,16 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
759759 return result;
760760}
761761
762fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {
763 const zcu = cg.pt.zcu;
764 const ty = val.typeOf(zcu);
765
766 return if (isByRef(ty, zcu, cg.target))
767 .{ .uav_ref = .{ .ip_index = val.toIntern() } }
768 else
769 try cg.lowerConstant(val, ty);
770}
771
762772/// NOTE: if result == .stack, it will be stored in .local
763773fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void {
764774 assert(operands.len <= Liveness.bpi - 1);
......@@ -1588,12 +1598,18 @@ fn toWasmBits(bits: u16) ?u16 {
15881598/// Performs a copy of bytes for a given type. Copying all bytes
15891599/// from rhs to lhs.
15901600fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1601 const len_known_neq_0 = switch (len) {
1602 .imm32 => |val| if (val != 0) true else return,
1603 .imm64 => |val| if (val != 0) true else return,
1604 else => false,
1605 };
15911606 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
15921607 // If not, we lower it ourselves manually
15931608 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {
15941609 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
1610 const emit_check = !(len0_ok or len_known_neq_0);
15951611
1596 if (!len0_ok) {
1612 if (emit_check) {
15971613 try cg.startBlock(.block, .empty);
15981614
15991615 // Even if `len` is zero, the spec requires an implementation to trap if `src + len` or
......@@ -1616,7 +1632,7 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16161632 try cg.emitWValue(len);
16171633 try cg.addExtended(.memory_copy);
16181634
1619 if (!len0_ok) {
1635 if (emit_check) {
16201636 try cg.endBlock();
16211637 }
16221638
......@@ -2296,11 +2312,6 @@ fn airAlloc(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
22962312fn airStore(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
22972313 const pt = cg.pt;
22982314 const zcu = pt.zcu;
2299 if (safety) {
2300 // TODO if the value is undef, write 0xaa bytes to dest
2301 } else {
2302 // TODO if the value is undef, don't lower this instruction
2303 }
23042315 const bin_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
23052316
23062317 const lhs = try cg.resolveInst(bin_op.lhs);
......@@ -2309,44 +2320,65 @@ fn airStore(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
23092320 const ptr_info = ptr_ty.ptrInfo(zcu);
23102321 const ty = ptr_ty.childType(zcu);
23112322
2323 if (!safety and bin_op.rhs == .undef) {
2324 return cg.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
2325 }
2326
23122327 if (ptr_info.packed_offset.host_size == 0) {
23132328 try cg.store(lhs, rhs, ty, 0);
23142329 } else {
23152330 // at this point we have a non-natural alignment, we must
23162331 // load the value, and then shift+or the rhs into the result location.
2317 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2332 const host_size = ptr_info.packed_offset.host_size * 8;
2333 const host_ty = try pt.intType(.unsigned, host_size);
2334 const bit_size: u16 = @intCast(ty.bitSize(zcu));
2335 const bit_offset = ptr_info.packed_offset.bit_offset;
2336
2337 const mask_val = try cg.resolveValue(val: {
2338 const limbs = try cg.gpa.alloc(
2339 std.math.big.Limb,
2340 std.math.big.int.calcTwosCompLimbCount(host_size) + 1,
2341 );
2342 defer cg.gpa.free(limbs);
23182343
2319 if (isByRef(int_elem_ty, zcu, cg.target)) {
2320 return cg.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2321 }
2344 var mask_bigint: std.math.big.int.Mutable = .{ .limbs = limbs, .positive = undefined, .len = undefined };
2345 mask_bigint.setTwosCompIntLimit(.max, .unsigned, host_size);
2346
2347 if (bit_size != host_size) {
2348 mask_bigint.shiftRight(mask_bigint.toConst(), host_size - bit_size);
2349 }
2350 if (bit_offset != 0) {
2351 mask_bigint.shiftLeft(mask_bigint.toConst(), bit_offset);
2352 }
2353 mask_bigint.bitNotWrap(mask_bigint.toConst(), .unsigned, host_size);
2354
2355 break :val try pt.intValue_big(host_ty, mask_bigint.toConst());
2356 });
23222357
2323 var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(zcu)))) - 1));
2324 mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset));
2325 mask ^= ~@as(u64, 0);
2326 const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2327 .{ .imm32 = ptr_info.packed_offset.bit_offset }
2358 const shift_val: WValue = if (33 <= host_size and host_size <= 64)
2359 .{ .imm64 = bit_offset }
23282360 else
2329 .{ .imm64 = ptr_info.packed_offset.bit_offset };
2330 const mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2331 .{ .imm32 = @as(u32, @truncate(mask)) }
2361 .{ .imm32 = bit_offset };
2362
2363 if (host_size <= 64) {
2364 try cg.emitWValue(lhs);
2365 }
2366 const loaded = if (host_size <= 64)
2367 try cg.load(lhs, host_ty, 0)
23322368 else
2333 .{ .imm64 = mask };
2334 const wrap_mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2335 .{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(zcu))) }
2369 lhs;
2370 const anded = try cg.binOp(loaded, mask_val, host_ty, .@"and");
2371 const extended_value = try cg.intcast(rhs, ty, host_ty);
2372 const shifted_value = if (bit_offset > 0)
2373 try cg.binOp(extended_value, shift_val, host_ty, .shl)
23362374 else
2337 .{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(zcu)) };
2338
2339 try cg.emitWValue(lhs);
2340 const loaded = try cg.load(lhs, int_elem_ty, 0);
2341 const anded = try cg.binOp(loaded, mask_val, int_elem_ty, .@"and");
2342 const extended_value = try cg.intcast(rhs, ty, int_elem_ty);
2343 const masked_value = try cg.binOp(extended_value, wrap_mask_val, int_elem_ty, .@"and");
2344 const shifted_value = if (ptr_info.packed_offset.bit_offset > 0) shifted: {
2345 break :shifted try cg.binOp(masked_value, shift_val, int_elem_ty, .shl);
2346 } else masked_value;
2347 const result = try cg.binOp(anded, shifted_value, int_elem_ty, .@"or");
2348 // lhs is still on the stack
2349 try cg.store(.stack, result, int_elem_ty, lhs.offset());
2375 extended_value;
2376 const result = try cg.binOp(anded, shifted_value, host_ty, .@"or");
2377 if (host_size <= 64) {
2378 try cg.store(.stack, result, host_ty, lhs.offset());
2379 } else {
2380 try cg.store(lhs, result, host_ty, lhs.offset());
2381 }
23502382 }
23512383
23522384 return cg.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
......@@ -2357,33 +2389,39 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
23572389 const pt = cg.pt;
23582390 const zcu = pt.zcu;
23592391 const abi_size = ty.abiSize(zcu);
2392
2393 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
2394
23602395 switch (ty.zigTypeTag(zcu)) {
23612396 .error_union => {
23622397 const pl_ty = ty.errorUnionPayload(zcu);
23632398 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2364 return cg.store(lhs, rhs, Type.anyerror, 0);
2399 return cg.store(lhs, rhs, Type.anyerror, offset);
23652400 }
23662401
23672402 const len = @as(u32, @intCast(abi_size));
2403 assert(offset == 0);
23682404 return cg.memcpy(lhs, rhs, .{ .imm32 = len });
23692405 },
23702406 .optional => {
23712407 if (ty.isPtrLikeOptional(zcu)) {
2372 return cg.store(lhs, rhs, Type.usize, 0);
2408 return cg.store(lhs, rhs, Type.usize, offset);
23732409 }
23742410 const pl_ty = ty.optionalChild(zcu);
23752411 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2376 return cg.store(lhs, rhs, Type.u8, 0);
2412 return cg.store(lhs, rhs, Type.u8, offset);
23772413 }
23782414 if (pl_ty.zigTypeTag(zcu) == .error_set) {
2379 return cg.store(lhs, rhs, Type.anyerror, 0);
2415 return cg.store(lhs, rhs, Type.anyerror, offset);
23802416 }
23812417
23822418 const len = @as(u32, @intCast(abi_size));
2419 assert(offset == 0);
23832420 return cg.memcpy(lhs, rhs, .{ .imm32 = len });
23842421 },
23852422 .@"struct", .array, .@"union" => if (isByRef(ty, zcu, cg.target)) {
23862423 const len = @as(u32, @intCast(abi_size));
2424 assert(offset == 0);
23872425 return cg.memcpy(lhs, rhs, .{ .imm32 = len });
23882426 },
23892427 .vector => switch (determineSimdStoreStrategy(ty, zcu, cg.target)) {
......@@ -2407,6 +2445,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
24072445 },
24082446 .pointer => {
24092447 if (ty.isSlice(zcu)) {
2448 assert(offset == 0);
24102449 // store pointer first
24112450 // lower it to the stack so we do not have to store rhs into a local first
24122451 try cg.emitWValue(lhs);
......@@ -2421,6 +2460,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
24212460 }
24222461 },
24232462 .int, .@"enum", .float => if (abi_size > 8 and abi_size <= 16) {
2463 assert(offset == 0);
24242464 try cg.emitWValue(lhs);
24252465 const lsb = try cg.load(rhs, Type.u64, 0);
24262466 try cg.store(.stack, lsb, Type.u64, 0 + lhs.offset());
......@@ -2430,6 +2470,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
24302470 try cg.store(.stack, msb, Type.u64, 8 + lhs.offset());
24312471 return;
24322472 } else if (abi_size > 16) {
2473 assert(offset == 0);
24332474 try cg.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) });
24342475 },
24352476 else => if (abi_size > 8) {
......@@ -2480,22 +2521,30 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24802521 }
24812522
24822523 if (ptr_info.packed_offset.host_size == 0) {
2483 break :result try cg.load(operand, ty, 0);
2484 }
2485
2486 // at this point we have a non-natural alignment, we must
2487 // shift the value to obtain the correct bit.
2488 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2489 const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2490 .{ .imm32 = ptr_info.packed_offset.bit_offset }
2491 else if (ptr_info.packed_offset.host_size <= 8)
2492 .{ .imm64 = ptr_info.packed_offset.bit_offset }
2493 else
2494 return cg.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
2524 const loaded = try cg.load(operand, ty, 0);
2525 const ty_size = ty.abiSize(zcu);
2526 if (ty.isAbiInt(zcu) and ty_size * 8 > ty.bitSize(zcu)) {
2527 const int_elem_ty = try pt.intType(.unsigned, @intCast(ty_size * 8));
2528 break :result try cg.trunc(loaded, ty, int_elem_ty);
2529 } else {
2530 break :result loaded;
2531 }
2532 } else {
2533 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2534 const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2535 .{ .imm32 = ptr_info.packed_offset.bit_offset }
2536 else if (ptr_info.packed_offset.host_size <= 8)
2537 .{ .imm64 = ptr_info.packed_offset.bit_offset }
2538 else
2539 .{ .imm32 = ptr_info.packed_offset.bit_offset };
24952540
2496 const stack_loaded = try cg.load(operand, int_elem_ty, 0);
2497 const shifted = try cg.binOp(stack_loaded, shift_val, int_elem_ty, .shr);
2498 break :result try cg.trunc(shifted, ty, int_elem_ty);
2541 const stack_loaded = if (ptr_info.packed_offset.host_size <= 8)
2542 try cg.load(operand, int_elem_ty, 0)
2543 else
2544 operand;
2545 const shifted = try cg.binOp(stack_loaded, shift_val, int_elem_ty, .shr);
2546 break :result try cg.trunc(shifted, ty, int_elem_ty);
2547 }
24992548 };
25002549 return cg.finishAir(inst, result, &.{ty_op.operand});
25012550}
......@@ -3118,7 +3167,13 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
31183167 .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
31193168 .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } },
31203169 .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
3121 .eu_payload => return cg.fail("Wasm TODO: lower error union payload pointer", .{}),
3170 .eu_payload => |eu_ptr| try cg.lowerPtr(
3171 eu_ptr,
3172 offset + codegen.errUnionPayloadOffset(
3173 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu),
3174 zcu,
3175 ),
3176 ),
31223177 .opt_payload => |opt_ptr| return cg.lowerPtr(opt_ptr, offset),
31233178 .field => |field| {
31243179 const base_ptr = Value.fromInterned(field.base);
......@@ -3137,19 +3192,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
31373192 .@"extern", .@"packed" => unreachable,
31383193 },
31393194 .@"union" => switch (base_ty.containerLayout(zcu)) {
3140 .auto => off: {
3141 // Keep in sync with the `un` case of `generateSymbol`.
3142 const layout = base_ty.unionGetLayout(zcu);
3143 if (layout.payload_size == 0) break :off 0;
3144 if (layout.tag_size == 0) break :off 0;
3145 if (layout.tag_align.compare(.gte, layout.payload_align)) {
3146 // Tag first.
3147 break :off layout.tag_size;
3148 } else {
3149 // Payload first.
3150 break :off 0;
3151 }
3152 },
3195 .auto => base_ty.structFieldOffset(@intCast(field.index), zcu),
31533196 .@"extern", .@"packed" => unreachable,
31543197 },
31553198 else => unreachable,
......@@ -3295,16 +3338,16 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32953338 },
32963339 else => unreachable,
32973340 },
3298 .un => |un| {
3299 // in this case we have a packed union which will not be passed by reference.
3300 const constant_ty = if (un.tag == .none)
3301 try ty.unionBackingType(pt)
3302 else field_ty: {
3303 const union_obj = zcu.typeToUnion(ty).?;
3304 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
3305 break :field_ty Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
3306 };
3307 return cg.lowerConstant(Value.fromInterned(un.val), constant_ty);
3341 .un => {
3342 const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
3343
3344 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3345 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3346 const int_val = try pt.intValue(
3347 int_type,
3348 mem.readInt(u64, &buf, .little),
3349 );
3350 return cg.lowerConstant(int_val, int_type);
33083351 },
33093352 .memoized_call => unreachable,
33103353 }
......@@ -3352,6 +3395,14 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
33523395 const packed_struct = zcu.typeToPackedStruct(ty).?;
33533396 return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
33543397 },
3398 .@"union" => switch (ty.containerLayout(zcu)) {
3399 .@"packed" => switch (ty.bitSize(zcu)) {
3400 0...32 => return .{ .imm32 = 0xaaaaaaaa },
3401 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3402 else => unreachable,
3403 },
3404 else => unreachable,
3405 },
33553406 else => return cg.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}),
33563407 }
33573408}
......@@ -3841,15 +3892,12 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38413892 const packed_struct = zcu.typeToPackedStruct(struct_ty).?;
38423893 const offset = pt.structPackedFieldBitOffset(packed_struct, field_index);
38433894 const backing_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
3844 const wasm_bits = toWasmBits(backing_ty.intInfo(zcu).bits) orelse {
3845 return cg.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
3846 };
3847 const const_wvalue: WValue = if (wasm_bits == 32)
3848 .{ .imm32 = offset }
3849 else if (wasm_bits == 64)
3895 const host_bits = backing_ty.intInfo(zcu).bits;
3896
3897 const const_wvalue: WValue = if (33 <= host_bits and host_bits <= 64)
38503898 .{ .imm64 = offset }
38513899 else
3852 return cg.fail("TODO: airStructFieldVal for packed structs larger than 64 bits", .{});
3900 .{ .imm32 = offset };
38533901
38543902 // for first field we don't require any shifting
38553903 const shifted_value = if (offset == 0)
......@@ -4027,7 +4075,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner
40274075 if (use_br_table) {
40284076 const width = width_maybe.?;
40294077
4030 const br_value_original = try cg.binOp(target, try cg.resolveInst(Air.internedToRef(min.?.toIntern())), target_ty, .sub);
4078 const br_value_original = try cg.binOp(target, try cg.resolveValue(min.?), target_ty, .sub);
40314079 _ = try cg.intcast(br_value_original, target_ty, Type.u32);
40324080
40334081 const jump_table: Mir.JumpTable = .{ .length = width + 1 };
......@@ -4167,52 +4215,61 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerEr
41674215 return cg.finishAir(inst, result, &.{un_op});
41684216}
41694217
4218/// E!T -> T op_is_ptr == false
4219/// *(E!T) -> *T op_is_prt == true
41704220fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
41714221 const zcu = cg.pt.zcu;
41724222 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
41734223
41744224 const operand = try cg.resolveInst(ty_op.operand);
41754225 const op_ty = cg.typeOf(ty_op.operand);
4176 const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty;
4177 const payload_ty = err_ty.errorUnionPayload(zcu);
4226 const eu_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty;
4227 const payload_ty = eu_ty.errorUnionPayload(zcu);
41784228
41794229 const result: WValue = result: {
41804230 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
41814231 if (op_is_ptr) {
41824232 break :result cg.reuseOperand(ty_op.operand, operand);
4233 } else {
4234 break :result .none;
41834235 }
4184 break :result .none;
41854236 }
41864237
4187 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu)));
4238 const pl_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
41884239 if (op_is_ptr or isByRef(payload_ty, zcu, cg.target)) {
41894240 break :result try cg.buildPointerOffset(operand, pl_offset, .new);
4241 } else {
4242 assert(isByRef(eu_ty, zcu, cg.target));
4243 break :result try cg.load(operand, payload_ty, pl_offset);
41904244 }
4191
4192 break :result try cg.load(operand, payload_ty, pl_offset);
41934245 };
41944246 return cg.finishAir(inst, result, &.{ty_op.operand});
41954247}
41964248
4249/// E!T -> E op_is_ptr == false
4250/// *(E!T) -> E op_is_prt == true
4251/// NOTE: op_is_ptr will not change return type
41974252fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
41984253 const zcu = cg.pt.zcu;
41994254 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42004255
42014256 const operand = try cg.resolveInst(ty_op.operand);
42024257 const op_ty = cg.typeOf(ty_op.operand);
4203 const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty;
4204 const payload_ty = err_ty.errorUnionPayload(zcu);
4258 const eu_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty;
4259 const payload_ty = eu_ty.errorUnionPayload(zcu);
42054260
42064261 const result: WValue = result: {
4207 if (err_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4262 if (eu_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
42084263 break :result .{ .imm32 = 0 };
42094264 }
42104265
4211 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4266 const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu));
4267 if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) {
4268 break :result try cg.load(operand, Type.anyerror, err_offset);
4269 } else {
4270 assert(!payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
42124271 break :result cg.reuseOperand(ty_op.operand, operand);
42134272 }
4214
4215 break :result try cg.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, zcu)));
42164273 };
42174274 return cg.finishAir(inst, result, &.{ty_op.operand});
42184275}
......@@ -4438,9 +4495,6 @@ fn airOptionalPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
44384495 const operand = try cg.resolveInst(ty_op.operand);
44394496 const opt_ty = cg.typeOf(ty_op.operand).childType(zcu);
44404497 const payload_ty = opt_ty.optionalChild(zcu);
4441 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4442 return cg.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
4443 }
44444498
44454499 if (opt_ty.optionalReprIsPayload(zcu)) {
44464500 return cg.finishAir(inst, operand, &.{ty_op.operand});
......@@ -4731,11 +4785,6 @@ fn airPtrBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
47314785
47324786fn airMemset(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
47334787 const zcu = cg.pt.zcu;
4734 if (safety) {
4735 // TODO if the value is undef, write 0xaa bytes to dest
4736 } else {
4737 // TODO if the value is undef, don't lower this instruction
4738 }
47394788 const bin_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
47404789
47414790 const ptr = try cg.resolveInst(bin_op.lhs);
......@@ -4752,6 +4801,10 @@ fn airMemset(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
47524801 else
47534802 ptr_ty.childType(zcu);
47544803
4804 if (!safety and bin_op.rhs == .undef) {
4805 return cg.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
4806 }
4807
47554808 const dst_ptr = try cg.sliceOrArrayPtr(ptr, ptr_ty);
47564809 try cg.memset(elem_ty, dst_ptr, len, value);
47574810
......@@ -5193,9 +5246,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51935246 const result = try cg.allocStack(result_ty);
51945247 const elem_ty = result_ty.childType(zcu);
51955248 const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu)));
5196 const sentinel = if (result_ty.sentinel(zcu)) |sent| blk: {
5197 break :blk try cg.lowerConstant(sent, elem_ty);
5198 } else null;
5249 const sentinel = result_ty.sentinel(zcu);
51995250
52005251 // When the element type is by reference, we must copy the entire
52015252 // value. It is therefore safer to move the offset pointer and store
......@@ -5208,12 +5259,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52085259 const elem_val = try cg.resolveInst(elem);
52095260 try cg.store(offset, elem_val, elem_ty, 0);
52105261
5211 if (elem_index < elements.len - 1 and sentinel == null) {
5262 if (elem_index < elements.len - 1 or sentinel != null) {
52125263 _ = try cg.buildPointerOffset(offset, elem_size, .modify);
52135264 }
52145265 }
5215 if (sentinel) |sent| {
5216 try cg.store(offset, sent, elem_ty, 0);
5266 if (sentinel) |s| {
5267 const val = try cg.resolveValue(s);
5268 try cg.store(offset, val, elem_ty, 0);
52175269 }
52185270 } else {
52195271 var offset: u32 = 0;
......@@ -5222,8 +5274,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52225274 try cg.store(result, elem_val, elem_ty, offset);
52235275 offset += elem_size;
52245276 }
5225 if (sentinel) |sent| {
5226 try cg.store(result, sent, elem_ty, offset);
5277 if (sentinel) |s| {
5278 const val = try cg.resolveValue(s);
5279 try cg.store(result, val, elem_ty, offset);
52275280 }
52285281 }
52295282 break :result_value result;
......@@ -5407,31 +5460,40 @@ fn cmpOptionals(cg: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: st
54075460 assert(operand_ty.hasRuntimeBitsIgnoreComptime(zcu));
54085461 assert(op == .eq or op == .neq);
54095462 const payload_ty = operand_ty.optionalChild(zcu);
5463 assert(!isByRef(payload_ty, zcu, cg.target));
54105464
5411 // We store the final result in here that will be validated
5412 // if the optional is truly equal.
5413 var result = try cg.ensureAllocLocal(Type.i32);
5465 var result = try cg.allocLocal(Type.i32);
54145466 defer result.free(cg);
54155467
5468 var lhs_null = try cg.allocLocal(Type.i32);
5469 defer lhs_null.free(cg);
5470
54165471 try cg.startBlock(.block, .empty);
5472
5473 try cg.addImm32(if (op == .eq) 0 else 1);
5474 try cg.addLocal(.local_set, result.local.value);
5475
54175476 _ = try cg.isNull(lhs, operand_ty, .i32_eq);
5477 try cg.addLocal(.local_tee, lhs_null.local.value);
54185478 _ = try cg.isNull(rhs, operand_ty, .i32_eq);
5419 try cg.addTag(.i32_ne); // inverse so we can exit early
5420 try cg.addLabel(.br_if, 0);
5479 try cg.addTag(.i32_ne);
5480 try cg.addLabel(.br_if, 0); // only one is null
5481
5482 try cg.addImm32(if (op == .eq) 1 else 0);
5483 try cg.addLocal(.local_set, result.local.value);
5484
5485 try cg.addLocal(.local_get, lhs_null.local.value);
5486 try cg.addLabel(.br_if, 0); // both are null
54215487
54225488 _ = try cg.load(lhs, payload_ty, 0);
54235489 _ = try cg.load(rhs, payload_ty, 0);
5424 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, zcu, cg.target) });
5425 try cg.addTag(Mir.Inst.Tag.fromOpcode(opcode));
5426 try cg.addLabel(.br_if, 0);
5427
5428 try cg.addImm32(1);
5490 _ = try cg.cmp(.stack, .stack, payload_ty, op);
54295491 try cg.addLocal(.local_set, result.local.value);
5492
54305493 try cg.endBlock();
54315494
5432 try cg.emitWValue(result);
5433 try cg.addImm32(0);
5434 try cg.addTag(if (op == .eq) .i32_ne else .i32_eq);
5495 try cg.addLocal(.local_get, result.local.value);
5496
54355497 return .stack;
54365498}
54375499
......@@ -5659,13 +5721,25 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
56595721}
56605722
56615723fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5662 const zcu = cg.pt.zcu;
5724 const pt = cg.pt;
5725 const zcu = pt.zcu;
56635726 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
56645727 const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
56655728
56665729 const field_ptr = try cg.resolveInst(extra.field_ptr);
5667 const parent_ty = ty_pl.ty.toType().childType(zcu);
5668 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);
5730 const parent_ptr_ty = cg.typeOfIndex(inst);
5731 const parent_ty = parent_ptr_ty.childType(zcu);
5732 const field_ptr_ty = cg.typeOf(extra.field_ptr);
5733 const field_index = extra.field_index;
5734 const field_offset = switch (parent_ty.containerLayout(zcu)) {
5735 .auto, .@"extern" => parent_ty.structFieldOffset(field_index, zcu),
5736 .@"packed" => offset: {
5737 const parent_ptr_offset = parent_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset;
5738 const field_offset = if (zcu.typeToStruct(parent_ty)) |loaded_struct| pt.structPackedFieldBitOffset(loaded_struct, field_index) else 0;
5739 const field_ptr_offset = field_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset;
5740 break :offset @divExact(parent_ptr_offset + field_offset - field_ptr_offset, 8);
5741 },
5742 };
56695743
56705744 const result = if (field_offset != 0) result: {
56715745 const base = try cg.buildPointerOffset(field_ptr, 0, .new);
......@@ -6260,11 +6334,21 @@ fn airClz(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62606334
62616335 switch (wasm_bits) {
62626336 32 => {
6263 try cg.emitWValue(operand);
6337 if (int_info.signedness == .signed) {
6338 const mask = ~@as(u32, 0) >> @intCast(32 - int_info.bits);
6339 _ = try cg.binOp(operand, .{ .imm32 = mask }, ty, .@"and");
6340 } else {
6341 try cg.emitWValue(operand);
6342 }
62646343 try cg.addTag(.i32_clz);
62656344 },
62666345 64 => {
6267 try cg.emitWValue(operand);
6346 if (int_info.signedness == .signed) {
6347 const mask = ~@as(u64, 0) >> @intCast(64 - int_info.bits);
6348 _ = try cg.binOp(operand, .{ .imm64 = mask }, ty, .@"and");
6349 } else {
6350 try cg.emitWValue(operand);
6351 }
62686352 try cg.addTag(.i64_clz);
62696353 try cg.addTag(.i32_wrap_i64);
62706354 },
test/behavior/array.zig-2
......@@ -1049,7 +1049,6 @@ test "@splat array with sentinel" {
10491049 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10501050 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10511051 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1052 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10531052 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10541053
10551054 const S = struct {
......@@ -1074,7 +1073,6 @@ test "@splat zero-length array" {
10741073 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10751074 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10761075 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1077 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10781076 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10791077
10801078 const S = struct {
test/behavior/bitcast.zig-2
......@@ -480,7 +480,6 @@ test "@bitCast of packed struct of bools all true" {
480480 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
481481 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
482482 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
483 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
484483 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
485484
486485 const P = packed struct {
......@@ -501,7 +500,6 @@ test "@bitCast of packed struct of bools all false" {
501500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
502501 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
503502 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
504 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
505503 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
506504
507505 const P = packed struct {
test/behavior/call.zig-2
......@@ -439,7 +439,6 @@ test "method call as parameter type" {
439439}
440440
441441test "non-anytype generic parameters provide result type" {
442 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
443442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
444443 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
445444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -469,7 +468,6 @@ test "non-anytype generic parameters provide result type" {
469468}
470469
471470test "argument to generic function has correct result type" {
472 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
473471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
474472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
475473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/cast.zig-2
......@@ -159,7 +159,6 @@ test "@floatFromInt(f80)" {
159159test "@intFromFloat" {
160160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
161161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
163162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
164163 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
165164
......@@ -2640,7 +2639,6 @@ test "numeric coercions with undefined" {
26402639}
26412640
26422641test "15-bit int to float" {
2643 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
26442642 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
26452643
26462644 var a: u15 = 42;
test/behavior/cast_int.zig-1
......@@ -214,7 +214,6 @@ test "load non byte-sized value in union" {
214214 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
215215 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
216216 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
217 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
218217 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
219218
220219 // note: this bug is triggered by the == operator, expectEqual will hide it
test/behavior/defer.zig-1
......@@ -134,7 +134,6 @@ test "errdefer with payload" {
134134test "reference to errdefer payload" {
135135 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
136136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
138137 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
139138 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
140139 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/error.zig-1
......@@ -1107,7 +1107,6 @@ test "result location initialization of error union with OPV payload" {
11071107}
11081108
11091109test "return error union with i65" {
1110 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
11111110 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11121111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11131112
test/behavior/field_parent_ptr.zig-8
......@@ -588,7 +588,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {
588588test "@fieldParentPtr unaligned packed struct" {
589589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
590590 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
591 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
592591 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
593592 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
594593
......@@ -727,7 +726,6 @@ test "@fieldParentPtr unaligned packed struct" {
727726test "@fieldParentPtr aligned packed struct" {
728727 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
729728 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
730 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
731729 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
732730 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
733731
......@@ -865,7 +863,6 @@ test "@fieldParentPtr aligned packed struct" {
865863
866864test "@fieldParentPtr nested packed struct" {
867865 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
868 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
869866 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
870867 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
871868
......@@ -1028,7 +1025,6 @@ test "@fieldParentPtr nested packed struct" {
10281025
10291026test "@fieldParentPtr packed struct first zero-bit field" {
10301027 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1031 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10321028 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10331029 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10341030
......@@ -1134,7 +1130,6 @@ test "@fieldParentPtr packed struct first zero-bit field" {
11341130
11351131test "@fieldParentPtr packed struct middle zero-bit field" {
11361132 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1137 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
11381133 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11391134 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11401135
......@@ -1240,7 +1235,6 @@ test "@fieldParentPtr packed struct middle zero-bit field" {
12401235
12411236test "@fieldParentPtr packed struct last zero-bit field" {
12421237 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1243 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
12441238 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12451239 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12461240
......@@ -1753,7 +1747,6 @@ test "@fieldParentPtr extern union" {
17531747}
17541748
17551749test "@fieldParentPtr packed union" {
1756 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
17571750 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
17581751 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17591752 if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO
......@@ -1892,7 +1885,6 @@ test "@fieldParentPtr packed union" {
18921885
18931886test "@fieldParentPtr tagged union all zero-bit fields" {
18941887 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1895 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
18961888 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18971889 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18981890
test/behavior/floatop.zig-3
......@@ -123,7 +123,6 @@ fn testMul(comptime T: type) !void {
123123
124124test "cmp f16" {
125125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
127126 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
128127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
129128 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
......@@ -1540,7 +1539,6 @@ test "neg f16" {
15401539 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15411540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15421541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1543 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
15441542 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
15451543 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15461544
......@@ -1557,7 +1555,6 @@ test "neg f32/f64" {
15571555 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15581556 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15591557 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1560 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
15611558 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15621559
15631560 try testNeg(f32);
test/behavior/int128.zig-1
......@@ -68,7 +68,6 @@ test "int128" {
6868}
6969
7070test "truncate int128" {
71 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
7271 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7372 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/math.zig-1
......@@ -65,7 +65,6 @@ test "@clz" {
6565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6666 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6767 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
6968 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
7069 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7170
test/behavior/optional.zig-3
......@@ -59,7 +59,6 @@ fn testNullPtrsEql() !void {
5959}
6060
6161test "optional with zero-bit type" {
62 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
6362 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
6463 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6564
......@@ -212,7 +211,6 @@ test "equality compare optionals and non-optionals" {
212211}
213212
214213test "compare optionals with modified payloads" {
215 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
216214 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
217215
218216 var lhs: ?bool = false;
......@@ -643,7 +641,6 @@ test "result location initialization of optional with OPV payload" {
643641 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
644642 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
645643 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
646 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
647644 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
648645
649646 const S = struct {
test/behavior/packed-struct.zig-1
......@@ -1321,7 +1321,6 @@ test "packed struct with signed field" {
13211321test "assign packed struct initialized with RLS to packed struct literal field" {
13221322 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) return error.SkipZigTest;
13231323 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1324 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
13251324 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13261325
13271326 const Inner = packed struct { x: u17 };
test/behavior/packed_struct_explicit_backing_int.zig-1
......@@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual;
55const native_endian = builtin.cpu.arch.endian();
66
77test "packed struct explicit backing integer" {
8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1110 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/struct.zig-3
......@@ -421,9 +421,7 @@ const Foo96Bits = packed struct {
421421test "packed struct 24bits" {
422422 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
423423 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
424 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
425424 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
426 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; // TODO
427425 if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO
428426 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
429427
......@@ -763,7 +761,6 @@ const S0 = struct {
763761var g_foo: S0 = S0.init();
764762
765763test "packed struct with fp fields" {
766 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
767764 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
768765 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
769766 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/switch_on_captured_error.zig-3
......@@ -7,7 +7,6 @@ const builtin = @import("builtin");
77
88test "switch on error union catch capture" {
99 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1110 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1211
1312 const S = struct {
......@@ -302,7 +301,6 @@ test "switch on error union catch capture" {
302301
303302test "switch on error union if else capture" {
304303 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
305 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
306304 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
307305
308306 const S = struct {
......@@ -794,7 +792,6 @@ test "switch on error union if else capture" {
794792 }
795793
796794 fn testAddressOf() !void {
797 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
798795 {
799796 const a: anyerror!usize = 0;
800797 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
test/behavior/tuple.zig-1
......@@ -507,7 +507,6 @@ test "tuple with runtime value coerced into a slice with a sentinel" {
507507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
509509 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
510 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
511510 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
512511 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
513512
test/behavior/undefined.zig-1
......@@ -103,7 +103,6 @@ test "reslice of undefined global var slice" {
103103test "returned undef is 0xaa bytes when runtime safety is enabled" {
104104 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
105105 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
106 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
107106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
108107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
109108