Commit 2f44cf1f authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

AIX: workaround the aix FP glibc bug

First CL with initial changes:
https://crrev.com/c/2468618

This CL adds the same set to the wasm interpreter.
We also need to make sure "negation" as well as
"std::abs" are excluded from this fix as they can reverse
the sign bit intentionally.

Change-Id: I115649f55b5290d2529dda3d5592feaff3363b76
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2485246Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#70632}
parent 49659a0e
...@@ -414,6 +414,14 @@ bool IsExtreme(float x) { ...@@ -414,6 +414,14 @@ bool IsExtreme(float x) {
(abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold); (abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold);
} }
#if V8_OS_AIX
template <typename T>
bool MightReverseSign(T float_op) {
return float_op == static_cast<T>(Negate) ||
float_op == static_cast<T>(std::abs);
}
#endif
WASM_SIMD_TEST(S128Globals) { WASM_SIMD_TEST(S128Globals) {
WasmRunner<int32_t> r(execution_tier, lower_simd); WasmRunner<int32_t> r(execution_tier, lower_simd);
// Set up a global to hold input and output vectors. // Set up a global to hold input and output vectors.
...@@ -587,6 +595,7 @@ void RunF32x4UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd, ...@@ -587,6 +595,7 @@ void RunF32x4UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
if (!exact && IsExtreme(x)) continue; if (!exact && IsExtreme(x)) continue;
float expected = expected_op(x); float expected = expected_op(x);
#if V8_OS_AIX #if V8_OS_AIX
if (!MightReverseSign<FloatUnOp>(expected_op))
expected = FpOpWorkaround<float>(x, expected); expected = FpOpWorkaround<float>(x, expected);
#endif #endif
if (!PlatformCanRepresent(expected)) continue; if (!PlatformCanRepresent(expected)) continue;
...@@ -1180,6 +1189,7 @@ void RunF64x2UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd, ...@@ -1180,6 +1189,7 @@ void RunF64x2UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
if (!exact && IsExtreme(x)) continue; if (!exact && IsExtreme(x)) continue;
double expected = expected_op(x); double expected = expected_op(x);
#if V8_OS_AIX #if V8_OS_AIX
if (!MightReverseSign<DoubleUnOp>(expected_op))
expected = FpOpWorkaround<double>(x, expected); expected = FpOpWorkaround<double>(x, expected);
#endif #endif
if (!PlatformCanRepresent(expected)) continue; if (!PlatformCanRepresent(expected)) continue;
......
...@@ -2085,6 +2085,14 @@ class WasmInterpreterInternals { ...@@ -2085,6 +2085,14 @@ class WasmInterpreterInternals {
return true; return true;
} }
template <typename T, T (*float_round_op)(T)>
T AixFpOpWorkaround(T input) {
#if V8_OS_AIX
return FpOpWorkaround<T>(input, float_round_op(input));
#else
return float_round_op(input);
#endif
}
bool ExecuteSimdOp(WasmOpcode opcode, Decoder* decoder, InterpreterCode* code, bool ExecuteSimdOp(WasmOpcode opcode, Decoder* decoder, InterpreterCode* code,
pc_t pc, int* const len) { pc_t pc, int* const len) {
switch (opcode) { switch (opcode) {
...@@ -2251,19 +2259,27 @@ class WasmInterpreterInternals { ...@@ -2251,19 +2259,27 @@ class WasmInterpreterInternals {
UNOP_CASE(F64x2Abs, f64x2, float2, 2, std::abs(a)) UNOP_CASE(F64x2Abs, f64x2, float2, 2, std::abs(a))
UNOP_CASE(F64x2Neg, f64x2, float2, 2, -a) UNOP_CASE(F64x2Neg, f64x2, float2, 2, -a)
UNOP_CASE(F64x2Sqrt, f64x2, float2, 2, std::sqrt(a)) UNOP_CASE(F64x2Sqrt, f64x2, float2, 2, std::sqrt(a))
UNOP_CASE(F64x2Ceil, f64x2, float2, 2, ceil(a)) UNOP_CASE(F64x2Ceil, f64x2, float2, 2,
UNOP_CASE(F64x2Floor, f64x2, float2, 2, floor(a)) (AixFpOpWorkaround<double, &ceil>(a)))
UNOP_CASE(F64x2Trunc, f64x2, float2, 2, trunc(a)) UNOP_CASE(F64x2Floor, f64x2, float2, 2,
UNOP_CASE(F64x2NearestInt, f64x2, float2, 2, nearbyint(a)) (AixFpOpWorkaround<double, &floor>(a)))
UNOP_CASE(F64x2Trunc, f64x2, float2, 2,
(AixFpOpWorkaround<double, &trunc>(a)))
UNOP_CASE(F64x2NearestInt, f64x2, float2, 2,
(AixFpOpWorkaround<double, &nearbyint>(a)))
UNOP_CASE(F32x4Abs, f32x4, float4, 4, std::abs(a)) UNOP_CASE(F32x4Abs, f32x4, float4, 4, std::abs(a))
UNOP_CASE(F32x4Neg, f32x4, float4, 4, -a) UNOP_CASE(F32x4Neg, f32x4, float4, 4, -a)
UNOP_CASE(F32x4Sqrt, f32x4, float4, 4, std::sqrt(a)) UNOP_CASE(F32x4Sqrt, f32x4, float4, 4, std::sqrt(a))
UNOP_CASE(F32x4RecipApprox, f32x4, float4, 4, base::Recip(a)) UNOP_CASE(F32x4RecipApprox, f32x4, float4, 4, base::Recip(a))
UNOP_CASE(F32x4RecipSqrtApprox, f32x4, float4, 4, base::RecipSqrt(a)) UNOP_CASE(F32x4RecipSqrtApprox, f32x4, float4, 4, base::RecipSqrt(a))
UNOP_CASE(F32x4Ceil, f32x4, float4, 4, ceilf(a)) UNOP_CASE(F32x4Ceil, f32x4, float4, 4,
UNOP_CASE(F32x4Floor, f32x4, float4, 4, floorf(a)) (AixFpOpWorkaround<float, &ceilf>(a)))
UNOP_CASE(F32x4Trunc, f32x4, float4, 4, truncf(a)) UNOP_CASE(F32x4Floor, f32x4, float4, 4,
UNOP_CASE(F32x4NearestInt, f32x4, float4, 4, nearbyintf(a)) (AixFpOpWorkaround<float, &floorf>(a)))
UNOP_CASE(F32x4Trunc, f32x4, float4, 4,
(AixFpOpWorkaround<float, &truncf>(a)))
UNOP_CASE(F32x4NearestInt, f32x4, float4, 4,
(AixFpOpWorkaround<float, &nearbyintf>(a)))
UNOP_CASE(I64x2Neg, i64x2, int2, 2, base::NegateWithWraparound(a)) UNOP_CASE(I64x2Neg, i64x2, int2, 2, base::NegateWithWraparound(a))
UNOP_CASE(I32x4Neg, i32x4, int4, 4, base::NegateWithWraparound(a)) UNOP_CASE(I32x4Neg, i32x4, int4, 4, base::NegateWithWraparound(a))
UNOP_CASE(I32x4Abs, i32x4, int4, 4, std::abs(a)) UNOP_CASE(I32x4Abs, i32x4, int4, 4, std::abs(a))
......
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