Description
Description
The Arm Advanced SIMD UQRSHRN
instruction performs an unsigned saturated narrow operation. As such, its result is always unsigned. However, the .NET intrinsics API for this instruction includes overloads that accept and return signed types.
These overloads will not work as expected if following the API description rather than the instruction description. Because the underlying implementation cannot be corrected to perform signed saturated narrow operations and return signed results, the methods are now marked as [Obsolete]
with a message indicating the unsigned overloads should be used instead.
Version
.NET 9 Preview 4
Previous behavior
The methods would perform unsigned saturated narrow operations, even when operating on and returning signed types.
New behavior
The overloads are marked as [Obsolete]
with a message citing the unexpected behavior. Build warnings will be produced if the obsolete overloads are used.
Type of breaking change
- Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
- Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code may require source changes to compile successfully.
- Behavioral change: Existing binaries may behave differently at run time.
Reason for change
These overloads will not work as expected if following the API description rather than the instruction description. Because the underlying implementation cannot be corrected to perform signed saturated narrow operations and return signed results, the methods are now marked as [Obsolete]
with a message indicating the unsigned overloads should be used instead.
Recommended action
Call the unsigned method overloads instead, intentionally converting the data to/from unsigned types as needed.
Feature area
Core .NET libraries
Affected APIs
System.Runtime.Intrinsics.Arm.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<short> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count)
System.Runtime.Intrinsics.Arm.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<int> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count)
System.Runtime.Intrinsics.Arm.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<long> value, [ConstantExpected(Min = 1, Max = (byte)(8))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<sbyte> lower, Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<short> lower, Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count)
System.Runtime.Intrinsics.Arm.ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<int> lower, Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count)