authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-18 18:08:10+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-19 20:22:47+02:00
logca870aa00504accd49e7f1d2fceed1e4b8d21100
treeb4c9d80002a7017ab61bfd91dde3239850e5b025
parent4a33aa922e90b76248b259a89be86966eb4898c2
signaturelock-open Commit is signed but in an unrecognized format.

wasm: fix `div_trunc` for floats

For floats we would previously only do the division, but not the truncation for floats. This would result in incorrect values being returned.

2 files changed, 22 insertions(+), 5 deletions(-)

src/arch/wasm/CodeGen.zig+22-4
......@@ -1814,10 +1814,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
18141814 .subwrap => func.airWrapBinOp(inst, .sub),
18151815 .mul => func.airBinOp(inst, .mul),
18161816 .mulwrap => func.airWrapBinOp(inst, .mul),
1817 .div_float,
1818 .div_exact,
1819 .div_trunc,
1820 => func.airDiv(inst),
1817 .div_float, .div_exact => func.airDiv(inst),
1818 .div_trunc => func.airDivTrunc(inst),
18211819 .div_floor => func.airDivFloor(inst),
18221820 .bit_and => func.airBinOp(inst, .@"and"),
18231821 .bit_or => func.airBinOp(inst, .@"or"),
......@@ -6138,6 +6136,26 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61386136 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
61396137}
61406138
6139fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6140 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
6141
6142 const ty = func.air.typeOfIndex(inst);
6143 const lhs = try func.resolveInst(bin_op.lhs);
6144 const rhs = try func.resolveInst(bin_op.rhs);
6145
6146 const div_result = if (ty.isSignedInt())
6147 try func.divSigned(lhs, rhs, ty)
6148 else
6149 try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
6150
6151 if (ty.isAnyFloat()) {
6152 const trunc_result = try (try func.floatOp(.trunc, ty, &.{div_result})).toLocal(func, ty);
6153 return func.finishAir(inst, trunc_result, &.{ bin_op.lhs, bin_op.rhs });
6154 }
6155
6156 return func.finishAir(inst, div_result, &.{ bin_op.lhs, bin_op.rhs });
6157}
6158
61416159fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61426160 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
61436161
test/behavior/math.zig-1
......@@ -486,7 +486,6 @@ fn testDivision() !void {
486486}
487487
488488test "division half-precision floats" {
489 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
490489 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
491490 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
492491 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO