diff --git a/src/coreclr/classlibnative/float/floatdouble.cpp b/src/coreclr/classlibnative/float/floatdouble.cpp index d20b772eb2207c..b7c9932bffdd8d 100644 --- a/src/coreclr/classlibnative/float/floatdouble.cpp +++ b/src/coreclr/classlibnative/float/floatdouble.cpp @@ -253,6 +253,13 @@ FCIMPL1_V(double, COMDouble::Sin, double x) return sin(x); FCIMPLEND +#if defined(_MSC_VER) +// The /fp:fast form of `sincos` for xarch returns sin twice, rather than sincos +// https://developercommunity.visualstudio.com/t/MSVCs-sincos-implementation-is-incorrec/10582378 +#pragma float_control(push) +#pragma float_control(precise, on) +#endif + /*====================================SinCos==================================== ** ==============================================================================*/ @@ -268,6 +275,10 @@ FCIMPL3_VII(void, COMDouble::SinCos, double x, double* pSin, double* pCos) FCIMPLEND +#if defined(_MSC_VER) +#pragma float_control(pop) +#endif + /*=====================================Sinh===================================== ** ==============================================================================*/ diff --git a/src/coreclr/classlibnative/float/floatsingle.cpp b/src/coreclr/classlibnative/float/floatsingle.cpp index 1694fd78cb8467..3f6290f12c43f3 100644 --- a/src/coreclr/classlibnative/float/floatsingle.cpp +++ b/src/coreclr/classlibnative/float/floatsingle.cpp @@ -228,6 +228,13 @@ FCIMPL1_V(float, COMSingle::Sin, float x) return sinf(x); FCIMPLEND +#if defined(_MSC_VER) +// The /fp:fast form of `sincos` for xarch returns sin twice, rather than sincos +// https://developercommunity.visualstudio.com/t/MSVCs-sincos-implementation-is-incorrec/10582378 +#pragma float_control(push) +#pragma float_control(precise, on) +#endif + /*====================================SinCos==================================== ** ==============================================================================*/ @@ -243,6 +250,10 @@ FCIMPL3_VII(void, COMSingle::SinCos, float x, float* pSin, float* pCos) FCIMPLEND +#if defined(_MSC_VER) +#pragma float_control(pop) +#endif + /*=====================================Sinh===================================== ** ==============================================================================*/ diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs index 86ca388b114217..bff81bdbe3858e 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs @@ -1497,6 +1497,7 @@ public static void Sin(double value, double expectedResult, double allowedVarian [Theory] [InlineData( double.NegativeInfinity, double.NaN, double.NaN, 0.0, 0.0)] + [InlineData(-1e18, 0.9929693207404051, 0.11837199021871073, 0.0002, 0.002)] // https://github.com/dotnet/runtime/issues/98204 [InlineData(-3.1415926535897932, -0.0, -1.0, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: -(pi) [InlineData(-2.7182818284590452, -0.41078129050290870, -0.91173391478696510, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(e) [InlineData(-2.3025850929940457, -0.74398033695749319, -0.66820151019031295, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(10)) @@ -1528,6 +1529,7 @@ public static void Sin(double value, double expectedResult, double allowedVarian [InlineData( 2.3025850929940457, 0.74398033695749319, -0.66820151019031295, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(10)) [InlineData( 2.7182818284590452, 0.41078129050290870, -0.91173391478696510, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (e) [InlineData( 3.1415926535897932, 0.0, -1.0, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( 1e18, -0.9929693207404051, 0.11837199021871073, 0.0002, 0.002)] // https://github.com/dotnet/runtime/issues/98204 [InlineData( double.PositiveInfinity, double.NaN, double.NaN, 0.0, 0.0)] public static void SinCos(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/MathF.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/MathF.cs index 85e62a190ad777..59040cd799c47a 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/MathF.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/MathF.cs @@ -1677,6 +1677,7 @@ public static void Sin(float value, float expectedResult, float allowedVariance) [Theory] [InlineData( float.NegativeInfinity, float.NaN, float.NaN, 0.0f, 0.0f)] + [InlineData(-1e8f, -0.931639, -0.36338508, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // https://github.com/dotnet/runtime/issues/98204 [InlineData(-3.14159265f, -0.0f, -1.0f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: -(pi) [InlineData(-2.71828183f, -0.410781291f, -0.911733918f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(e) [InlineData(-2.30258509f, -0.743980337f, -0.668201510f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(10)) @@ -1708,6 +1709,7 @@ public static void Sin(float value, float expectedResult, float allowedVariance) [InlineData( 2.30258509f, 0.743980337f, -0.668201510f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(10)) [InlineData( 2.71828183f, 0.410781291f, -0.911733918f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (e) [InlineData( 3.14159265f, 0.0f, -1.0f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( 1e8f, 0.931639, -0.36338508, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // https://github.com/dotnet/runtime/issues/98204 [InlineData( float.PositiveInfinity, float.NaN, float.NaN, 0.0f, 0.0f)] public static void SinCos(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos) {