From bf92ee80df6dd33a66328d6344184ed6de9fe56e Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Mon, 2 Jun 2025 16:54:42 +0100 Subject: [PATCH 01/14] SVE2 API for AddCarryWideningLower --- src/coreclr/jit/hwintrinsiclistarm64sve.h | 1 + .../Arm/Sve2.PlatformNotSupported.cs | 14 ++++++ .../src/System/Runtime/Intrinsics/Arm/Sve2.cs | 14 ++++++ .../ref/System.Runtime.Intrinsics.cs | 3 ++ .../GenerateHWIntrinsicTests_Arm.cs | 3 ++ .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 47 +++++++++++++++++++ 6 files changed, 82 insertions(+) diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index e70db726ce152f..2f6c05aa34fd03 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -318,6 +318,7 @@ HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningLower, HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, AddCarryWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclb, INS_invalid, INS_sve_adclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseClearXor, -1, 3, {INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelect, -1, 3, {INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index ff9b4b05b22bb9..c76174f8482870 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -230,6 +230,20 @@ internal Arm64() { } /// public static Vector AbsoluteDifferenceWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Add with carry long (bottom) + + /// + /// svuint32_t svadclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// ADCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svadclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// ADCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + // Bitwise clear and exclusive OR /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index 77bd276cb5bad0..1312f09097fbd1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -230,6 +230,20 @@ internal Arm64() { } /// public static Vector AbsoluteDifferenceWideningUpper(Vector left, Vector right) => AbsoluteDifferenceWideningUpper(left, right); + // Add with carry long (bottom) + + /// + /// svuint32_t svadclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// ADCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) => AddCarryWideningLower(op1, op2, op3); + + /// + /// svuint64_t svadclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// ADCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) => AddCarryWideningLower(op1, op2, op3); + // Bitwise clear and exclusive OR /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 9072c1d2f03185..b85652a4df3d8b 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -6116,6 +6116,9 @@ internal Arm64() { } public static System.Numerics.Vector AbsoluteDifferenceWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AbsoluteDifferenceWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddCarryWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector AddCarryWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index f7812710903cb5..c7c97499e39754 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4817,6 +4817,9 @@ ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningUpper_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningUpper_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int32) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 355730e6ddab56..2aa21608664893 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2293,6 +2293,27 @@ private static long Reduce(Func reduceOp, sbyte[] op1) public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int i) + { + uint lsb; + ulong res; + + if (i % 2 == 0) + { + lsb = op3[i + 1] & 1u; + res = (ulong)op1[i] + op2[i] + lsb; + return (uint)res; + } + else + { + lsb = op3[i] & 1u; + res = (ulong)op1[i - 1] + op2[i - 1] + lsb; + + // Shift result to get the carry bit + return (uint)(res >> 32); + } + } + private static short HighNarrowing(int op1, bool round) { uint roundConst = 0; @@ -2415,6 +2436,32 @@ private static long Reduce(Func reduceOp, short[] op1) public static long AddPairwiseWideningAndAdd(long[] op1, int[] op2, int i) => (long)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, int i) + { + ulong lsb; + ulong res; + + if (i % 2 == 0) + { + lsb = op3[i + 1] & 1UL; + res = op1[i] + op2[i] + lsb; + return res; + } + else + { + lsb = op3[i] & 1UL; + + // Look for an overflow in the addition to get the carry bit + ulong sum1 = op1[i - 1] + op2[i - 1]; + bool overflow1 = sum1 < op1[i - 1]; + + ulong sum2 = sum1 + lsb; + bool overflow2 = sum2 < sum1; + + return (overflow1 || overflow2) ? 1UL : 0UL; + } + } + private static int HighNarrowing(long op1, bool round) { ulong roundConst = 0; From 63eb159ba973938b767015ee020a26309c55083b Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Tue, 3 Jun 2025 14:35:58 +0100 Subject: [PATCH 02/14] SVE2 API for AddCarryWideningUpper --- src/coreclr/jit/hwintrinsiclistarm64sve.h | 1 + .../Arm/Sve2.PlatformNotSupported.cs | 14 ++++++ .../src/System/Runtime/Intrinsics/Arm/Sve2.cs | 14 ++++++ .../ref/System.Runtime.Intrinsics.cs | 3 +- .../GenerateHWIntrinsicTests_Arm.cs | 2 + .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 48 +++++++++++++++++++ 6 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 2f6c05aa34fd03..97ceab72af1d4b 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -319,6 +319,7 @@ HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningUpper, HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, AddCarryWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclb, INS_invalid, INS_sve_adclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, AddCarryWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclt, INS_invalid, INS_sve_adclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseClearXor, -1, 3, {INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelect, -1, 3, {INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index c76174f8482870..1750d1e17a5d16 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -244,6 +244,20 @@ internal Arm64() { } /// public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + // Add with carry long (top) + + /// + /// svuint32_t svadclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// ADCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static unsafe Vector AddCarryWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svadclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// ADCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static unsafe Vector AddCarryWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + // Bitwise clear and exclusive OR /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index 1312f09097fbd1..77da21a5005738 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -244,6 +244,20 @@ internal Arm64() { } /// public static unsafe Vector AddCarryWideningLower(Vector op1, Vector op2, Vector op3) => AddCarryWideningLower(op1, op2, op3); + // Add with carry long (top) + + /// + /// svuint32_t svadclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// ADCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static unsafe Vector AddCarryWideningUpper(Vector op1, Vector op2, Vector op3) => AddCarryWideningUpper(op1, op2, op3); + + /// + /// svuint64_t svadclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// ADCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static unsafe Vector AddCarryWideningUpper(Vector op1, Vector op2, Vector op3) => AddCarryWideningUpper(op1, op2, op3); + // Bitwise clear and exclusive OR /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index b85652a4df3d8b..4299f323ac1397 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -6118,7 +6118,8 @@ internal Arm64() { } public static System.Numerics.Vector AddCarryWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector AddCarryWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - + public static System.Numerics.Vector AddCarryWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector AddCarryWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index c7c97499e39754..120ecd68a600d0 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4819,6 +4819,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningOdd(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningOdd(first, second, third, i)"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 2aa21608664893..ef2b73c64ae0db 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2314,6 +2314,28 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int } } + public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i) + { + uint lsb; + ulong res; + + if (i % 2 == 0) + { + lsb = op3[i + 1] & 1u; + res = (ulong)op1[i] + op2[i + 1] + lsb; + return (uint)res; + } + else + { + lsb = op3[i] & 1u; + res = (ulong)op1[i - 1] + op2[i] + lsb; + + // Shift result to get the carry bit + return (uint)(res >> 32); + } + } + + private static short HighNarrowing(int op1, bool round) { uint roundConst = 0; @@ -2462,6 +2484,32 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, } } + public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, int i) + { + ulong lsb; + ulong res; + + if (i % 2 == 0) + { + lsb = op3[i + 1] & 1UL; + res = op1[i] + op2[i + 1] + lsb; + return res; + } + else + { + lsb = op3[i] & 1UL; + + // Look for an overflow in the addition to get the carry bit + ulong sum1 = op1[i - 1] + op2[i]; + bool overflow1 = sum1 < op1[i - 1]; + + ulong sum2 = sum1 + lsb; + bool overflow2 = sum2 < sum1; + + return (overflow1 || overflow2) ? 1UL : 0UL; + } + } + private static int HighNarrowing(long op1, bool round) { ulong roundConst = 0; From f1f055cfa69a3e6a61c980decfa6ab3cbedb7b8b Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Tue, 10 Jun 2025 11:22:39 +0100 Subject: [PATCH 03/14] Adding bounds checks in AddCarry helper functions --- .../GenerateHWIntrinsicTests_Arm.cs | 4 +-- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 120ecd68a600d0..ac8c9a9771aa16 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4819,8 +4819,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningOdd(first, second, third, i)"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningOdd(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningOdd(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningUpper_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningOdd(first, second, third, i)"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index ef2b73c64ae0db..2fe316cf3e4899 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2298,14 +2298,23 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int uint lsb; ulong res; + if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + if (i % 2 == 0) { + if (i + 1 >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + lsb = op3[i + 1] & 1u; res = (ulong)op1[i] + op2[i] + lsb; return (uint)res; } else { + if (i - 1 < 0) + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + lsb = op3[i] & 1u; res = (ulong)op1[i - 1] + op2[i - 1] + lsb; @@ -2319,14 +2328,23 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i uint lsb; ulong res; + if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + if (i % 2 == 0) { + if (i + 1 >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + lsb = op3[i + 1] & 1u; res = (ulong)op1[i] + op2[i + 1] + lsb; return (uint)res; } else { + if (i - 1 < 0) + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + lsb = op3[i] & 1u; res = (ulong)op1[i - 1] + op2[i] + lsb; @@ -2463,14 +2481,23 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, ulong lsb; ulong res; + if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + if (i % 2 == 0) { + if (i + 1 >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + lsb = op3[i + 1] & 1UL; res = op1[i] + op2[i] + lsb; return res; } else { + if (i - 1 < 0) + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + lsb = op3[i] & 1UL; // Look for an overflow in the addition to get the carry bit @@ -2489,14 +2516,23 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i ulong lsb; ulong res; + if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + if (i % 2 == 0) { + if (i + 1 >= op3.Length) + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + lsb = op3[i + 1] & 1UL; res = op1[i] + op2[i + 1] + lsb; return res; } else { + if (i - 1 < 0) + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + lsb = op3[i] & 1UL; // Look for an overflow in the addition to get the carry bit From 55905b95bebec62a5c3e5b2515b02a989841d2e1 Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Fri, 13 Jun 2025 10:12:52 +0000 Subject: [PATCH 04/14] Handling RMW semantics on 3rd operand in lsra and codegen --- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 9 +++++ src/coreclr/jit/hwintrinsiclistarm64sve.h | 4 +-- src/coreclr/jit/lsra.h | 2 ++ src/coreclr/jit/lsraarm64.cpp | 20 ++++++++++- src/coreclr/jit/lsrabuild.cpp | 1 + .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 34 +++++++++---------- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index a4cc960bd29921..d59f58f09cd5bc 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2685,6 +2685,15 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_Sve2_AddCarryWideningLower: + case NI_Sve2_AddCarryWideningUpper: + if (targetReg != op3Reg) + { + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op3Reg, /* canSkip */ true); + } + GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + case NI_Sve2_BitwiseClearXor: case NI_Sve2_Xor: if (targetReg != op1Reg) diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 97ceab72af1d4b..5a943763b993ec 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -318,8 +318,8 @@ HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningLower, HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -HARDWARE_INTRINSIC(Sve2, AddCarryWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclb, INS_invalid, INS_sve_adclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, AddCarryWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclt, INS_invalid, INS_sve_adclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, AddCarryWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclb, INS_invalid, INS_sve_adclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve2, AddCarryWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclt, INS_invalid, INS_sve_adclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, BitwiseClearXor, -1, 3, {INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelect, -1, 3, {INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index a1e81422b27082..b47fe8f962780a 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1935,6 +1935,7 @@ class LinearScan : public LinearScanInterface // 'tgtPrefUse' to that RefPosition. RefPosition* tgtPrefUse = nullptr; RefPosition* tgtPrefUse2 = nullptr; + RefPosition* tgtPrefUse3 = nullptr; public: // The following keep track of information about internal (temporary register) intervals @@ -1957,6 +1958,7 @@ class LinearScan : public LinearScanInterface { tgtPrefUse = nullptr; tgtPrefUse2 = nullptr; + tgtPrefUse3 = nullptr; internalCount = 0; setInternalRegsDelayFree = false; pendingDelayFree = false; diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index cb19df849ada8f..06d832d10307ba 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1464,15 +1464,25 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou { assert(tgtPrefUse == nullptr); assert(tgtPrefUse2 == nullptr); + assert(tgtPrefUse3 == nullptr); tgtPrefUse = delayUse; } - else + else if (opNum == 2) { assert(opNum == 2); assert(tgtPrefUse == nullptr); assert(tgtPrefUse2 == nullptr); + assert(tgtPrefUse3 == nullptr); tgtPrefUse2 = delayUse; } + else + { + assert(opNum == 3); + assert(tgtPrefUse == nullptr); + assert(tgtPrefUse2 == nullptr); + assert(tgtPrefUse3 == nullptr); + tgtPrefUse3 = delayUse; + } } } else if (containedCselOp == operand) @@ -2292,6 +2302,14 @@ GenTree* LinearScan::getDelayFreeOperand(GenTreeHWIntrinsic* intrinsicTree, bool assert(delayFreeOp != nullptr); break; + case NI_Sve2_AddCarryWideningLower: + case NI_Sve2_AddCarryWideningUpper: + // RMW operates on the third op. + assert(isRMW); + delayFreeOp = intrinsicTree->Op(3); + assert(delayFreeOp != nullptr); + break; + default: if (isRMW) { diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 0d297d92a929e5..a57a3bebaebdca 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3062,6 +3062,7 @@ RefPosition* LinearScan::BuildDef(GenTree* tree, SingleTypeRegSet dstCandidates, #ifndef TARGET_ARM setTgtPref(interval, tgtPrefUse); setTgtPref(interval, tgtPrefUse2); + setTgtPref(interval, tgtPrefUse3); #endif // !TARGET_ARM #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 2fe316cf3e4899..877efa7c559d95 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2306,8 +2306,8 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int if (i + 1 >= op3.Length) throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); - lsb = op3[i + 1] & 1u; - res = (ulong)op1[i] + op2[i] + lsb; + lsb = op2[i + 1] & 1u; + res = (ulong)op1[i] + op3[i] + lsb; return (uint)res; } else @@ -2315,8 +2315,8 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int if (i - 1 < 0) throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - lsb = op3[i] & 1u; - res = (ulong)op1[i - 1] + op2[i - 1] + lsb; + lsb = op2[i] & 1u; + res = (ulong)op1[i - 1] + op3[i - 1] + lsb; // Shift result to get the carry bit return (uint)(res >> 32); @@ -2336,8 +2336,8 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i if (i + 1 >= op3.Length) throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); - lsb = op3[i + 1] & 1u; - res = (ulong)op1[i] + op2[i + 1] + lsb; + lsb = op2[i + 1] & 1u; + res = (ulong)op1[i + 1] + op3[i] + lsb; return (uint)res; } else @@ -2345,8 +2345,8 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i if (i - 1 < 0) throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - lsb = op3[i] & 1u; - res = (ulong)op1[i - 1] + op2[i] + lsb; + lsb = op2[i] & 1u; + res = (ulong)op1[i] + op3[i - 1] + lsb; // Shift result to get the carry bit return (uint)(res >> 32); @@ -2489,8 +2489,8 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, if (i + 1 >= op3.Length) throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); - lsb = op3[i + 1] & 1UL; - res = op1[i] + op2[i] + lsb; + lsb = op2[i + 1] & 1UL; + res = op1[i] + op3[i] + lsb; return res; } else @@ -2498,10 +2498,10 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, if (i - 1 < 0) throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - lsb = op3[i] & 1UL; + lsb = op2[i] & 1UL; // Look for an overflow in the addition to get the carry bit - ulong sum1 = op1[i - 1] + op2[i - 1]; + ulong sum1 = op1[i - 1] + op3[i - 1]; bool overflow1 = sum1 < op1[i - 1]; ulong sum2 = sum1 + lsb; @@ -2524,8 +2524,8 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i if (i + 1 >= op3.Length) throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); - lsb = op3[i + 1] & 1UL; - res = op1[i] + op2[i + 1] + lsb; + lsb = op2[i + 1] & 1UL; + res = op1[i + 1] + op3[i] + lsb; return res; } else @@ -2533,11 +2533,11 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i if (i - 1 < 0) throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - lsb = op3[i] & 1UL; + lsb = op2[i] & 1UL; // Look for an overflow in the addition to get the carry bit - ulong sum1 = op1[i - 1] + op2[i]; - bool overflow1 = sum1 < op1[i - 1]; + ulong sum1 = op1[i] + op3[i - 1]; + bool overflow1 = sum1 < op1[i]; ulong sum2 = sum1 + lsb; bool overflow2 = sum2 < sum1; From 8cc95fc913acc7cb937aa043f2570ad832434e82 Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Tue, 17 Jun 2025 15:22:50 +0100 Subject: [PATCH 05/14] Fixing formatting --- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index d59f58f09cd5bc..ca38c26ab7c845 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2692,7 +2692,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op3Reg, /* canSkip */ true); } GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); - break; + break; case NI_Sve2_BitwiseClearXor: case NI_Sve2_Xor: From 8850e9fc6bdeb72423c0c32c5061804df091c155 Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Wed, 18 Jun 2025 12:04:33 +0100 Subject: [PATCH 06/14] Updating array validation in helper functions Change-Id: I9dd753d27af6041f96792ad2958a5cc4f0093ca4 --- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 877efa7c559d95..23ed87645db3d0 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2299,12 +2299,16 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int ulong res; if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } if (i % 2 == 0) { - if (i + 1 >= op3.Length) - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + if (i + 1 >= op2.Length) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); + } lsb = op2[i + 1] & 1u; res = (ulong)op1[i] + op3[i] + lsb; @@ -2312,8 +2316,10 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int } else { - if (i - 1 < 0) + if (i - 1 < 0 || i - 1 >= op1.Length || i - 1 >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } lsb = op2[i] & 1u; res = (ulong)op1[i - 1] + op3[i - 1] + lsb; @@ -2329,21 +2335,27 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i ulong res; if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } if (i % 2 == 0) { - if (i + 1 >= op3.Length) - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + if (i + 1 >= op1.Length || i + 1 >= op2.Length) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); + } lsb = op2[i + 1] & 1u; - res = (ulong)op1[i + 1] + op3[i] + lsb; + res = (ulong)op1[i + 1] + op3[i] + lsb; return (uint)res; } else { - if (i - 1 < 0) + if (i - 1 < 0 || i - 1 >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } lsb = op2[i] & 1u; res = (ulong)op1[i] + op3[i - 1] + lsb; @@ -2482,12 +2494,16 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, ulong res; if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } if (i % 2 == 0) { - if (i + 1 >= op3.Length) + if (i + 1 >= op2.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + } lsb = op2[i + 1] & 1UL; res = op1[i] + op3[i] + lsb; @@ -2495,8 +2511,10 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, } else { - if (i - 1 < 0) + if (i - 1 < 0 || i - 1 >= op1.Length || i - 1 >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } lsb = op2[i] & 1UL; @@ -2517,12 +2535,16 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i ulong res; if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } if (i % 2 == 0) { - if (i + 1 >= op3.Length) - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + if (i + 1 >= op1.Length || i + 1 >= op2.Length) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); + } lsb = op2[i + 1] & 1UL; res = op1[i + 1] + op3[i] + lsb; @@ -2530,8 +2552,10 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i } else { - if (i - 1 < 0) + if (i - 1 < 0 || i - 1 >= op3.Length) + { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } lsb = op2[i] & 1UL; From d6b17b003deaea2929dd8af56b9ae5b38e1fb993 Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Wed, 18 Jun 2025 15:13:07 +0100 Subject: [PATCH 07/14] adding parentheses to subexpressions Change-Id: Ibb95a18ad5abffae2a4b215a31412395c750ba89 --- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 23ed87645db3d0..c16b7282eee4c6 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2298,7 +2298,7 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int uint lsb; ulong res; - if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } @@ -2316,7 +2316,7 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int } else { - if (i - 1 < 0 || i - 1 >= op1.Length || i - 1 >= op3.Length) + if ((i - 1 < 0) || (i - 1 >= op1.Length) || (i - 1 >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } @@ -2334,14 +2334,14 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i uint lsb; ulong res; - if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } if (i % 2 == 0) { - if (i + 1 >= op1.Length || i + 1 >= op2.Length) + if ((i + 1 >= op1.Length) || (i + 1 >= op2.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); } @@ -2352,7 +2352,7 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i } else { - if (i - 1 < 0 || i - 1 >= op3.Length) + if ((i - 1 < 0) || (i - 1 >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } @@ -2493,7 +2493,7 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, ulong lsb; ulong res; - if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } @@ -2511,7 +2511,7 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, } else { - if (i - 1 < 0 || i - 1 >= op1.Length || i - 1 >= op3.Length) + if ((i - 1 < 0) || (i - 1 >= op1.Length) || (i - 1 >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } @@ -2534,14 +2534,14 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i ulong lsb; ulong res; - if (i < 0 || i >= op1.Length || i >= op2.Length || i >= op3.Length) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } if (i % 2 == 0) { - if (i + 1 >= op1.Length || i + 1 >= op2.Length) + if ((i + 1 >= op1.Length) || (i + 1 >= op2.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); } @@ -2552,7 +2552,7 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i } else { - if (i - 1 < 0 || i - 1 >= op3.Length) + if ((i - 1 < 0) || (i - 1 >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } From 253bfb9657f8284e8a142d708d98816519c35d84 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:11:56 -0700 Subject: [PATCH 08/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index c16b7282eee4c6..a254b537123d05 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2316,7 +2316,7 @@ public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int } else { - if ((i - 1 < 0) || (i - 1 >= op1.Length) || (i - 1 >= op3.Length)) + if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } From bb1454bd971abb637bffbd4e236aabeac0c4ce6c Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:12:06 -0700 Subject: [PATCH 09/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index a254b537123d05..e99b195cde3be8 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2341,7 +2341,7 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i if (i % 2 == 0) { - if ((i + 1 >= op1.Length) || (i + 1 >= op2.Length)) + if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); } From 4b83f1b17c414c603b1d41adf107bdd2dea1c68a Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:12:16 -0700 Subject: [PATCH 10/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index e99b195cde3be8..22d8c75f82db9c 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2352,7 +2352,7 @@ public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i } else { - if ((i - 1 < 0) || (i - 1 >= op3.Length)) + if (((i - 1) < 0) || ((i - 1) >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } From 0620077786e9458641fe31aa07ebbe5a4cbbf65b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:12:29 -0700 Subject: [PATCH 11/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 22d8c75f82db9c..a0154b77346967 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2500,7 +2500,7 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, if (i % 2 == 0) { - if (i + 1 >= op2.Length) + if ((i + 1) >= op2.Length) { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); } From 18e4075fac9f0bfc3926cce96e996d4b649654f1 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:12:40 -0700 Subject: [PATCH 12/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index a0154b77346967..20eedd768fd4f9 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2552,7 +2552,7 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i } else { - if ((i - 1 < 0) || (i - 1 >= op3.Length)) + if (((i - 1) < 0) || ((i - 1) >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } From 06ffb6d8c120abf7ade493dd1dc8d329d1bcf1b7 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:12:51 -0700 Subject: [PATCH 13/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 20eedd768fd4f9..f551b47d8d6a53 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2511,7 +2511,7 @@ public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, } else { - if ((i - 1 < 0) || (i - 1 >= op1.Length) || (i - 1 >= op3.Length)) + if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } From 164af7cf2eccd50d62764674b01677dde7ca447a Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 18 Jun 2025 09:13:06 -0700 Subject: [PATCH 14/14] Update src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs --- src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index f551b47d8d6a53..1ad711276c3941 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2541,7 +2541,7 @@ public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, i if (i % 2 == 0) { - if ((i + 1 >= op1.Length) || (i + 1 >= op2.Length)) + if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) { throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); }