Skip to content

[API Proposal]: Obsolete invalid overloads of AdvSimd.ShiftRightLogicalRoundedNarrowingSaturate family #95525

@saucecontrol

Description

@saucecontrol

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

 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 Usage

N/A

Alternative Designs

Could just leave them there and let people trip on them.

Risks

Source-breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.Runtime.Intrinsicsbreaking-changeIssue or PR that represents a breaking API or functional change over a prerelease.help wanted[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is mergedneeds-breaking-change-doc-createdBreaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions