From b3c498454b6006f64aecf96b181720c524d76ae8 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Fri, 2 Jan 2026 13:37:58 +0000 Subject: [PATCH] codegen.wasm: fix 64-bit saturating shl Previously, 64-bit '<<|' operations were emitting 64-bit shifts with one 64-bit operand and one 32-bit operand, which is illegal. Instead, as in the lowering for regular shifts, we need to cast the RHS in this case. --- src/codegen/wasm/CodeGen.zig | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/codegen/wasm/CodeGen.zig b/src/codegen/wasm/CodeGen.zig index 5d78b46702..5799ee614d 100644 --- a/src/codegen/wasm/CodeGen.zig +++ b/src/codegen/wasm/CodeGen.zig @@ -6973,9 +6973,20 @@ fn airShlSat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { return cg.fail("TODO: Saturating shifting left for integers with bitsize '{d}'", .{int_info.bits}); } - const lhs = try cg.resolveInst(bin_op.lhs); - const rhs = try cg.resolveInst(bin_op.rhs); const wasm_bits = toWasmBits(int_info.bits).?; + + const lhs = try cg.resolveInst(bin_op.lhs); + const rhs = rhs: { + const rhs = try cg.resolveInst(bin_op.rhs); + const rhs_ty = cg.typeOf(bin_op.rhs); + // The type of `rhs` is the log2 int of the type of `lhs`, but WASM wants the lhs and rhs types to match. + if (toWasmBits(@intCast(rhs_ty.bitSize(zcu))).? == wasm_bits) { + break :rhs rhs; // the WASM types match, so no cast necessary + } + const casted = try cg.intcast(rhs, rhs_ty, ty); + break :rhs try casted.toLocal(cg, ty); + }; + const result = try cg.allocLocal(ty); if (wasm_bits == int_info.bits) {