From 6f1d8c5c0dbae1904d35fb9680957f811703d47d Mon Sep 17 00:00:00 2001 From: Phoebe Owusu <91153139+ebepho@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:19:20 -0700 Subject: [PATCH] Arm64/SVE: Implemented `ConvertToint64` and `ConvertToUInt64` (#104069) * Added ConverToInt32 and ConvertToUInt32 for float inputs. * Added flags to handle only low predicate registers. * Fix whitespace * Remove special codegen flag * Added new test template for operations with different return types. * Add new test template. * Added api for ConvertToInt32 and ConvertToUInt 32 for double. * Completed SVE Apis for ConvertToInt64 and ConvertToUInt64. * ConvertToSingle for int and uint. * ConvertToSingle for long and ulong. * Started ConvertToDouble. * Changed Validation Template Test name. * ConvertToInt64. * ConvertToInt64 passes optimized tests. * Added cases for ConvertToSingle and ConvertToDouble. * double or long to 32 bit value. * Removed ConvertToDouble and ConvertToSingle. * Removed more of ConvertToSingle and ConvertToDouble. * all tests pass. * addressed comments. * jit format: * Remove trailing space --------- Co-authored-by: Kunal Pathak --- src/coreclr/jit/hwintrinsic.cpp | 2 + src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 17 ++++++-- src/coreclr/jit/hwintrinsiclistarm64sve.h | 2 + src/coreclr/jit/lowerarmarch.cpp | 4 +- .../Arm/Sve.PlatformNotSupported.cs | 41 ++++++++++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 42 +++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 4 ++ .../GenerateHWIntrinsicTests_Arm.cs | 14 ++++--- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 8 +++- ...aryOpDifferentRetTypeTestTemplate.template | 9 ++-- 10 files changed, 127 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index c78f712433cb0..afea65b63eb82 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1731,6 +1731,8 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, { case NI_Sve_ConvertToInt32: case NI_Sve_ConvertToUInt32: + case NI_Sve_ConvertToInt64: + case NI_Sve_ConvertToUInt64: // Save the base type of return SIMD. It is used to contain this intrinsic inside // ConditionalSelect. retNode->AsHWIntrinsic()->SetAuxiliaryJitType(getBaseJitTypeOfSIMDType(sig->retTypeSigClass)); diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 9a2e8e810f5d1..c568a3bad4977 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -511,12 +511,22 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // Special handling for ConvertTo* APIs // Just need to change the opt here. + insOpts embOpt = opt; switch (intrinEmbMask.id) { case NI_Sve_ConvertToInt32: case NI_Sve_ConvertToUInt32: { - opt = intrinEmbMask.baseType == TYP_DOUBLE ? INS_OPTS_D_TO_S : INS_OPTS_SCALABLE_S; + embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_8BYTE ? INS_OPTS_D_TO_S + : INS_OPTS_SCALABLE_S; + break; + } + + case NI_Sve_ConvertToInt64: + case NI_Sve_ConvertToUInt64: + { + embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_4BYTE ? INS_OPTS_S_TO_D + : INS_OPTS_SCALABLE_D; break; } default: @@ -555,7 +565,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // We cannot use use `movprfx` here to move falseReg to targetReg because that will // overwrite the value of embMaskOp1Reg which is present in targetReg. - GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, + embOpt); GetEmitter()->emitIns_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, targetReg, falseReg, opt); @@ -569,7 +580,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } } - GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, embOpt); break; } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index e9b705ea20f47..688691124eab6 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -32,7 +32,9 @@ HARDWARE_INTRINSIC(Sve, Compute64BitAddresses, HARDWARE_INTRINSIC(Sve, Compute8BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, ConditionalSelect, -1, 3, true, {INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_SupportsContainment) HARDWARE_INTRINSIC(Sve, ConvertToInt32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzs, INS_sve_fcvtzs}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ConvertToInt64, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzs, INS_sve_fcvtzs}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertToUInt32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzu, INS_sve_fcvtzu}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ConvertToUInt64, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzu, INS_sve_fcvtzu}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Count16BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cnth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) HARDWARE_INTRINSIC(Sve, Count32BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) HARDWARE_INTRINSIC(Sve, Count64BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 49f47338276fe..d4eaedea91853 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3390,7 +3390,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) // For now, make sure that we get here only for intrinsics that we are // sure about to rely on auxiliary type's size. assert((embOp->GetHWIntrinsicId() == NI_Sve_ConvertToInt32) || - (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt32)); + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt32) || + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToInt64) || + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt64)); uint32_t auxSize = genTypeSize(embOp->GetAuxiliaryType()); if (maskSize == auxSize) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 71734f02404f1..371da71f844ed 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -869,6 +869,26 @@ internal Arm64() { } public static unsafe Vector ConvertToInt32(Vector value) { throw new PlatformNotSupportedException(); } + /// ConvertToInt64 : Floating-point convert + + /// + /// svint64_t svcvt_s64[_f64]_m(svint64_t inactive, svbool_t pg, svfloat64_t op) + /// FCVTZS Ztied.D, Pg/M, Zop.D + /// svint64_t svcvt_s64[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVTZS Ztied.D, Pg/M, Ztied.D + /// svint64_t svcvt_s64[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToInt64(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svcvt_s64[_f32]_m(svint64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVTZS Ztied.D, Pg/M, Zop.S + /// svint64_t svcvt_s64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTZS Ztied.D, Pg/M, Ztied.S + /// svint64_t svcvt_s64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToInt64(Vector value) { throw new PlatformNotSupportedException(); } + /// ConvertToUInt32 : Floating-point convert /// @@ -890,6 +910,27 @@ internal Arm64() { } public static unsafe Vector ConvertToUInt32(Vector value) { throw new PlatformNotSupportedException(); } + /// ConvertToUInt64 : Floating-point convert + + /// + /// svuint64_t svcvt_u64[_f64]_m(svuint64_t inactive, svbool_t pg, svfloat64_t op) + /// FCVTZU Ztied.D, Pg/M, Zop.D + /// svuint64_t svcvt_u64[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVTZU Ztied.D, Pg/M, Ztied.D + /// svuint64_t svcvt_u64[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToUInt64(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svcvt_u64[_f32]_m(svuint64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVTZU Ztied.D, Pg/M, Zop.S + /// svuint64_t svcvt_u64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTZU Ztied.D, Pg/M, Ztied.S + /// svuint64_t svcvt_u64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToUInt64(Vector value) { throw new PlatformNotSupportedException(); } + + /// Count16BitElements : Count the number of 16-bit elements in a vector /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 83808ac6374d5..39d8dde224aa9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -926,6 +926,27 @@ internal Arm64() { } public static unsafe Vector ConvertToInt32(Vector value) => ConvertToInt32(value); + /// ConvertToInt64 : Floating-point convert + + /// + /// svint64_t svcvt_s64[_f64]_m(svint64_t inactive, svbool_t pg, svfloat64_t op) + /// FCVTZS Ztied.D, Pg/M, Zop.D + /// svint64_t svcvt_s64[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVTZS Ztied.D, Pg/M, Ztied.D + /// svint64_t svcvt_s64[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToInt64(Vector value) => ConvertToInt64(value); + + /// + /// svint64_t svcvt_s64[_f32]_m(svint64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVTZS Ztied.D, Pg/M, Zop.S + /// svint64_t svcvt_s64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTZS Ztied.D, Pg/M, Ztied.S + /// svint64_t svcvt_s64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToInt64(Vector value) => ConvertToInt64(value); + + /// ConvertToUInt32 : Floating-point convert /// @@ -947,6 +968,27 @@ internal Arm64() { } public static unsafe Vector ConvertToUInt32(Vector value) => ConvertToUInt32(value); + /// ConvertToUInt64 : Floating-point convert + + /// + /// svuint64_t svcvt_u64[_f64]_m(svuint64_t inactive, svbool_t pg, svfloat64_t op) + /// FCVTZU Ztied.D, Pg/M, Zop.D + /// svuint64_t svcvt_u64[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVTZU Ztied.D, Pg/M, Ztied.D + /// svuint64_t svcvt_u64[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToUInt64(Vector value) => ConvertToUInt64(value); + + /// + /// svuint64_t svcvt_u64[_f32]_m(svuint64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVTZU Ztied.D, Pg/M, Zop.S + /// svuint64_t svcvt_u64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTZU Ztied.D, Pg/M, Ztied.S + /// svuint64_t svcvt_u64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToUInt64(Vector value) => ConvertToUInt64(value); + + /// Count16BitElements : Count the number of 16-bit elements in a vector /// 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 b18efc40efe73..1904b956195d0 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4317,8 +4317,12 @@ internal Arm64() { } public static System.Numerics.Vector ConvertToInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToInt64(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToInt64(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToUInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToUInt32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToUInt64(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToUInt64(System.Numerics.Vector value) { throw null; } public static ulong Count16BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static ulong Count32BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 5cfe4287ee8d0..0719ba73f68c5 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3085,11 +3085,15 @@ ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToInt32(leftOp[i])"}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToInt32(leftOp[i])"}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToUInt32(leftOp[i])"}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToUInt32(leftOp[i])"}), + + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToInt32(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToInt32(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertFloatToInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertFloatToInt64(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToInt64(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToUInt32(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToUInt32(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertFloatToUInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertFloatToUInt64(leftOp[i])"}), + ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToUInt64(leftOp[i])"}), ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count16BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count16BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int16)));",}), ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count32BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count32BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int32)));",}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 4c9f4a3fbed79..2af2aea572c60 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -6434,14 +6434,18 @@ public static ulong ShiftRightAndInsert(ulong left, ulong right, byte shift) public static int ConvertDoubleToInt32(double op1) => (int)Math.Clamp(op1, long.MinValue, long.MaxValue); public static int ConvertToInt32(float op1) => (int)Math.Clamp(op1, int.MinValue, int.MaxValue); + + public static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); - private static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); + public static long ConvertFloatToInt64(float op1) => (long)Math.Clamp(op1, int.MinValue, int.MaxValue); public static uint ConvertDoubleToUInt32(double op1) => (uint)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); public static uint ConvertToUInt32(float op1) => (uint)Math.Clamp(op1, uint.MinValue, uint.MaxValue); - private static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); + public static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); + + public static ulong ConvertFloatToUInt64(float op1) => (ulong)Math.Clamp(op1, uint.MinValue, uint.MaxValue); public static Int32 ConvertToInt32RoundAwayFromZero(float op1) => ConvertToInt32(RoundAwayFromZero(op1)); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template index dc84d4319f312..d58e5c5aad0ba 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template @@ -143,7 +143,6 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int LargestVectorSize = {LargestVectorSize}; private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; private static {RetBaseType}[] _data2 = new {RetBaseType}[Op1ElementCount]; @@ -166,7 +165,7 @@ namespace JIT.HardwareIntrinsics.Arm Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + _dataTable = new DataTable(_data1, new {RetBaseType}[Op1ElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; @@ -311,7 +310,7 @@ namespace JIT.HardwareIntrinsics.Arm {RetBaseType}[] mask = new {RetBaseType}[Op1ElementCount]; {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; {RetBaseType}[] falseVal = new {RetBaseType}[Op1ElementCount]; - {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[Op1ElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); @@ -338,7 +337,7 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[Op1ElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); @@ -349,7 +348,7 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[Op1ElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());