Commit eac97a97 authored by Yahan Lu's avatar Yahan Lu Committed by Commit Bot

[riscv64] Fix NaN related issue

Optimize FPUCanonicalizeNaN
Float Round reutrn qNan when input is Nan
FMaxMin return qNan with Nan inputs

Change-Id: I7568be3d27d030e49f292a956b3084b54bdf8577
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2814725
Commit-Queue: Brice Dobry <brice.dobry@futurewei.com>
Reviewed-by: 's avatarBrice Dobry <brice.dobry@futurewei.com>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74006}
parent b079e0b3
......@@ -1869,6 +1869,28 @@ void TurboAssembler::RoundHelper(FPURegister dst, FPURegister src,
fmv_s(dst, src);
}
}
{
Label not_NaN;
UseScratchRegisterScope temps2(this);
Register scratch = temps2.Acquire();
// According to the wasm spec
// (https://webassembly.github.io/spec/core/exec/numerics.html#aux-nans)
// if input is canonical NaN, then output is canonical NaN, and if input is
// any other NaN, then output is any NaN with most significant bit of
// payload is 1. In RISC-V, feq_d will set scratch to 0 if src is a NaN. If
// src is not a NaN, branch to the label and do nothing, but if it is,
// fmin_d will set dst to the canonical NaN.
if (std::is_same<F, double>::value) {
feq_d(scratch, src, src);
bnez(scratch, &not_NaN);
fmin_d(dst, src, src);
} else {
feq_s(scratch, src, src);
bnez(scratch, &not_NaN);
fmin_s(dst, src, src);
}
bind(&not_NaN);
}
// If real exponent (i.e., t6 - kFloatExponentBias) is greater than
// kFloat32MantissaBits, it means the floating-point value has no fractional
......@@ -3372,16 +3394,10 @@ void MacroAssembler::PopStackHandler() {
void TurboAssembler::FPUCanonicalizeNaN(const DoubleRegister dst,
const DoubleRegister src) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
Label NotNaN;
fmv_d(dst, src);
feq_d(scratch, src, src);
bne(scratch, zero_reg, &NotNaN);
RV_li(scratch, 0x7ff8000000000000ULL); // This is the canonical NaN
fmv_d_x(dst, scratch);
bind(&NotNaN);
// Subtracting 0.0 preserves all inputs except for signalling NaNs, which
// become quiet NaNs. We use fsub rather than fadd because fsub preserves -0.0
// inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 = -0.0.
fsub_d(dst, src, kDoubleRegZero);
}
void TurboAssembler::MovFromFloatResult(const DoubleRegister dst) {
......
......@@ -1066,7 +1066,7 @@ T Simulator::FMaxMinHelper(T a, T b, MaxMinKind kind) {
T result = 0;
if (std::isnan(a) && std::isnan(b)) {
result = a;
result = std::numeric_limits<float>::quiet_NaN();
} else if (std::isnan(a)) {
result = b;
} else if (std::isnan(b)) {
......
......@@ -104,19 +104,6 @@
'proposals/multi-value/conversions': [SKIP],
'proposals/reference-types/conversions': [SKIP],
'f32': [SKIP],
'f64': [SKIP],
'proposals/multi-value/f64': [SKIP],
'proposals/JS-BigInt-integration/f64': [SKIP],
'proposals/JS-BigInt-integration/f32': [SKIP],
'proposals/bulk-memory-operations/f32': [SKIP],
'proposals/bulk-memory-operations/f64': [SKIP],
'proposals/js-types/f32': [SKIP],
'proposals/js-types/f64': [SKIP],
'proposals/multi-value/f32': [SKIP],
'proposals/reference-types/f32': [SKIP],
'proposals/reference-types/f64': [SKIP],
# the following all fail w/ symptons captured in issue #166
'float_exprs': [SKIP],
'proposals/tail-call/conversions': [SKIP],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment