diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-05-29 14:23:51 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-05-31 18:04:33 +0200 |
| commit | 7e10cf4fbe2a8a379564941be9953ce157d483cc (patch) | |
| tree | 8fa09988695d6c2ae090923ddc20b38025121fba | |
| parent | e36cc0ce8f4c0ec7c1398149c5fa30f15d8dae9f (diff) | |
| download | zig-7e10cf4fbe2a8a379564941be9953ce157d483cc.tar.gz zig-7e10cf4fbe2a8a379564941be9953ce157d483cc.zip | |
wasm: `shl_with_overflow` ensure rhs is coerced
Both operands must have the same Wasm type before we are allowed
to perform any binary operation on the values.
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 34a3c68102..2072ff1506 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -5707,6 +5707,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const lhs = try func.resolveInst(extra.lhs); const rhs = try func.resolveInst(extra.rhs); const lhs_ty = func.air.typeOf(extra.lhs); + const rhs_ty = func.air.typeOf(extra.rhs); if (lhs_ty.zigTypeTag() == .Vector) { return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); @@ -5718,7 +5719,15 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits}); }; - var shl = try (try func.binOp(lhs, rhs, lhs_ty, .shl)).toLocal(func, lhs_ty); + // Ensure rhs is coerced to lhs as they must have the same WebAssembly types + // before we can perform any binary operation. + const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(func.target).bits).?; + const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: { + const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty); + break :blk try rhs_casted.toLocal(func, lhs_ty); + } else rhs; + + var shl = try (try func.binOp(lhs, rhs_final, lhs_ty, .shl)).toLocal(func, lhs_ty); defer shl.free(func); var result = if (wasm_bits != int_info.bits) blk: { break :blk try (try func.wrapOperand(shl, lhs_ty)).toLocal(func, lhs_ty); @@ -5729,11 +5738,11 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { // emit lhs to stack to we can keep 'wrapped' on the stack also try func.emitWValue(lhs); const abs = try func.signAbsValue(shl, lhs_ty); - const wrapped = try func.wrapBinOp(abs, rhs, lhs_ty, .shr); + const wrapped = try func.wrapBinOp(abs, rhs_final, lhs_ty, .shr); break :blk try func.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq); } else blk: { try func.emitWValue(lhs); - const shr = try func.binOp(result, rhs, lhs_ty, .shr); + const shr = try func.binOp(result, rhs_final, lhs_ty, .shr); break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq); }; var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1)); |
