authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-11 12:16:18+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-11 17:09:18+01:00
log320c4d68f5f40794ae31d5535de9c3a8ff5cb471
treec658f57f89942bc57b0f7e725487933dcfe27a38
parente56fe06d3083d29b253ee8f4586971ec362a1e95

wasm: correctly lower packed structs in arguments

When an argument is a 'local', which is the case when it's a parameter, we should not attempt to load it from memory. Instead, we directly emit it to the stack. Only when the `WValue` is ensure to live in the linear data section do we load it from memory onto the stack. closes #18894

1 files changed, 8 insertions(+), 16 deletions(-)

src/arch/wasm/CodeGen.zig+8-16
......@@ -1432,21 +1432,13 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
14321432 }
14331433 assert(ty_classes[0] == .direct);
14341434 const scalar_type = abi.scalarType(ty, mod);
1435 const abi_size = scalar_type.abiSize(mod);
1436 try func.emitWValue(value);
1437
1438 // When the value lives in the virtual stack, we must load it onto the actual stack
1439 if (value != .imm32 and value != .imm64) {
1440 const opcode = buildOpcode(.{
1441 .op = .load,
1442 .width = @as(u8, @intCast(abi_size)),
1443 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
1444 .valtype1 = typeToValtype(scalar_type, mod),
1445 });
1446 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
1447 .offset = value.offset(),
1448 .alignment = @intCast(scalar_type.abiAlignment(mod).toByteUnitsOptional().?),
1449 });
1435 switch (value) {
1436 .memory,
1437 .memory_offset,
1438 .stack_offset,
1439 => _ = try func.load(value, scalar_type, 0),
1440 .dead => unreachable,
1441 else => try func.emitWValue(value),
14501442 }
14511443 },
14521444 .Int, .Float => {
......@@ -2522,7 +2514,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25222514 return WValue{ .stack = {} };
25232515 }
25242516
2525 const abi_size = @as(u8, @intCast(ty.abiSize(mod)));
2517 const abi_size: u8 = @intCast(ty.abiSize(mod));
25262518 const opcode = buildOpcode(.{
25272519 .valtype1 = typeToValtype(ty, mod),
25282520 .width = abi_size * 8,