Skip to content

Vector{<T>|64|128|256|512}.Narrow with saturation #75724

Open
@gfoidl

Description

Summary

For SSE2 there's Sse2.PackSignedSaturate which packs the two vectors with saturation.
Such functionality is missing for the xplat-vectors -- i.e. Vector128.Narrow packs the two vectors, but cuts / masks off the values outside of the target range, e.g. for short -> sbyte bits above 0xFF is cut off resulting in (for me) unexpected values.

Maybe it's a bit astonishing that Narrow doesn't pack with saturation. This just bit me, and as it seems #73064 (comment) was similar.

There should be something like NarrowWithSaturation in order to don't need to fallback to Sse2 / AdvSimd.

API Proposal

namespace System.Runtime.Intrinsics;

public static class Vector64
{
    // Existing methods left out for brevity

    [CLSCompliant(false)]
    public static Vector64<sbyte> NarrowWithSaturation(Vector64<short> lower, Vector64<short> upper);

    public static Vector64<short> NarrowWithSaturation(Vector64<int> lower, Vector64<int> upper);

    public static Vector64<int> NarrowWithSaturation(Vector64<long> lower, Vector64<long> upper);

    [CLSCompliant(false)]
    public static Vector64<byte> NarrowWithSaturation(Vector64<ushort> lower, Vector64<ushort> upper);

    [CLSCompliant(false)]
    public static Vector64<ushort> NarrowWithSaturation(Vector64<uint> lower, Vector64<uint> upper);

    public static Vector64<uint> NarrowWithSaturation(Vector64<ulong> lower, Vector64<ulong> upper);

    public static Vector64<float> NarrowWithSaturation(Vector64<double> lower, Vector64<double> upper);
}

public static class Vector128
{
    // Existing methods left out for brevity

    [CLSCompliant(false)]
    public static Vector128<sbyte> NarrowWithSaturation(Vector128<short> lower, Vector128<short> upper);

    public static Vector128<short> NarrowWithSaturation(Vector128<int> lower, Vector128<int> upper);

    public static Vector128<int> NarrowWithSaturation(Vector128<long> lower, Vector128<long> upper);

    [CLSCompliant(false)]
    public static Vector128<byte> NarrowWithSaturation(Vector128<ushort> lower, Vector128<ushort> upper);

    [CLSCompliant(false)]
    public static Vector128<ushort> NarrowWithSaturation(Vector128<uint> lower, Vector128<uint> upper);

    public static Vector128<uint> NarrowWithSaturation(Vector128<ulong> lower, Vector128<ulong> upper);

    public static Vector128<float> NarrowWithSaturation(Vector128<double> lower, Vector128<double> upper);
}

public static class Vector256
{
    // Existing methods left out for brevity

    [CLSCompliant(false)]
    public static Vector256<sbyte> NarrowWithSaturation(Vector256<short> lower, Vector256<short> upper);

    public static Vector256<short> NarrowWithSaturation(Vector256<int> lower, Vector256<int> upper);

    public static Vector256<int> NarrowWithSaturation(Vector256<long> lower, Vector256<long> upper);

    [CLSCompliant(false)]
    public static Vector256<byte> NarrowWithSaturation(Vector256<ushort> lower, Vector256<ushort> upper);

    [CLSCompliant(false)]
    public static Vector256<ushort> NarrowWithSaturation(Vector256<uint> lower, Vector256<uint> upper);

    public static Vector256<uint> NarrowWithSaturation(Vector256<ulong> lower, Vector256<ulong> upper);

    public static Vector256<float> NarrowWithSaturation(Vector256<double> lower, Vector256<double> upper);
}

public static class Vector512
{
    // Existing methods left out for brevity

    [CLSCompliant(false)]
    public static Vector512<sbyte> NarrowWithSaturation(Vector512<short> lower, Vector512<short> upper);

    public static Vector512<short> NarrowWithSaturation(Vector512<int> lower, Vector512<int> upper);

    public static Vector512<int> NarrowWithSaturation(Vector512<long> lower, Vector512<long> upper);

    [CLSCompliant(false)]
    public static Vector512<byte> NarrowWithSaturation(Vector512<ushort> lower, Vector512<ushort> upper);

    [CLSCompliant(false)]
    public static Vector512<ushort> NarrowWithSaturation(Vector512<uint> lower, Vector512<uint> upper);

    public static Vector512<uint> NarrowWithSaturation(Vector512<ulong> lower, Vector512<ulong> upper);

    public static Vector512<float> NarrowWithSaturation(Vector512<double> lower, Vector512<double> upper);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions