authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-06 17:46:51+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-19 20:18:59+02:00
log67d27dbe631d1292be363f4121217d66e2d7fd0f
treea75355b2c870c352a8f977a72d29376674d17553
parente20976b7f209a768cb55a37e6a58ed177d76013e
signaturelock-open Commit is signed but in an unrecognized format.

wasm: fix liveness bugs

Make sure to increase the reference count for `intcast` when the operand doesn't require any casting of the respective WebAssembly type. Function arguments have a reserved slot, and therefore cannot be re-used arbitrarily

1 files changed, 10 insertions(+), 1 deletions(-)

src/arch/wasm/CodeGen.zig+10-1
...@@ -881,6 +881,9 @@ fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {...@@ -881,6 +881,9 @@ fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {
881 const value = func.currentBranch().values.getPtr(ref) orelse return;881 const value = func.currentBranch().values.getPtr(ref) orelse return;
882 if (value.* != .local) return;882 if (value.* != .local) return;
883 log.debug("Decreasing reference for ref: %{?d}\n", .{Air.refToIndex(ref)});883 log.debug("Decreasing reference for ref: %{?d}\n", .{Air.refToIndex(ref)});
884 if (value.local.value < func.arg_index) {
885 return; // function arguments can never be re-used
886 }
884 value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer887 value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer
885 if (value.local.references == 0) {888 if (value.local.references == 0) {
886 value.free(func);889 value.free(func);
...@@ -4021,7 +4024,13 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4021,7 +4024,13 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4021 return func.fail("todo Wasm intcast for bitsize > 128", .{});4024 return func.fail("todo Wasm intcast for bitsize > 128", .{});
4022 }4025 }
40234026
4024 const result = try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);4027 const op_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
4028 const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
4029 const result = if (op_bits == wanted_bits)
4030 func.reuseOperand(ty_op.operand, operand)
4031 else
4032 try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
4033
4025 func.finishAir(inst, result, &.{});4034 func.finishAir(inst, result, &.{});
4026}4035}
40274036