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
This commit is contained in:
Luuk de Gram
2024-02-11 12:16:18 +01:00
parent e56fe06d30
commit 320c4d68f5

View File

@@ -1432,21 +1432,13 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
}
assert(ty_classes[0] == .direct);
const scalar_type = abi.scalarType(ty, mod);
const abi_size = scalar_type.abiSize(mod);
try func.emitWValue(value);
// When the value lives in the virtual stack, we must load it onto the actual stack
if (value != .imm32 and value != .imm64) {
const opcode = buildOpcode(.{
.op = .load,
.width = @as(u8, @intCast(abi_size)),
.signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
.valtype1 = typeToValtype(scalar_type, mod),
});
try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
.offset = value.offset(),
.alignment = @intCast(scalar_type.abiAlignment(mod).toByteUnitsOptional().?),
});
switch (value) {
.memory,
.memory_offset,
.stack_offset,
=> _ = try func.load(value, scalar_type, 0),
.dead => unreachable,
else => try func.emitWValue(value),
}
},
.Int, .Float => {
@@ -2522,7 +2514,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
return WValue{ .stack = {} };
}
const abi_size = @as(u8, @intCast(ty.abiSize(mod)));
const abi_size: u8 = @intCast(ty.abiSize(mod));
const opcode = buildOpcode(.{
.valtype1 = typeToValtype(ty, mod),
.width = abi_size * 8,