Skip to content

Commit ab46c54

Browse files
ARM64-SVE: Add TrigonometricSelectCoefficient, TrigonometricStartingValue (#104681)
* Implement ftssel, ftsmul * Skip test for invalid inputs
1 parent 6d3cb53 commit ab46c54

File tree

6 files changed

+132
-0
lines changed

6 files changed

+132
-0
lines changed

src/coreclr/jit/hwintrinsiclistarm64sve.h

+2
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ HARDWARE_INTRINSIC(Sve, TestFirstTrue,
246246
HARDWARE_INTRINSIC(Sve, TestLastTrue, -1, 2, true, {INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen)
247247
HARDWARE_INTRINSIC(Sve, TransposeEven, -1, 2, true, {INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
248248
HARDWARE_INTRINSIC(Sve, TransposeOdd, -1, 2, true, {INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
249+
HARDWARE_INTRINSIC(Sve, TrigonometricSelectCoefficient, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftssel, INS_sve_ftssel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg)
250+
HARDWARE_INTRINSIC(Sve, TrigonometricStartingValue, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftsmul, INS_sve_ftsmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg)
249251
HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
250252
HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, true, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
251253
HARDWARE_INTRINSIC(Sve, VectorTableLookup, -1, 2, true, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable)

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs

+30
Original file line numberDiff line numberDiff line change
@@ -8631,6 +8631,36 @@ internal Arm64() { }
86318631
public static unsafe Vector<ulong> TransposeOdd(Vector<ulong> left, Vector<ulong> right) { throw new PlatformNotSupportedException(); }
86328632

86338633

8634+
/// Trigonometric select coefficient
8635+
8636+
/// <summary>
8637+
/// svfloat64_t svtssel[_f64](svfloat64_t op1, svuint64_t op2)
8638+
/// FTSSEL Zresult.D, Zop1.D, Zop2.D
8639+
/// </summary>
8640+
public static unsafe Vector<double> TrigonometricSelectCoefficient(Vector<double> value, Vector<ulong> selector) { throw new PlatformNotSupportedException(); }
8641+
8642+
/// <summary>
8643+
/// svfloat32_t svtssel[_f32](svfloat32_t op1, svuint32_t op2)
8644+
/// FTSSEL Zresult.S, Zop1.S, Zop2.S
8645+
/// </summary>
8646+
public static unsafe Vector<float> TrigonometricSelectCoefficient(Vector<float> value, Vector<uint> selector) { throw new PlatformNotSupportedException(); }
8647+
8648+
8649+
/// Trigonometric starting value
8650+
8651+
/// <summary>
8652+
/// svfloat64_t svtsmul[_f64](svfloat64_t op1, svuint64_t op2)
8653+
/// FTSMUL Zresult.D, Zop1.D, Zop2.D
8654+
/// </summary>
8655+
public static unsafe Vector<double> TrigonometricStartingValue(Vector<double> value, Vector<ulong> sign) { throw new PlatformNotSupportedException(); }
8656+
8657+
/// <summary>
8658+
/// svfloat32_t svtsmul[_f32](svfloat32_t op1, svuint32_t op2)
8659+
/// FTSMUL Zresult.S, Zop1.S, Zop2.S
8660+
/// </summary>
8661+
public static unsafe Vector<float> TrigonometricStartingValue(Vector<float> value, Vector<uint> sign) { throw new PlatformNotSupportedException(); }
8662+
8663+
86348664
/// UnzipEven : Concatenate even elements from two inputs
86358665

86368666
/// <summary>

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs

+30
Original file line numberDiff line numberDiff line change
@@ -8676,6 +8676,36 @@ internal Arm64() { }
86768676
public static unsafe Vector<ulong> TransposeOdd(Vector<ulong> left, Vector<ulong> right) => TransposeOdd(left, right);
86778677

86788678

8679+
/// Trigonometric select coefficient
8680+
8681+
/// <summary>
8682+
/// svfloat64_t svtssel[_f64](svfloat64_t op1, svuint64_t op2)
8683+
/// FTSSEL Zresult.D, Zop1.D, Zop2.D
8684+
/// </summary>
8685+
public static unsafe Vector<double> TrigonometricSelectCoefficient(Vector<double> value, Vector<ulong> selector) => TrigonometricSelectCoefficient(value, selector);
8686+
8687+
/// <summary>
8688+
/// svfloat32_t svtssel[_f32](svfloat32_t op1, svuint32_t op2)
8689+
/// FTSSEL Zresult.S, Zop1.S, Zop2.S
8690+
/// </summary>
8691+
public static unsafe Vector<float> TrigonometricSelectCoefficient(Vector<float> value, Vector<uint> selector) => TrigonometricSelectCoefficient(value, selector);
8692+
8693+
8694+
/// Trigonometric starting value
8695+
8696+
/// <summary>
8697+
/// svfloat64_t svtsmul[_f64](svfloat64_t op1, svuint64_t op2)
8698+
/// FTSMUL Zresult.D, Zop1.D, Zop2.D
8699+
/// </summary>
8700+
public static unsafe Vector<double> TrigonometricStartingValue(Vector<double> value, Vector<ulong> sign) => TrigonometricStartingValue(value, sign);
8701+
8702+
/// <summary>
8703+
/// svfloat32_t svtsmul[_f32](svfloat32_t op1, svuint32_t op2)
8704+
/// FTSMUL Zresult.S, Zop1.S, Zop2.S
8705+
/// </summary>
8706+
public static unsafe Vector<float> TrigonometricStartingValue(Vector<float> value, Vector<uint> sign) => TrigonometricStartingValue(value, sign);
8707+
8708+
86798709
/// UnzipEven : Concatenate even elements from two inputs
86808710

86818711
/// <summary>

src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs

+5
Original file line numberDiff line numberDiff line change
@@ -5603,6 +5603,11 @@ internal Arm64() { }
56035603
public static System.Numerics.Vector<uint> TransposeOdd(System.Numerics.Vector<uint> left, System.Numerics.Vector<uint> right) { throw null; }
56045604
public static System.Numerics.Vector<ulong> TransposeOdd(System.Numerics.Vector<ulong> left, System.Numerics.Vector<ulong> right) { throw null; }
56055605

5606+
public static System.Numerics.Vector<double> TrigonometricSelectCoefficient(System.Numerics.Vector<double> value, System.Numerics.Vector<ulong> selector) { throw null; }
5607+
public static System.Numerics.Vector<float> TrigonometricSelectCoefficient(System.Numerics.Vector<float> value, System.Numerics.Vector<uint> selector) { throw null; }
5608+
public static System.Numerics.Vector<double> TrigonometricStartingValue(System.Numerics.Vector<double> value, System.Numerics.Vector<ulong> sign) { throw null; }
5609+
public static System.Numerics.Vector<float> TrigonometricStartingValue(System.Numerics.Vector<float> value, System.Numerics.Vector<uint> sign) { throw null; }
5610+
56065611
public static System.Numerics.Vector<sbyte> UnzipEven(System.Numerics.Vector<sbyte> left, System.Numerics.Vector<sbyte> right) { throw null; }
56075612
public static System.Numerics.Vector<short> UnzipEven(System.Numerics.Vector<short> left, System.Numerics.Vector<short> right) { throw null; }
56085613
public static System.Numerics.Vector<int> UnzipEven(System.Numerics.Vector<int> left, System.Numerics.Vector<int> right) { throw null; }

src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs

+5
Original file line numberDiff line numberDiff line change
@@ -4156,6 +4156,11 @@
41564156
("SveVecReduceUnOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_XorAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}),
41574157
("SveVecReduceUnOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_XorAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}),
41584158

4159+
("SveVecBinOpDifferentTypesTest.template", new Dictionary<string, string> {["TestName"] = "Sve_TrigonometricSelectCoefficient_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}),
4160+
("SveVecBinOpDifferentTypesTest.template", new Dictionary<string, string> {["TestName"] = "Sve_TrigonometricSelectCoefficient_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}),
4161+
("SveVecBinOpDifferentTypesTest.template", new Dictionary<string, string> {["TestName"] = "Sve_TrigonometricStartingValue_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}),
4162+
("SveVecBinOpDifferentTypesTest.template", new Dictionary<string, string> {["TestName"] = "Sve_TrigonometricStartingValue_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}),
4163+
41594164
("SveVecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SveUnzipEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),
41604165
("SveVecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SveUnzipEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),
41614166
("SveVecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SveUnzipEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),

src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs

+60
Original file line numberDiff line numberDiff line change
@@ -5252,6 +5252,36 @@ public static float MultiplyExtended(float op1, float op2)
52525252
}
52535253
}
52545254

5255+
public static float TrigonometricSelectCoefficient(float op1, uint op2)
5256+
{
5257+
float result = ((op2 % 2) == 0) ? op1 : (float)1.0;
5258+
bool isNegative = (op2 & 0b10) == 0b10;
5259+
5260+
if (isNegative != (result < 0))
5261+
{
5262+
result *= -1;
5263+
}
5264+
5265+
return result;
5266+
}
5267+
5268+
public static float TrigonometricStartingValue(float op1, uint op2)
5269+
{
5270+
float result = op1 * op1;
5271+
5272+
if (float.IsNaN(result))
5273+
{
5274+
return result;
5275+
}
5276+
5277+
if ((op2 % 2) == 1)
5278+
{
5279+
result *= -1;
5280+
}
5281+
5282+
return result;
5283+
}
5284+
52555285
public static float FPExponentialAccelerator(uint op1)
52565286
{
52575287
uint index = op1 & 0b111111;
@@ -5372,6 +5402,36 @@ public static double MultiplyExtended(double op1, double op2)
53725402
}
53735403
}
53745404

5405+
public static double TrigonometricSelectCoefficient(double op1, ulong op2)
5406+
{
5407+
double result = ((op2 % 2) == 0) ? op1 : 1.0;
5408+
bool isNegative = (op2 & 0b10) == 0b10;
5409+
5410+
if (isNegative != (result < 0))
5411+
{
5412+
result *= -1;
5413+
}
5414+
5415+
return result;
5416+
}
5417+
5418+
public static double TrigonometricStartingValue(double op1, ulong op2)
5419+
{
5420+
double result = op1 * op1;
5421+
5422+
if (double.IsNaN(result))
5423+
{
5424+
return result;
5425+
}
5426+
5427+
if ((op2 % 2) == 1)
5428+
{
5429+
result *= -1;
5430+
}
5431+
5432+
return result;
5433+
}
5434+
53755435
public static double FPExponentialAccelerator(ulong op1)
53765436
{
53775437
ulong index = op1 & 0b111111;

0 commit comments

Comments
 (0)