commit b3c498454b6006f64aecf96b181720c524d76ae8 (tree)
parent f7f0b9d28f2d68f40fcfe79f85b4cc37ea9ba2e8
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date: Fri, 2 Jan 2026 13:37:58 +0000
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.
Diffstat:
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git 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) {