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.
This commit is contained in:
Luuk de Gram 2023-05-18 18:08:10 +02:00
parent 4a33aa922e
commit ca870aa005
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
2 changed files with 22 additions and 5 deletions

View File

@ -1814,10 +1814,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.subwrap => func.airWrapBinOp(inst, .sub),
.mul => func.airBinOp(inst, .mul),
.mulwrap => func.airWrapBinOp(inst, .mul),
.div_float,
.div_exact,
.div_trunc,
=> func.airDiv(inst),
.div_float, .div_exact => func.airDiv(inst),
.div_trunc => func.airDivTrunc(inst),
.div_floor => func.airDivFloor(inst),
.bit_and => func.airBinOp(inst, .@"and"),
.bit_or => func.airBinOp(inst, .@"or"),
@ -6138,6 +6136,26 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
}
fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const ty = func.air.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
const div_result = if (ty.isSignedInt())
try func.divSigned(lhs, rhs, ty)
else
try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
if (ty.isAnyFloat()) {
const trunc_result = try (try func.floatOp(.trunc, ty, &.{div_result})).toLocal(func, ty);
return func.finishAir(inst, trunc_result, &.{ bin_op.lhs, bin_op.rhs });
}
return func.finishAir(inst, div_result, &.{ bin_op.lhs, bin_op.rhs });
}
fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;

View File

@ -486,7 +486,6 @@ fn testDivision() !void {
}
test "division half-precision floats" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO