Adds flag for which sin/cos implementation to use
My plan is to add a finch flag to the chrome side. It'll be a kill switch, but given the history with changing the implementation, I want to make sure we have the ability to switch back. Bug=v8:13477 Change-Id: I1559e10d134bd78699b1119be26934570c6e5241 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4108811 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Scott Violet <sky@chromium.org> Cr-Commit-Position: refs/heads/main@{#84874}
This commit is contained in:
parent
37e5a28add
commit
ef680d1b01
@ -107,10 +107,8 @@ namespace {
|
||||
int32_t __ieee754_rem_pio2(double x, double* y) V8_WARN_UNUSED_RESULT;
|
||||
int __kernel_rem_pio2(double* x, double* y, int e0, int nx, int prec,
|
||||
const int32_t* ipio2) V8_WARN_UNUSED_RESULT;
|
||||
#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
double __kernel_cos(double x, double y) V8_WARN_UNUSED_RESULT;
|
||||
double __kernel_sin(double x, double y, int iy) V8_WARN_UNUSED_RESULT;
|
||||
#endif
|
||||
|
||||
/* __ieee754_rem_pio2(x,y)
|
||||
*
|
||||
@ -271,7 +269,6 @@ int32_t __ieee754_rem_pio2(double x, double *y) {
|
||||
return n;
|
||||
}
|
||||
|
||||
#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
/* __kernel_cos( x, y )
|
||||
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
|
||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
@ -337,7 +334,6 @@ V8_INLINE double __kernel_cos(double x, double y) {
|
||||
return a - (iz - (z * r - x * y));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
|
||||
* double x[],y[]; int e0,nx,prec; int ipio2[];
|
||||
@ -647,7 +643,6 @@ recompute:
|
||||
return n & 7;
|
||||
}
|
||||
|
||||
#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
/* __kernel_sin( x, y, iy)
|
||||
* kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
|
||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
@ -701,7 +696,6 @@ V8_INLINE double __kernel_sin(double x, double y, int iy) {
|
||||
return x - ((z * (half * y - v * r) - y) - v * S1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* __kernel_tan( x, y, k )
|
||||
* kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
|
||||
@ -1324,7 +1318,6 @@ double atan2(double y, double x) {
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
/* cos(x)
|
||||
* Return cosine function of x.
|
||||
*
|
||||
@ -1355,7 +1348,11 @@ double atan2(double y, double x) {
|
||||
* Accuracy:
|
||||
* TRIG(x) returns trig(x) nearly rounded
|
||||
*/
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
double fdlibm_cos(double x) {
|
||||
#else
|
||||
double cos(double x) {
|
||||
#endif
|
||||
double y[2], z = 0.0;
|
||||
int32_t n, ix;
|
||||
|
||||
@ -1384,7 +1381,6 @@ double cos(double x) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* exp(x)
|
||||
* Returns the exponential of x.
|
||||
@ -2418,7 +2414,6 @@ double cbrt(double x) {
|
||||
return (t);
|
||||
}
|
||||
|
||||
#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
/* sin(x)
|
||||
* Return sine function of x.
|
||||
*
|
||||
@ -2449,7 +2444,11 @@ double cbrt(double x) {
|
||||
* Accuracy:
|
||||
* TRIG(x) returns trig(x) nearly rounded
|
||||
*/
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
double fdlibm_sin(double x) {
|
||||
#else
|
||||
double sin(double x) {
|
||||
#endif
|
||||
double y[2], z = 0.0;
|
||||
int32_t n, ix;
|
||||
|
||||
@ -2478,7 +2477,6 @@ double sin(double x) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tan(x)
|
||||
* Return tangent function of x.
|
||||
@ -3026,12 +3024,8 @@ double tanh(double x) {
|
||||
#undef SET_LOW_WORD
|
||||
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && defined(BUILDING_V8_BASE_SHARED)
|
||||
double sin(double x) {
|
||||
return glibc_sin(x);
|
||||
}
|
||||
double cos(double x) {
|
||||
return glibc_cos(x);
|
||||
}
|
||||
double libm_sin(double x) { return glibc_sin(x); }
|
||||
double libm_cos(double x) { return glibc_cos(x); }
|
||||
#endif
|
||||
|
||||
} // namespace ieee754
|
||||
|
@ -37,15 +37,23 @@ V8_BASE_EXPORT double atan(double x);
|
||||
// the two arguments to determine the quadrant of the result.
|
||||
V8_BASE_EXPORT double atan2(double y, double x);
|
||||
|
||||
// Returns the cosine of |x|, where |x| is given in radians.
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \
|
||||
!defined(BUILDING_V8_BASE_SHARED) && \
|
||||
!defined(USING_V8_BASE_SHARED)
|
||||
inline double cos(double x) {
|
||||
return glibc_cos(x);
|
||||
}
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
// To ensure there aren't problems with libm's sin/cos, both implementations
|
||||
// are shipped. The plan is to transition to libm once we ensure there are no
|
||||
// compatibility or performance issues.
|
||||
V8_BASE_EXPORT double fdlibm_sin(double x);
|
||||
V8_BASE_EXPORT double fdlibm_cos(double x);
|
||||
|
||||
#if !defined(BUILDING_V8_BASE_SHARED) && !defined(USING_V8_BASE_SHARED)
|
||||
inline double libm_sin(double x) { return glibc_sin(x); }
|
||||
inline double libm_cos(double x) { return glibc_cos(x); }
|
||||
#else
|
||||
V8_BASE_EXPORT double libm_sin(double x);
|
||||
V8_BASE_EXPORT double libm_cos(double x);
|
||||
#endif
|
||||
#else
|
||||
V8_BASE_EXPORT double cos(double x);
|
||||
V8_BASE_EXPORT double sin(double x);
|
||||
#endif
|
||||
|
||||
// Returns the base-e exponential of |x|.
|
||||
@ -80,17 +88,6 @@ V8_BASE_EXPORT double expm1(double x);
|
||||
// behaviour is preserved for compatibility reasons.
|
||||
V8_BASE_EXPORT double pow(double x, double y);
|
||||
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \
|
||||
!defined(BUILDING_V8_BASE_SHARED) && \
|
||||
!defined(USING_V8_BASE_SHARED)
|
||||
inline double sin(double x) {
|
||||
return glibc_sin(x);
|
||||
}
|
||||
#else
|
||||
// Returns the sine of |x|, where |x| is given in radians.
|
||||
V8_BASE_EXPORT double sin(double x);
|
||||
#endif
|
||||
|
||||
// Returns the tangent of |x|, where |x| is given in radians.
|
||||
V8_BASE_EXPORT double tan(double x);
|
||||
|
||||
|
@ -359,4 +359,17 @@ Builtin ExampleBuiltinForTorqueFunctionPointerType(
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
// Helper while transitioning some functions to libm.
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
#define SIN_IMPL(X) \
|
||||
v8_flags.use_libm_trig_functions ? base::ieee754::libm_sin(X) \
|
||||
: base::ieee754::fdlibm_sin(X)
|
||||
#define COS_IMPL(X) \
|
||||
v8_flags.use_libm_trig_functions ? base::ieee754::libm_cos(X) \
|
||||
: base::ieee754::fdlibm_cos(X)
|
||||
#else
|
||||
#define SIN_IMPL(X) base::ieee754::sin(X)
|
||||
#define COS_IMPL(X) base::ieee754::cos(X)
|
||||
#endif
|
||||
|
||||
#endif // V8_BUILTINS_BUILTINS_H_
|
||||
|
@ -880,8 +880,6 @@ FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan2_function, base::ieee754::atan2,
|
||||
BUILTIN_FP_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_cbrt_function, base::ieee754::cbrt,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_cos_function, base::ieee754::cos,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_cosh_function, base::ieee754::cosh,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_exp_function, base::ieee754::exp,
|
||||
@ -896,8 +894,6 @@ FUNCTION_REFERENCE_WITH_TYPE(ieee754_log10_function, base::ieee754::log10,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_log2_function, base::ieee754::log2,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_sin_function, base::ieee754::sin,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_sinh_function, base::ieee754::sinh,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_tan_function, base::ieee754::tan,
|
||||
@ -907,6 +903,32 @@ FUNCTION_REFERENCE_WITH_TYPE(ieee754_tanh_function, base::ieee754::tanh,
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_pow_function, base::ieee754::pow,
|
||||
BUILTIN_FP_FP_CALL)
|
||||
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
ExternalReference ExternalReference::ieee754_sin_function() {
|
||||
static_assert(
|
||||
IsValidExternalReferenceType<decltype(&base::ieee754::libm_sin)>::value);
|
||||
static_assert(IsValidExternalReferenceType<
|
||||
decltype(&base::ieee754::fdlibm_sin)>::value);
|
||||
auto* f = v8_flags.use_libm_trig_functions ? base::ieee754::libm_sin
|
||||
: base::ieee754::fdlibm_sin;
|
||||
return ExternalReference(Redirect(FUNCTION_ADDR(f), BUILTIN_FP_CALL));
|
||||
}
|
||||
ExternalReference ExternalReference::ieee754_cos_function() {
|
||||
static_assert(
|
||||
IsValidExternalReferenceType<decltype(&base::ieee754::libm_cos)>::value);
|
||||
static_assert(IsValidExternalReferenceType<
|
||||
decltype(&base::ieee754::fdlibm_cos)>::value);
|
||||
auto* f = v8_flags.use_libm_trig_functions ? base::ieee754::libm_cos
|
||||
: base::ieee754::fdlibm_cos;
|
||||
return ExternalReference(Redirect(FUNCTION_ADDR(f), BUILTIN_FP_CALL));
|
||||
}
|
||||
#else
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_sin_function, base::ieee754::sin,
|
||||
BUILTIN_FP_CALL)
|
||||
FUNCTION_REFERENCE_WITH_TYPE(ieee754_cos_function, base::ieee754::cos,
|
||||
BUILTIN_FP_CALL)
|
||||
#endif
|
||||
|
||||
void* libc_memchr(void* string, int character, size_t search_length) {
|
||||
return memchr(string, character, search_length);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/base/ieee754.h"
|
||||
#include "src/base/logging.h"
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/compiler/diamond.h"
|
||||
#include "src/compiler/graph.h"
|
||||
#include "src/compiler/js-operator.h"
|
||||
@ -771,7 +772,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
case IrOpcode::kFloat64Cos: {
|
||||
Float64Matcher m(node->InputAt(0));
|
||||
if (m.HasResolvedValue())
|
||||
return ReplaceFloat64(base::ieee754::cos(m.ResolvedValue()));
|
||||
return ReplaceFloat64(COS_IMPL(m.ResolvedValue()));
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kFloat64Cosh: {
|
||||
@ -836,7 +837,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
case IrOpcode::kFloat64Sin: {
|
||||
Float64Matcher m(node->InputAt(0));
|
||||
if (m.HasResolvedValue())
|
||||
return ReplaceFloat64(base::ieee754::sin(m.ResolvedValue()));
|
||||
return ReplaceFloat64(SIN_IMPL(m.ResolvedValue()));
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kFloat64Sinh: {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/base/template-utils.h"
|
||||
#include "src/base/vector.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/compiler/backend/instruction.h"
|
||||
#include "src/compiler/machine-operator-reducer.h"
|
||||
@ -250,9 +251,9 @@ class MachineOptimizationReducer : public Next {
|
||||
case FloatUnaryOp::Kind::kExpm1:
|
||||
return Asm().Float32Constant(base::ieee754::expm1(k));
|
||||
case FloatUnaryOp::Kind::kSin:
|
||||
return Asm().Float32Constant(base::ieee754::sin(k));
|
||||
return Asm().Float32Constant(SIN_IMPL(k));
|
||||
case FloatUnaryOp::Kind::kCos:
|
||||
return Asm().Float32Constant(base::ieee754::cos(k));
|
||||
return Asm().Float32Constant(COS_IMPL(k));
|
||||
case FloatUnaryOp::Kind::kSinh:
|
||||
return Asm().Float32Constant(base::ieee754::sinh(k));
|
||||
case FloatUnaryOp::Kind::kCosh:
|
||||
@ -314,9 +315,9 @@ class MachineOptimizationReducer : public Next {
|
||||
case FloatUnaryOp::Kind::kExpm1:
|
||||
return Asm().Float64Constant(base::ieee754::expm1(k));
|
||||
case FloatUnaryOp::Kind::kSin:
|
||||
return Asm().Float64Constant(base::ieee754::sin(k));
|
||||
return Asm().Float64Constant(SIN_IMPL(k));
|
||||
case FloatUnaryOp::Kind::kCos:
|
||||
return Asm().Float64Constant(base::ieee754::cos(k));
|
||||
return Asm().Float64Constant(COS_IMPL(k));
|
||||
case FloatUnaryOp::Kind::kSinh:
|
||||
return Asm().Float64Constant(base::ieee754::sinh(k));
|
||||
case FloatUnaryOp::Kind::kCosh:
|
||||
|
@ -2394,6 +2394,10 @@ DEFINE_IMPLICATION(verify_predictable, predictable)
|
||||
DEFINE_INT(dump_allocations_digest_at_alloc, -1,
|
||||
"dump allocations digest each n-th allocation")
|
||||
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
DEFINE_BOOL(use_libm_trig_functions, true, "use libm trig functions")
|
||||
#endif
|
||||
|
||||
// Cleanup...
|
||||
#undef FLAG_FULL
|
||||
#undef FLAG_READONLY
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/base/safe_conversions.h"
|
||||
#include "src/base/utils/random-number-generator.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/common/ptr-compr-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/utils/boxed-float.h"
|
||||
@ -6318,7 +6319,7 @@ TEST(RunFloat64Cos) {
|
||||
m.Return(m.Float64Cos(m.Parameter(0)));
|
||||
CHECK(std::isnan(m.Call(std::numeric_limits<double>::quiet_NaN())));
|
||||
CHECK(std::isnan(m.Call(std::numeric_limits<double>::signaling_NaN())));
|
||||
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(base::ieee754::cos(i), m.Call(i)); }
|
||||
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(COS_IMPL(i), m.Call(i)); }
|
||||
}
|
||||
|
||||
TEST(RunFloat64Cosh) {
|
||||
@ -6428,7 +6429,7 @@ TEST(RunFloat64Sin) {
|
||||
m.Return(m.Float64Sin(m.Parameter(0)));
|
||||
CHECK(std::isnan(m.Call(std::numeric_limits<double>::quiet_NaN())));
|
||||
CHECK(std::isnan(m.Call(std::numeric_limits<double>::signaling_NaN())));
|
||||
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(base::ieee754::sin(i), m.Call(i)); }
|
||||
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(SIN_IMPL(i), m.Call(i)); }
|
||||
}
|
||||
|
||||
TEST(RunFloat64Sinh) {
|
||||
|
@ -131,6 +131,175 @@ TEST(Ieee754, Atanh) {
|
||||
EXPECT_DOUBLE_EQ(0.54930614433405478, atanh(0.5));
|
||||
}
|
||||
|
||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||
TEST(Ieee754, LibmCos) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(libm_cos(kQNaN), IsNaN());
|
||||
EXPECT_THAT(libm_cos(kSNaN), IsNaN());
|
||||
EXPECT_THAT(libm_cos(kInfinity), IsNaN());
|
||||
EXPECT_THAT(libm_cos(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for cos for |x| < pi/4
|
||||
EXPECT_EQ(1.0, 1 / libm_cos(-0.0));
|
||||
EXPECT_EQ(1.0, 1 / libm_cos(0.0));
|
||||
// cos(x) = 1 for |x| < 2^-27
|
||||
EXPECT_EQ(1, libm_cos(2.3283064365386963e-10));
|
||||
EXPECT_EQ(1, libm_cos(-2.3283064365386963e-10));
|
||||
// Test KERNELCOS for |x| < 0.3.
|
||||
// cos(pi/20) = sqrt(sqrt(2)*sqrt(sqrt(5)+5)+4)/2^(3/2)
|
||||
EXPECT_EQ(0.9876883405951378, libm_cos(0.15707963267948966));
|
||||
// Test KERNELCOS for x ~= 0.78125
|
||||
EXPECT_EQ(0.7100335477927638, libm_cos(0.7812504768371582));
|
||||
EXPECT_EQ(0.7100338835660797, libm_cos(0.78125));
|
||||
// Test KERNELCOS for |x| > 0.3.
|
||||
// cos(pi/8) = sqrt(sqrt(2)+1)/2^(3/4)
|
||||
EXPECT_EQ(0.9238795325112867, libm_cos(0.39269908169872414));
|
||||
// Test KERNELTAN for |x| < 0.67434.
|
||||
EXPECT_EQ(0.9238795325112867, libm_cos(-0.39269908169872414));
|
||||
|
||||
// Tests for cos.
|
||||
EXPECT_EQ(1, libm_cos(3.725290298461914e-9));
|
||||
// Cover different code paths in KERNELCOS.
|
||||
EXPECT_EQ(0.9689124217106447, libm_cos(0.25));
|
||||
EXPECT_EQ(0.8775825618903728, libm_cos(0.5));
|
||||
EXPECT_EQ(0.7073882691671998, libm_cos(0.785));
|
||||
// Test that cos(Math.PI/2) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(6.123233995736766e-17, libm_cos(1.5707963267948966));
|
||||
// Test cos for various phases.
|
||||
EXPECT_EQ(0.7071067811865474, libm_cos(7.0 / 4 * kPI));
|
||||
EXPECT_EQ(0.7071067811865477, libm_cos(9.0 / 4 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865467, libm_cos(11.0 / 4 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865471, libm_cos(13.0 / 4 * kPI));
|
||||
EXPECT_EQ(0.9367521275331447, libm_cos(1000000.0));
|
||||
EXPECT_EQ(-3.435757038074824e-12, libm_cos(1048575.0 / 2 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(-0.9258790228548379e0, libm_cos(kTwo120));
|
||||
EXPECT_EQ(-0.9258790228548379e0, libm_cos(-kTwo120));
|
||||
}
|
||||
|
||||
TEST(Ieee754, LibmSin) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(libm_sin(kQNaN), IsNaN());
|
||||
EXPECT_THAT(libm_sin(kSNaN), IsNaN());
|
||||
EXPECT_THAT(libm_sin(kInfinity), IsNaN());
|
||||
EXPECT_THAT(libm_sin(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for sin for |x| < pi/4
|
||||
EXPECT_EQ(-kInfinity, Divide(1.0, libm_sin(-0.0)));
|
||||
EXPECT_EQ(kInfinity, Divide(1.0, libm_sin(0.0)));
|
||||
// sin(x) = x for x < 2^-27
|
||||
EXPECT_EQ(2.3283064365386963e-10, libm_sin(2.3283064365386963e-10));
|
||||
EXPECT_EQ(-2.3283064365386963e-10, libm_sin(-2.3283064365386963e-10));
|
||||
// sin(pi/8) = sqrt(sqrt(2)-1)/2^(3/4)
|
||||
EXPECT_EQ(0.3826834323650898, libm_sin(0.39269908169872414));
|
||||
EXPECT_EQ(-0.3826834323650898, libm_sin(-0.39269908169872414));
|
||||
|
||||
// Tests for sin.
|
||||
EXPECT_EQ(0.479425538604203, libm_sin(0.5));
|
||||
EXPECT_EQ(-0.479425538604203, libm_sin(-0.5));
|
||||
EXPECT_EQ(1, libm_sin(kPI / 2.0));
|
||||
EXPECT_EQ(-1, libm_sin(-kPI / 2.0));
|
||||
// Test that sin(Math.PI) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(1.2246467991473532e-16, libm_sin(kPI));
|
||||
EXPECT_EQ(-7.047032979958965e-14, libm_sin(2200.0 * kPI));
|
||||
// Test sin for various phases.
|
||||
EXPECT_EQ(-0.7071067811865477, libm_sin(7.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865474, libm_sin(9.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865483, libm_sin(11.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865479, libm_sin(13.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-3.2103381051568376e-11, libm_sin(1048576.0 / 4 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(0.377820109360752e0, libm_sin(kTwo120));
|
||||
EXPECT_EQ(-0.377820109360752e0, libm_sin(-kTwo120));
|
||||
}
|
||||
|
||||
TEST(Ieee754, FdlibmCos) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(fdlibm_cos(kQNaN), IsNaN());
|
||||
EXPECT_THAT(fdlibm_cos(kSNaN), IsNaN());
|
||||
EXPECT_THAT(fdlibm_cos(kInfinity), IsNaN());
|
||||
EXPECT_THAT(fdlibm_cos(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for cos for |x| < pi/4
|
||||
EXPECT_EQ(1.0, 1 / fdlibm_cos(-0.0));
|
||||
EXPECT_EQ(1.0, 1 / fdlibm_cos(0.0));
|
||||
// cos(x) = 1 for |x| < 2^-27
|
||||
EXPECT_EQ(1, fdlibm_cos(2.3283064365386963e-10));
|
||||
EXPECT_EQ(1, fdlibm_cos(-2.3283064365386963e-10));
|
||||
// Test KERNELCOS for |x| < 0.3.
|
||||
// cos(pi/20) = sqrt(sqrt(2)*sqrt(sqrt(5)+5)+4)/2^(3/2)
|
||||
EXPECT_EQ(0.9876883405951378, fdlibm_cos(0.15707963267948966));
|
||||
// Test KERNELCOS for x ~= 0.78125
|
||||
EXPECT_EQ(0.7100335477927638, fdlibm_cos(0.7812504768371582));
|
||||
EXPECT_EQ(0.7100338835660797, fdlibm_cos(0.78125));
|
||||
// Test KERNELCOS for |x| > 0.3.
|
||||
// cos(pi/8) = sqrt(sqrt(2)+1)/2^(3/4)
|
||||
EXPECT_EQ(0.9238795325112867, fdlibm_cos(0.39269908169872414));
|
||||
// Test KERNELTAN for |x| < 0.67434.
|
||||
EXPECT_EQ(0.9238795325112867, fdlibm_cos(-0.39269908169872414));
|
||||
|
||||
// Tests for cos.
|
||||
EXPECT_EQ(1, fdlibm_cos(3.725290298461914e-9));
|
||||
// Cover different code paths in KERNELCOS.
|
||||
EXPECT_EQ(0.9689124217106447, fdlibm_cos(0.25));
|
||||
EXPECT_EQ(0.8775825618903728, fdlibm_cos(0.5));
|
||||
EXPECT_EQ(0.7073882691671998, fdlibm_cos(0.785));
|
||||
// Test that cos(Math.PI/2) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(6.123233995736766e-17, fdlibm_cos(1.5707963267948966));
|
||||
// Test cos for various phases.
|
||||
EXPECT_EQ(0.7071067811865474, fdlibm_cos(7.0 / 4 * kPI));
|
||||
EXPECT_EQ(0.7071067811865477, fdlibm_cos(9.0 / 4 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865467, fdlibm_cos(11.0 / 4 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865471, fdlibm_cos(13.0 / 4 * kPI));
|
||||
EXPECT_EQ(0.9367521275331447, fdlibm_cos(1000000.0));
|
||||
EXPECT_EQ(-3.435757038074824e-12, fdlibm_cos(1048575.0 / 2 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(-0.9258790228548379e0, fdlibm_cos(kTwo120));
|
||||
EXPECT_EQ(-0.9258790228548379e0, fdlibm_cos(-kTwo120));
|
||||
}
|
||||
|
||||
TEST(Ieee754, FdlibmSin) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(fdlibm_sin(kQNaN), IsNaN());
|
||||
EXPECT_THAT(fdlibm_sin(kSNaN), IsNaN());
|
||||
EXPECT_THAT(fdlibm_sin(kInfinity), IsNaN());
|
||||
EXPECT_THAT(fdlibm_sin(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for sin for |x| < pi/4
|
||||
EXPECT_EQ(-kInfinity, Divide(1.0, fdlibm_sin(-0.0)));
|
||||
EXPECT_EQ(kInfinity, Divide(1.0, fdlibm_sin(0.0)));
|
||||
// sin(x) = x for x < 2^-27
|
||||
EXPECT_EQ(2.3283064365386963e-10, fdlibm_sin(2.3283064365386963e-10));
|
||||
EXPECT_EQ(-2.3283064365386963e-10, fdlibm_sin(-2.3283064365386963e-10));
|
||||
// sin(pi/8) = sqrt(sqrt(2)-1)/2^(3/4)
|
||||
EXPECT_EQ(0.3826834323650898, fdlibm_sin(0.39269908169872414));
|
||||
EXPECT_EQ(-0.3826834323650898, fdlibm_sin(-0.39269908169872414));
|
||||
|
||||
// Tests for sin.
|
||||
EXPECT_EQ(0.479425538604203, fdlibm_sin(0.5));
|
||||
EXPECT_EQ(-0.479425538604203, fdlibm_sin(-0.5));
|
||||
EXPECT_EQ(1, fdlibm_sin(kPI / 2.0));
|
||||
EXPECT_EQ(-1, fdlibm_sin(-kPI / 2.0));
|
||||
// Test that sin(Math.PI) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(1.2246467991473532e-16, fdlibm_sin(kPI));
|
||||
EXPECT_EQ(-7.047032979958965e-14, fdlibm_sin(2200.0 * kPI));
|
||||
// Test sin for various phases.
|
||||
EXPECT_EQ(-0.7071067811865477, fdlibm_sin(7.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865474, fdlibm_sin(9.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865483, fdlibm_sin(11.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865479, fdlibm_sin(13.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-3.2103381051568376e-11, fdlibm_sin(1048576.0 / 4 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(0.377820109360752e0, fdlibm_sin(kTwo120));
|
||||
EXPECT_EQ(-0.377820109360752e0, fdlibm_sin(-kTwo120));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
TEST(Ieee754, Cos) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(cos(kQNaN), IsNaN());
|
||||
@ -177,6 +346,45 @@ TEST(Ieee754, Cos) {
|
||||
EXPECT_EQ(-0.9258790228548379e0, cos(-kTwo120));
|
||||
}
|
||||
|
||||
TEST(Ieee754, Sin) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(sin(kQNaN), IsNaN());
|
||||
EXPECT_THAT(sin(kSNaN), IsNaN());
|
||||
EXPECT_THAT(sin(kInfinity), IsNaN());
|
||||
EXPECT_THAT(sin(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for sin for |x| < pi/4
|
||||
EXPECT_EQ(-kInfinity, Divide(1.0, sin(-0.0)));
|
||||
EXPECT_EQ(kInfinity, Divide(1.0, sin(0.0)));
|
||||
// sin(x) = x for x < 2^-27
|
||||
EXPECT_EQ(2.3283064365386963e-10, sin(2.3283064365386963e-10));
|
||||
EXPECT_EQ(-2.3283064365386963e-10, sin(-2.3283064365386963e-10));
|
||||
// sin(pi/8) = sqrt(sqrt(2)-1)/2^(3/4)
|
||||
EXPECT_EQ(0.3826834323650898, sin(0.39269908169872414));
|
||||
EXPECT_EQ(-0.3826834323650898, sin(-0.39269908169872414));
|
||||
|
||||
// Tests for sin.
|
||||
EXPECT_EQ(0.479425538604203, sin(0.5));
|
||||
EXPECT_EQ(-0.479425538604203, sin(-0.5));
|
||||
EXPECT_EQ(1, sin(kPI / 2.0));
|
||||
EXPECT_EQ(-1, sin(-kPI / 2.0));
|
||||
// Test that sin(Math.PI) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(1.2246467991473532e-16, sin(kPI));
|
||||
EXPECT_EQ(-7.047032979958965e-14, sin(2200.0 * kPI));
|
||||
// Test sin for various phases.
|
||||
EXPECT_EQ(-0.7071067811865477, sin(7.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865474, sin(9.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865483, sin(11.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865479, sin(13.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-3.2103381051568376e-11, sin(1048576.0 / 4 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(0.377820109360752e0, sin(kTwo120));
|
||||
EXPECT_EQ(-0.377820109360752e0, sin(-kTwo120));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Ieee754, Cosh) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(cosh(kQNaN), IsNaN());
|
||||
@ -306,43 +514,6 @@ TEST(Ieee754, Cbrt) {
|
||||
EXPECT_EQ(46.415888336127786, cbrt(100000));
|
||||
}
|
||||
|
||||
TEST(Ieee754, Sin) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(sin(kQNaN), IsNaN());
|
||||
EXPECT_THAT(sin(kSNaN), IsNaN());
|
||||
EXPECT_THAT(sin(kInfinity), IsNaN());
|
||||
EXPECT_THAT(sin(-kInfinity), IsNaN());
|
||||
|
||||
// Tests for sin for |x| < pi/4
|
||||
EXPECT_EQ(-kInfinity, Divide(1.0, sin(-0.0)));
|
||||
EXPECT_EQ(kInfinity, Divide(1.0, sin(0.0)));
|
||||
// sin(x) = x for x < 2^-27
|
||||
EXPECT_EQ(2.3283064365386963e-10, sin(2.3283064365386963e-10));
|
||||
EXPECT_EQ(-2.3283064365386963e-10, sin(-2.3283064365386963e-10));
|
||||
// sin(pi/8) = sqrt(sqrt(2)-1)/2^(3/4)
|
||||
EXPECT_EQ(0.3826834323650898, sin(0.39269908169872414));
|
||||
EXPECT_EQ(-0.3826834323650898, sin(-0.39269908169872414));
|
||||
|
||||
// Tests for sin.
|
||||
EXPECT_EQ(0.479425538604203, sin(0.5));
|
||||
EXPECT_EQ(-0.479425538604203, sin(-0.5));
|
||||
EXPECT_EQ(1, sin(kPI / 2.0));
|
||||
EXPECT_EQ(-1, sin(-kPI / 2.0));
|
||||
// Test that sin(Math.PI) != 0 since Math.PI is not exact.
|
||||
EXPECT_EQ(1.2246467991473532e-16, sin(kPI));
|
||||
EXPECT_EQ(-7.047032979958965e-14, sin(2200.0 * kPI));
|
||||
// Test sin for various phases.
|
||||
EXPECT_EQ(-0.7071067811865477, sin(7.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865474, sin(9.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(0.7071067811865483, sin(11.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-0.7071067811865479, sin(13.0 / 4.0 * kPI));
|
||||
EXPECT_EQ(-3.2103381051568376e-11, sin(1048576.0 / 4 * kPI));
|
||||
|
||||
// Test Hayne-Panek reduction.
|
||||
EXPECT_EQ(0.377820109360752e0, sin(kTwo120));
|
||||
EXPECT_EQ(-0.377820109360752e0, sin(-kTwo120));
|
||||
}
|
||||
|
||||
TEST(Ieee754, Sinh) {
|
||||
// Test values mentioned in the EcmaScript spec.
|
||||
EXPECT_THAT(sinh(kQNaN), IsNaN());
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/base/division-by-constant.h"
|
||||
#include "src/base/ieee754.h"
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/compiler/js-graph.h"
|
||||
#include "src/compiler/machine-operator.h"
|
||||
#include "src/numbers/conversions-inl.h"
|
||||
@ -2840,7 +2841,7 @@ TEST_F(MachineOperatorReducerTest, Float64CosWithConstant) {
|
||||
Reduce(graph()->NewNode(machine()->Float64Cos(), Float64Constant(x)));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cos(x))));
|
||||
IsFloat64Constant(NanSensitiveDoubleEq(COS_IMPL(x))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2939,7 +2940,7 @@ TEST_F(MachineOperatorReducerTest, Float64SinWithConstant) {
|
||||
Reduce(graph()->NewNode(machine()->Float64Sin(), Float64Constant(x)));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sin(x))));
|
||||
IsFloat64Constant(NanSensitiveDoubleEq(SIN_IMPL(x))));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user