AIX: workaround the aix FP glibc bug

Due to a bug on AIX, some of the glibc FP functions do not
preserve the sign bit when a negative input is passed by
value and the output is rounded to 0:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97086

This CL continue the fixes previously added here:
https://crrev.com/c/2468618

Change-Id: I2afa1f67ac1d29ec0606de6d6ebcf05be0664b8d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3282308
Reviewed-by: Zhi An Ng <zhin@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#77915}
This commit is contained in:
Milad Fa 2021-11-15 13:59:31 -05:00 committed by V8 LUCI CQ
parent 6c6a602451
commit 85a85cf092
3 changed files with 40 additions and 7 deletions

View File

@ -56,7 +56,12 @@ void f32_ceil_wrapper(Address data) {
}
void f32_nearest_int_wrapper(Address data) {
WriteUnalignedValue<float>(data, nearbyintf(ReadUnalignedValue<float>(data)));
float input = ReadUnalignedValue<float>(data);
float value = nearbyintf(input);
#if V8_OS_AIX
value = FpOpWorkaround<float>(input, value);
#endif
WriteUnalignedValue<float>(data, value);
}
void f64_trunc_wrapper(Address data) {
@ -72,8 +77,12 @@ void f64_ceil_wrapper(Address data) {
}
void f64_nearest_int_wrapper(Address data) {
WriteUnalignedValue<double>(data,
nearbyint(ReadUnalignedValue<double>(data)));
double input = ReadUnalignedValue<double>(data);
double value = nearbyint(input);
#if V8_OS_AIX
value = FpOpWorkaround<double>(input, value);
#endif
WriteUnalignedValue<double>(data, value);
}
void int64_to_float32_wrapper(Address data) {

View File

@ -3247,7 +3247,13 @@ WASM_EXEC_TEST(F32NearestInt) {
WasmRunner<float, float> r(execution_tier);
BUILD(r, WASM_F32_NEARESTINT(WASM_LOCAL_GET(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyintf(i), r.Call(i)); }
FOR_FLOAT32_INPUTS(i) {
float value = nearbyintf(i);
#if V8_OS_AIX
value = FpOpWorkaround<float>(i, value);
#endif
CHECK_FLOAT_EQ(value, r.Call(i));
}
}
WASM_EXEC_TEST(F64Floor) {
@ -3275,7 +3281,13 @@ WASM_EXEC_TEST(F64NearestInt) {
WasmRunner<double, double> r(execution_tier);
BUILD(r, WASM_F64_NEARESTINT(WASM_LOCAL_GET(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(i), r.Call(i)); }
FOR_FLOAT64_INPUTS(i) {
double value = nearbyint(i);
#if V8_OS_AIX
value = FpOpWorkaround<double>(i, value);
#endif
CHECK_DOUBLE_EQ(value, r.Call(i));
}
}
WASM_EXEC_TEST(F32Min) {

View File

@ -417,7 +417,13 @@ float ExecuteF32Floor(float a, TrapReason* trap) { return floorf(a); }
float ExecuteF32Trunc(float a, TrapReason* trap) { return truncf(a); }
float ExecuteF32NearestInt(float a, TrapReason* trap) { return nearbyintf(a); }
float ExecuteF32NearestInt(float a, TrapReason* trap) {
float value = nearbyintf(a);
#if V8_OS_AIX
value = FpOpWorkaround<float>(a, value);
#endif
return value;
}
float ExecuteF32Sqrt(float a, TrapReason* trap) {
float result = sqrtf(a);
@ -438,7 +444,13 @@ double ExecuteF64Floor(double a, TrapReason* trap) { return floor(a); }
double ExecuteF64Trunc(double a, TrapReason* trap) { return trunc(a); }
double ExecuteF64NearestInt(double a, TrapReason* trap) { return nearbyint(a); }
double ExecuteF64NearestInt(double a, TrapReason* trap) {
double value = nearbyint(a);
#if V8_OS_AIX
value = FpOpWorkaround<double>(a, value);
#endif
return value;
}
double ExecuteF64Sqrt(double a, TrapReason* trap) { return sqrt(a); }