authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2025-02-27 18:25:38+01:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2025-03-24 15:00:00+01:00
log0e109add37e304bf97b2f5f5d91be0870d18506c
treee69c82041067ff0b504385db8497a78283d05fce
parent15bc2ab0a868fed31780d73451db4d1c69e7b489

stage2-wasm: clean memcpy + fix another bug in aggr_init for optionals arr


2 files changed, 16 insertions(+), 11 deletions(-)

src/arch/wasm/CodeGen.zig+16-10
...@@ -1588,12 +1588,18 @@ fn toWasmBits(bits: u16) ?u16 {...@@ -1588,12 +1588,18 @@ fn toWasmBits(bits: u16) ?u16 {
1588/// Performs a copy of bytes for a given type. Copying all bytes1588/// Performs a copy of bytes for a given type. Copying all bytes
1589/// from rhs to lhs.1589/// from rhs to lhs.
1590fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {1590fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1591 const len_known_neq_0 = switch (len) {
1592 .imm32 => |val| if (val != 0) true else return,
1593 .imm64 => |val| if (val != 0) true else return,
1594 else => false,
1595 };
1591 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.1596 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
1592 // If not, we lower it ourselves manually1597 // If not, we lower it ourselves manually
1593 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {1598 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {
1594 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);1599 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
1600 const emit_check = !(len0_ok or len_known_neq_0);
15951601
1596 if (!len0_ok) {1602 if (emit_check) {
1597 try cg.startBlock(.block, .empty);1603 try cg.startBlock(.block, .empty);
15981604
1599 // Even if `len` is zero, the spec requires an implementation to trap if `src + len` or1605 // Even if `len` is zero, the spec requires an implementation to trap if `src + len` or
...@@ -1616,7 +1622,7 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {...@@ -1616,7 +1622,7 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1616 try cg.emitWValue(len);1622 try cg.emitWValue(len);
1617 try cg.addExtended(.memory_copy);1623 try cg.addExtended(.memory_copy);
16181624
1619 if (!len0_ok) {1625 if (emit_check) {
1620 try cg.endBlock();1626 try cg.endBlock();
1621 }1627 }
16221628
...@@ -5196,9 +5202,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5196,9 +5202,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5196 const result = try cg.allocStack(result_ty);5202 const result = try cg.allocStack(result_ty);
5197 const elem_ty = result_ty.childType(zcu);5203 const elem_ty = result_ty.childType(zcu);
5198 const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu)));5204 const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu)));
5199 const sentinel = if (result_ty.sentinel(zcu)) |sent| blk: {5205 const sentinel = result_ty.sentinel(zcu);
5200 break :blk try cg.lowerConstant(sent, elem_ty);
5201 } else null;
52025206
5203 // When the element type is by reference, we must copy the entire5207 // When the element type is by reference, we must copy the entire
5204 // value. It is therefore safer to move the offset pointer and store5208 // value. It is therefore safer to move the offset pointer and store
...@@ -5211,12 +5215,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5211,12 +5215,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5211 const elem_val = try cg.resolveInst(elem);5215 const elem_val = try cg.resolveInst(elem);
5212 try cg.store(offset, elem_val, elem_ty, 0);5216 try cg.store(offset, elem_val, elem_ty, 0);
52135217
5214 if (elem_index < elements.len - 1 and sentinel == null) {5218 if (elem_index < elements.len - 1 or sentinel != null) {
5215 _ = try cg.buildPointerOffset(offset, elem_size, .modify);5219 _ = try cg.buildPointerOffset(offset, elem_size, .modify);
5216 }5220 }
5217 }5221 }
5218 if (sentinel) |sent| {5222 if (sentinel) |s| {
5219 try cg.store(offset, sent, elem_ty, 0);5223 const val = try cg.resolveInst(Air.internedToRef(s.toIntern()));
5224 try cg.store(offset, val, elem_ty, 0);
5220 }5225 }
5221 } else {5226 } else {
5222 var offset: u32 = 0;5227 var offset: u32 = 0;
...@@ -5225,8 +5230,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5225,8 +5230,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5225 try cg.store(result, elem_val, elem_ty, offset);5230 try cg.store(result, elem_val, elem_ty, offset);
5226 offset += elem_size;5231 offset += elem_size;
5227 }5232 }
5228 if (sentinel) |sent| {5233 if (sentinel) |s| {
5229 try cg.store(result, sent, elem_ty, offset);5234 const val = try cg.resolveInst(Air.internedToRef(s.toIntern()));
5235 try cg.store(result, val, elem_ty, offset);
5230 }5236 }
5231 }5237 }
5232 break :result_value result;5238 break :result_value result;
test/behavior/tuple.zig-1
...@@ -507,7 +507,6 @@ test "tuple with runtime value coerced into a slice with a sentinel" {...@@ -507,7 +507,6 @@ test "tuple with runtime value coerced into a slice with a sentinel" {
507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO509 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
510 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
511 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;510 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
512 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;511 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
513512