aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-05-06 17:46:51 +0200
committerLuuk de Gram <luuk@degram.dev>2023-05-19 20:18:59 +0200
commit67d27dbe631d1292be363f4121217d66e2d7fd0f (patch)
treea75355b2c870c352a8f977a72d29376674d17553 /src/arch/wasm/CodeGen.zig
parente20976b7f209a768cb55a37e6a58ed177d76013e (diff)
downloadzig-67d27dbe631d1292be363f4121217d66e2d7fd0f.tar.gz
zig-67d27dbe631d1292be363f4121217d66e2d7fd0f.zip
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
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
-rw-r--r--src/arch/wasm/CodeGen.zig11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 799c4a40a2..c2d2ffd8e4 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -881,6 +881,9 @@ fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {
const value = func.currentBranch().values.getPtr(ref) orelse return;
if (value.* != .local) return;
log.debug("Decreasing reference for ref: %{?d}\n", .{Air.refToIndex(ref)});
+ if (value.local.value < func.arg_index) {
+ return; // function arguments can never be re-used
+ }
value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer
if (value.local.references == 0) {
value.free(func);
@@ -4021,7 +4024,13 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
return func.fail("todo Wasm intcast for bitsize > 128", .{});
}
- const result = try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
+ const op_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
+ const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
+ const result = if (op_bits == wanted_bits)
+ func.reuseOperand(ty_op.operand, operand)
+ else
+ try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
+
func.finishAir(inst, result, &.{});
}