Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The following System.Runtime.Intrinsics.X86.Sse and System.Runtime.Intrinsics.X86.Sse2 methods have been fixed to properly handle NaN inputs and match the hardware behavior of the equivalent methods in the System.Runtime.Intrinsics.X86.Avx class:
- CompareGreaterThan
- CompareGreaterThanOrEqual
- CompareNotGreaterThan
- CompareNotGreaterThanOrEqual
- CompareScalarGreaterThan
- CompareScalarGreaterThanOrEqual
- CompareScalarNotGreaterThan
- CompareScalarNotGreaterThanOrEqual
Change description
Previously, NaN inputs to the listed Sse and Sse2 methods returned an incorrect result. The result also differed from the result generated by the corresponding method in the Avx class.
Starting in .NET 5, these methods correctly handle NaN inputs and return the same results as the corresponding methods in the Avx class.
The Streaming SIMD Extensions (SSE) and Streaming SIMD Extensions 2 (SSE2) Instruction Set Architectures (ISAs) don't provide direct hardware support for these comparison methods, so they're implemented in software. Previously, the methods were improperly implemented, and they incorrectly handled NaN inputs. For code ported from native, the incorrect behavior may introduce bugs. For a 256-bit code path, the methods can also produce different results to the equivalent methods in the Avx class.
As an example of how the methods were previously incorrect, you can implement CompareNotGreaterThan(x,y) as CompareLessThanOrEqual(x,y) for regular integers. However, for NaN inputs, that logic computes the wrong result. Instead, using CompareNotLessThan(y,x) compares the numbers correctly and takes NaN inputs into consideration.
Version introduced
5.0
Recommended action
- If the previous behavior was a bug, no change is required. 
- If the previous behavior was desired, you can maintain that behavior by changing the relevant invocation as follows: - CompareGreaterThan(x,y)->- CompareNotLessThanOrEqual(x,y)
- CompareGreaterThanOrEqual(x,y)->- CompareNotLessThan(x,y)
- CompareNotGreaterThan(x,y)->- CompareLessThanOrEqual(x,y)
- CompareNotGreaterThanOrEqual(x,y)->- CompareLessThan(x,y)
- CompareScalarGreaterThan(x,y)->- CompareScalarNotLessThanOrEqual(x,y)
- CompareScalarGreaterThanOrEqual(x,y)->- CompareScalarNotLessThan(x,y)
- CompareScalarNotGreaterThan(x,y)->- CompareScalarLessThanOrEqual(x,y)
- CompareScalarNotGreaterThanOrEqual(x,y)->- CompareScalarLessThan(x,y)
 
Affected APIs
- System.Runtime.Intrinsics.X86.Sse.CompareGreaterThan(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse.CompareGreaterThanOrEqual(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThan(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThanOrEqual(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse.CompareScalarGreaterThan(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse.CompareScalarNotGreaterThan(Vector128<Single>, Vector128<Single>) 
- System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThan(Vector128<Double>, Vector128<Double>) 
- System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThanOrEqual(Vector128<Double>, Vector128<Double>) 
- System.Runtime.Intrinsics.X86.Sse2.CompareNotGreaterThan(Vector128<Double>, Vector128<Double>) 
- System.Runtime.Intrinsics.X86.Sse2.CompareScalarGreaterThan(Vector128<Double>, Vector128<Double>) 
- System.Runtime.Intrinsics.X86.Sse2.CompareScalarNotGreaterThan(Vector128<Double>, Vector128<Double>)