-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Obsolete invalid overloads of AdvSimd.ShiftRightLogicalRoundedNarrowingSaturate
family
#95525
Comments
Tagging subscribers to this area: @dotnet/area-system-runtime-intrinsics Issue DetailsBackground and motivationThe Arm Advanced SIMD These overloads will not work as expected if following the API description rather than the instruction description. It would likely be best to obsolete and hide them to avoid potential confusion. API Proposal namespace System.Runtime.Intrinsics.Arm;
public abstract class AdvSimd : ArmBase
{
public new abstract class Arm64 : ArmBase.Arm64
{
/// <summary>
/// uint16_t vqrshrns_n_u32 (uint32_t a, const int n)
/// A64: UQRSHRN Hd, Sn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<short> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<int> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n)
/// A64: UQRSHRN Sd, Dn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<int> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<long> value, [ConstantExpected(Min = 1, Max = (byte)(8))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n)
/// A64: UQRSHRN Bd, Hn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<sbyte> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<short> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
}
/// <summary>
/// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n)
/// A32: VQRSHRN.U32 Dd, Qm, #n
/// A64: UQRSHRN Vd.4H, Vn.4S, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<short> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n)
/// A32: VQRSHRN.U64 Dd, Qm, #n
/// A64: UQRSHRN Vd.2S, Vn.2D, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<int> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n)
/// A32: VQRSHRN.U16 Dd, Qm, #n
/// A64: UQRSHRN Vd.8B, Vn.8H, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<sbyte> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n)
/// A32: VQRSHRN.U32 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.8H, Vn.4S, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<short> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<short> lower, Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n)
/// A32: VQRSHRN.U64 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.4S, Vn.2D, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<int> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<int> lower, Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n)
/// A32: VQRSHRN.U16 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.16B, Vn.8H, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<sbyte> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<sbyte> lower, Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count) { throw new PlatformNotSupportedException(); }
} API UsageN/A Alternative DesignsCould just leave them there and let people trip on them. RisksSource-breaking change.
|
|
It's not the shift that's the problem, it's the unsigned saturated narrow. The result literally cannot be a signed value -- it will be saturated to a min of zero. |
namespace System.Runtime.Intrinsics.Arm;
public abstract class AdvSimd : ArmBase
{
public new abstract class Arm64 : ArmBase.Arm64
{
/// <summary>
/// uint16_t vqrshrns_n_u32 (uint32_t a, const int n)
/// A64: UQRSHRN Hd, Sn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<short> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<int> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n)
/// A64: UQRSHRN Sd, Dn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<int> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<long> value, [ConstantExpected(Min = 1, Max = (byte)(8))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n)
/// A64: UQRSHRN Bd, Hn, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<sbyte> ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64<short> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
}
/// <summary>
/// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n)
/// A32: VQRSHRN.U32 Dd, Qm, #n
/// A64: UQRSHRN Vd.4H, Vn.4S, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<short> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n)
/// A32: VQRSHRN.U64 Dd, Qm, #n
/// A64: UQRSHRN Vd.2S, Vn.2D, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<int> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n)
/// A32: VQRSHRN.U16 Dd, Qm, #n
/// A64: UQRSHRN Vd.8B, Vn.8H, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector64<sbyte> ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n)
/// A32: VQRSHRN.U32 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.8H, Vn.4S, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<short> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<short> lower, Vector128<int> value, [ConstantExpected(Min = 1, Max = (byte)(32))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n)
/// A32: VQRSHRN.U64 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.4S, Vn.2D, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<int> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<int> lower, Vector128<long> value, [ConstantExpected(Min = 1, Max = (byte)(16))] byte count) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n)
/// A32: VQRSHRN.U16 Dd+1, Dn, #n
/// A64: UQRSHRN2 Vd.16B, Vn.8H, #n
/// </summary>
+ [Obsolete("Use unsigned overload or signed instruction.")]
public static Vector128<sbyte> ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64<sbyte> lower, Vector128<short> value, [ConstantExpected(Min = 1, Max = (byte)(64))] byte count) { throw new PlatformNotSupportedException(); }
} |
Background and motivation
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. It would likely be best to obsolete and hide them to avoid potential confusion.
API Proposal
API Usage
N/A
Alternative Designs
Could just leave them there and let people trip on them.
Risks
Source-breaking change.
The text was updated successfully, but these errors were encountered: