authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-29 14:23:51+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-31 18:04:33+02:00
log7e10cf4fbe2a8a379564941be9953ce157d483cc
tree8fa09988695d6c2ae090923ddc20b38025121fba
parente36cc0ce8f4c0ec7c1398149c5fa30f15d8dae9f
signaturelock-open Commit is signed but in an unrecognized format.

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.

1 files changed, 12 insertions(+), 3 deletions(-)

src/arch/wasm/CodeGen.zig+12-3
...@@ -5707,6 +5707,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5707,6 +5707,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5707 const lhs = try func.resolveInst(extra.lhs);5707 const lhs = try func.resolveInst(extra.lhs);
5708 const rhs = try func.resolveInst(extra.rhs);5708 const rhs = try func.resolveInst(extra.rhs);
5709 const lhs_ty = func.air.typeOf(extra.lhs);5709 const lhs_ty = func.air.typeOf(extra.lhs);
5710 const rhs_ty = func.air.typeOf(extra.rhs);
57105711
5711 if (lhs_ty.zigTypeTag() == .Vector) {5712 if (lhs_ty.zigTypeTag() == .Vector) {
5712 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});5713 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
...@@ -5718,7 +5719,15 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5718,7 +5719,15 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5718 return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits});5719 return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits});
5719 };5720 };
57205721
5721 var shl = try (try func.binOp(lhs, rhs, lhs_ty, .shl)).toLocal(func, lhs_ty);5722 // Ensure rhs is coerced to lhs as they must have the same WebAssembly types
5723 // before we can perform any binary operation.
5724 const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(func.target).bits).?;
5725 const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: {
5726 const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty);
5727 break :blk try rhs_casted.toLocal(func, lhs_ty);
5728 } else rhs;
5729
5730 var shl = try (try func.binOp(lhs, rhs_final, lhs_ty, .shl)).toLocal(func, lhs_ty);
5722 defer shl.free(func);5731 defer shl.free(func);
5723 var result = if (wasm_bits != int_info.bits) blk: {5732 var result = if (wasm_bits != int_info.bits) blk: {
5724 break :blk try (try func.wrapOperand(shl, lhs_ty)).toLocal(func, lhs_ty);5733 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 {...@@ -5729,11 +5738,11 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5729 // emit lhs to stack to we can keep 'wrapped' on the stack also5738 // emit lhs to stack to we can keep 'wrapped' on the stack also
5730 try func.emitWValue(lhs);5739 try func.emitWValue(lhs);
5731 const abs = try func.signAbsValue(shl, lhs_ty);5740 const abs = try func.signAbsValue(shl, lhs_ty);
5732 const wrapped = try func.wrapBinOp(abs, rhs, lhs_ty, .shr);5741 const wrapped = try func.wrapBinOp(abs, rhs_final, lhs_ty, .shr);
5733 break :blk try func.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq);5742 break :blk try func.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq);
5734 } else blk: {5743 } else blk: {
5735 try func.emitWValue(lhs);5744 try func.emitWValue(lhs);
5736 const shr = try func.binOp(result, rhs, lhs_ty, .shr);5745 const shr = try func.binOp(result, rhs_final, lhs_ty, .shr);
5737 break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq);5746 break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq);
5738 };5747 };
5739 var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1));5748 var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1));